diff --git a/Channel.pde b/Channel.pde index 1400c13..546c1db 100644 --- a/Channel.pde +++ b/Channel.pde @@ -1,5 +1,4 @@ import processing.sound.*; -import java.util.Map.*; public class ChannelOsc { @@ -23,7 +22,6 @@ public class ChannelOsc { float last_freq = 0; - ChannelOsc() { current_notes = new HashMap(); circular_array_envs = new Env[CIRCULAR_ARR_SIZE]; @@ -59,6 +57,7 @@ public class ChannelOsc { void play_note(int note_code, int velocity) { if (curr_global_amp <= 0 || silenced) return; + stop_note(note_code); float freq = midi_to_freq(note_code); float amp = map(velocity, 0, 127, 0.0, 1.0); @@ -78,7 +77,7 @@ public class ChannelOsc { }*/ if (osc_type == 0) ((Pulse) s).width(pulse_width); - s.amp(amp * (osc_type == 1 || osc_type == 2 ? 0.26 : 0.1) * curr_global_amp); // give a volume boost to TRI and SIN + s.amp(amp * (osc_type == 1 || osc_type == 2 ? 0.12 : 0.05) * curr_global_amp); // give a volume boost to TRI and SIN if (env_values != null && env_values.length == 3) { Env e = new Env(PARENT); e.play(s, env_values[0], env_values[1], 1.0, env_values[2]); // will come back to envelopes... great potential but buggy :( @@ -120,7 +119,7 @@ public class ChannelOsc { void set_volume(int volume) { float amp = map(volume, 0, 127, 0.0, 1.0); for (SoundObject s : current_notes.values()) { - ((Oscillator) s).amp((osc_type == 1 || osc_type == 2 ? 0.26 : 0.1) * amp); + ((Oscillator) s).amp((osc_type == 1 || osc_type == 2 ? 0.12 : 0.05) * amp); } curr_global_amp = amp; } @@ -164,35 +163,40 @@ public class ChannelOsc { class ChannelOscDrum extends ChannelOsc { + SoundFile[] samples; + + ChannelOscDrum() { super(); + + // preloading samples... + samples = new SoundFile[4]; + for (int i = 1; i <= samples.length; i++) { + samples[i-1] = new SoundFile(PARENT, "data/samples/" + i + ".wav"); + } } void play_note(int note_code, int velocity) { if (curr_global_amp <= 0 || silenced) return; - stop_note(note_code); - float freq = midi_to_freq(note_code); float amp = map(velocity, 0, 127, 0.0, 1.0); - SoundFile s = (SoundFile) current_notes.get(note_code); - if (s == null) { - s = new SoundFile(PARENT, "data/samples/" + note_code_to_percussion(note_code) + ".wav"); - current_notes.put(note_code, s); - } + int sample_code = note_code_to_percussion(note_code); + SoundFile s = (SoundFile) samples[sample_code-1]; + if (s == null || s.isPlaying()) return; s.amp(amp * 0.26); s.play(); last_amp = amp; - last_freq = freq; + last_freq = sample_code; } void stop_note(int note_code) { last_amp = 0.0; - last_freq = 0.0; + last_freq = 0; } @@ -223,8 +227,3 @@ Oscillator get_new_osc(int osc_type) { return new SawOsc(PARENT); } } - - -processing.sound.Noise get_new_noise(int note_code) { - return new WhiteNoise(PARENT); -} diff --git a/P3synth.pde b/P3synth.pde index 09b1c36..4e0bf7b 100644 --- a/P3synth.pde +++ b/P3synth.pde @@ -1,11 +1,13 @@ import java.io.*; +import java.util.Map.*; final processing.core.PApplet PARENT = this; -final float VERCODE = 22.66; +final float VERCODE = 22.67; Player player; PImage[] logo_anim; PImage[] osc_type_textures; +PImage bg_gradient; PFont[] fonts; ThemeEngine t; ButtonToolbar media_buttons; @@ -15,25 +17,18 @@ WaitingDialog dialog_meta_msgs; HashMap config_map; void setup() { + text("please wait!\nloading...", 12, 12); + new Sound(PARENT).volume(0.7); // oscillators at volume 1 are ridiculously loud... + SinOsc warmup = new SinOsc(PARENT); warmup.freq(100); - warmup.amp(0.1); + warmup.amp(0.01); warmup.play(); // has to be done so the audio driver is prepared for what we're about to do to 'em...*/ size(724, 420); surface.setTitle("vlco_o P3synth"); - logo_anim = new PImage[8]; - for (int i = 0; i < 8; i++) { - PImage img = loadImage("graphics/logo" + i + ".png"); - logo_anim[i] = img; - } - osc_type_textures = new PImage[6]; - for (int i = -1; i < 5; i++) { - PImage img = loadImage("graphics/osc_" + i + ".png"); - osc_type_textures[i+1] = img; - } - + setup_images(); setup_fonts(); setup_buttons(); setup_config(); @@ -47,6 +42,7 @@ void setup() { } + void draw() { if (!player.stopped) { player.redraw(); @@ -61,6 +57,7 @@ void draw() { } + void load_config(boolean just_opened) { try { BufferedReader br = new BufferedReader(new FileReader("P3synth config")); @@ -87,6 +84,7 @@ void load_config(boolean just_opened) { } + void save_config() { try { PrintStream f = new PrintStream(new File("P3synth config")); @@ -103,8 +101,17 @@ void save_config() { } + void redraw_all() { background(t.theme[2]); + + push(); + noFill(); + strokeWeight(2); + stroke(t.theme[0]); + rect(1, 1, width-2, height-2); + pop(); + media_buttons.redraw(); setting_buttons.redraw(); image(logo_anim[0], 311, 10); @@ -113,6 +120,25 @@ void redraw_all() { } + +void setup_images() { + logo_anim = new PImage[8]; + for (int i = 0; i < 8; i++) { + PImage img = loadImage("graphics/logo" + i + ".png"); + logo_anim[i] = img; + } + + osc_type_textures = new PImage[6]; + for (int i = -1; i < 5; i++) { + PImage img = loadImage("graphics/osc_" + i + ".png"); + osc_type_textures[i+1] = img; + } + + bg_gradient = loadImage("graphics/gradient.png"); + bg_gradient.resize(width, bg_gradient.height); +} + + void setup_config() { config_map = new HashMap(); config_map.put("theme name", "Fresh Blue"); @@ -139,13 +165,15 @@ void setup_buttons() { b1 = new Button("info", "Help"); b2 = new Button("confTheme", "Theme"); - Button[] buttons_set = {b2, b1}; + b3 = new Button("update", "Update"); + Button[] buttons_set = {b2, b1, b3}; setting_buttons = new ButtonToolbar(470, 16, 1.2, 0, buttons_set); b_meta_msgs = new Button(682, 376, "message", "Hist."); // next to the player's message bar } + void mouseClicked() { if (mouseButton == LEFT) { if(media_buttons.collided("Play")) { @@ -217,6 +245,21 @@ void mouseClicked() { //ui.showInfoDialog(player.history_text_messages); } + else if(setting_buttons.collided("Update")) { + WaitingDialog wd = ui.showWaitingDialog("Checking for updates...", "Please wait"); + boolean b = check_if_newer_ver(); + wd.close(); + + if (b) { + ui.showConfirmDialog( + "There is a newer version available. Download now?", "Update", + new Runnable() { public void run() { download_latest_ver(); } }, + new Runnable() { public void run() {} } + ); + } + else ui.showInfoDialog("You're running the latest version of P3synth."); + } + else { player.disp.check_buttons(); // check for any presses on the player controls player.check_chan_disp_buttons(); // check for any presses on the channel display @@ -230,19 +273,6 @@ void mouseClicked() { } -class LongMessageNotException extends Exception { - String msg; - - public LongMessageNotException(String text_msg) { - this.msg = text_msg; - } - - @Override - String toString() { - return this.msg; - } -} - boolean try_play_file(File selection) { if (selection != null) { diff --git a/Player.pde b/Player.pde index 92aa1bc..fa1ba71 100644 --- a/Player.pde +++ b/Player.pde @@ -42,10 +42,10 @@ class Player { String text = ""; for (byte b : arr) { - text += Character.toString((char) b); + if (b >= 0) text += Character.toString((char) b); } - return text.trim(); + return text.trim().replace("\n", ""); } @@ -181,7 +181,7 @@ class Player { if (data1 >= 112) channels[chan].curr_global_amp = 0.0; else { channels[chan].set_osc_type(program_to_osc(data1)); - channels[chan].set_env_values(program_to_env(data1)); + //channels[chan].set_env_values(program_to_env(data1)); } } diff --git a/Resources.pde b/Resources.pde index cac869c..395637f 100644 --- a/Resources.pde +++ b/Resources.pde @@ -30,6 +30,7 @@ class ThemeEngine { } } + float[] prog_osc_relationship = { 2, 1, 1, 0.5, 0.5, 0.5, 0.3, 0.3, 0.3, 1, 1, 1, 1, 0.5, 0.3, 0.3, 1, 1, 1, 0.7, 0.7, 0.3, 0.7, 0.3, 2, 1, 2, @@ -54,18 +55,14 @@ float[] program_to_env(int prog) { } -String[] notecode_perc_relationship = { - "Tom", "Tom", "Tom", "Snare", "Snare", "Snare", "Tom", - "Closed hihat", "Tom", "Closed hihat", "Tom", "Open hihat", - "Tom", "Tom", "Open hihat", "Tom", "Open hihat", "Open hihat", - "Closed hihat", "Snare", "Open hihat", "Closed hihat", - "Open hihat", "Tom", "Snare", "Snare", "Snare", "Open hihat", - "Open hihat", "Closed hihat", "Open hihat", "Snare", "Tom", - "Closed hihat", "Open hihat", "Snare", "Tom", "Closed hihat", - "Open hihat", "Snare", "Tom", "Closed hihat", "Open hihat", - "Snare", "Tom", "Closed hihat", "Open hihat" +// 1 → closed hihat, 2 → open hihat, 3 → snare, 4 → tom +int[] notecode_perc_relationship = { + 4, 4, 4, 3, 3, 3, 4, 1, 4, 1, 4, 2, + 4, 4, 2, 4, 2, 2, 1, 3, 2, 1, 2, 4, + 3, 3, 3, 2, 2, 2, 3, 1, 4, 4, 2, 1, + 3, 4, 1, 2, 3, 2, 3, 4, 1, 2, 3 }; -String note_code_to_percussion(int note_code) { +int note_code_to_percussion(int note_code) { return notecode_perc_relationship[constrain(note_code, 35, 81) - 35]; } diff --git a/UIServer.pde b/UIServer.pde index 9acd320..e041956 100644 --- a/UIServer.pde +++ b/UIServer.pde @@ -128,7 +128,7 @@ class ChannelDisplay { // Freq label fill(t.theme[0]); textFont(fonts[0]); - if (id == 9) text(label_frequency == 0 ? "- -" : "-ts-", x+113, y+10); + if (id == 9) text(label_frequency == 0 ? "- -" : (label_frequency < 4.0 ? "-ts-" : "-pf-"), x+113, y+10); else text(label_frequency, x+113, y+10); // Velocity meter @@ -218,9 +218,9 @@ class PlayerDisplay { void redraw(boolean renew_values) { if (renew_values) update_all_values(); - fill(t.theme[2]); + /*fill(t.theme[2]); noStroke(); - rect(x+1, y+40, 680, 63); + rect(x+1, y+40, 680, 63);*/ // File name label textAlign(CENTER, CENTER); @@ -321,6 +321,7 @@ class ButtonToolbar { int i = 0; for (Button b : buttons) { + if (b == null) continue; this.buttons.put(b.label, b); b.x = int(i * (b.width * this.x_sep) + x); b.y = int(i * (b.height * this.y_sep) + y); @@ -340,6 +341,8 @@ class ButtonToolbar { boolean collided(String b_name) { - return this.buttons.get(b_name).collided(); + Button b = this.buttons.get(b_name); + if (b == null) return false; + return b.collided(); } } diff --git a/Updater.pde b/Updater.pde new file mode 100644 index 0000000..ed171f9 --- /dev/null +++ b/Updater.pde @@ -0,0 +1,40 @@ +import http.requests.*; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +float latest_vercode = VERCODE; +String latest_tagname = ""; + +final String RELEASES_URL = "https://api.github.com/repos/vlcoo/P3synth/releases"; + + +boolean check_if_newer_ver() { + if (latest_vercode > VERCODE) return true; + + GetRequest r = new GetRequest("https://api.github.com/repos/vlcoo/P3synth/releases"); + r.send(); + JSONArray response; + + try { response = parseJSONArray(r.getContent()); } + catch (NullPointerException npe) { return false; } + + JSONObject latest = (JSONObject) response.get(0); + latest_vercode = Float.parseFloat(latest.get("name").toString().replace("v", "")); + latest_tagname = latest.get("tag_name").toString(); + + return latest_vercode > VERCODE; +} + + +void download_latest_ver() { + if (latest_tagname.equals("")) return; + + Desktop desktop = java.awt.Desktop.getDesktop(); + try { + desktop.browse(new URI("https://github.com/vlcoo/P3synth/releases/tag/" + latest_tagname)); + } + catch (URISyntaxException use) {} + catch (IOException ioe) {} +} diff --git a/data/buttons/updateDown.png b/data/buttons/updateDown.png new file mode 100644 index 0000000..43d37d1 Binary files /dev/null and b/data/buttons/updateDown.png differ diff --git a/data/buttons/updateUp.png b/data/buttons/updateUp.png new file mode 100644 index 0000000..5d86b4b Binary files /dev/null and b/data/buttons/updateUp.png differ diff --git a/data/samples/1.wav b/data/samples/1.wav new file mode 100644 index 0000000..8eb0ca0 Binary files /dev/null and b/data/samples/1.wav differ diff --git a/data/samples/2.wav b/data/samples/2.wav new file mode 100644 index 0000000..109ec4b Binary files /dev/null and b/data/samples/2.wav differ diff --git a/data/samples/3.wav b/data/samples/3.wav new file mode 100644 index 0000000..1873cb8 Binary files /dev/null and b/data/samples/3.wav differ diff --git a/data/samples/4.wav b/data/samples/4.wav new file mode 100644 index 0000000..bf87a8b Binary files /dev/null and b/data/samples/4.wav differ