sound_type snd_make_mandolin(time_type t0, double freq, time_type d, double body_size, double detune, rate_type sr) { register mandolin_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, mandolin_susp_node, "snd_make_mandolin"); susp->mymand = initInstrument(MANDOLIN, round(sr)); controlChange(susp->mymand, 1, detune); controlChange(susp->mymand, 2, MAND_CONTROL_CHANGE_CONST * body_size);; susp->temp_ret_value = noteOn(susp->mymand, freq, 1.0); susp->susp.fetch = mandolin__fetch; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = mandolin_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = mandolin_print_tree; susp->susp.name = "mandolin"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
// ****************************************** bool MidiOut::programChange(unsigned char channel, unsigned char program) { // ****************************************** if (program>127) { return controlChange(channel,32,1) && write((192|channel),(program-128)); } else { return controlChange(channel,32,0) && write((192|channel),program); } }
sound_type snd_make_flute_freq(double freq, sound_type breath_env, sound_type freq_env, rate_type sr) { register flute_freq_susp_type susp; /* sr specified as input parameter */ time_type t0 = breath_env->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, flute_freq_susp_node, "snd_make_flute_freq"); susp->myflute = initInstrument(FLUTE, round(sr)); controlChange(susp->myflute, 1, 0.0);; susp->temp_ret_value = noteOn(susp->myflute, freq, 1.0); susp->breath_scale = breath_env->scale * FLUTE_CONTROL_CHANGE_CONST; susp->frequency = freq; /* make sure no sample rate is too high */ if (breath_env->sr > sr) { sound_unref(breath_env); snd_badsr(); } else if (breath_env->sr < sr) breath_env = snd_make_up(sr, breath_env); if (freq_env->sr > sr) { sound_unref(freq_env); snd_badsr(); } else if (freq_env->sr < sr) freq_env = snd_make_up(sr, freq_env); susp->susp.fetch = flute_freq_ns_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < breath_env->t0) sound_prepend_zeros(breath_env, t0); if (t0 < freq_env->t0) sound_prepend_zeros(freq_env, t0); /* minimum start time over all inputs: */ t0_min = min(breath_env->t0, min(freq_env->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = flute_freq_toss_fetch; } /* initialize susp state */ susp->susp.free = flute_freq_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = flute_freq_mark; susp->susp.print_tree = flute_freq_print_tree; susp->susp.name = "flute_freq"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->breath_env = breath_env; susp->breath_env_cnt = 0; susp->freq_env = freq_env; susp->freq_env_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void handleMIDIMessage(uint8_t ctrlByte, uint8_t msgByte1, uint8_t msgByte2) { uint8_t control = ctrlByte & 0xf0; //uint8_t channel = ctrlByte & 0x0f; //lcd_clear_line(1); //dip204_printf_string("control: %u",ctrlByte); //lcd_clear_line(2); //dip204_printf_string("note: %u", msgByte1); switch(control) { case 144: if (msgByte2) { addNote(msgByte1,msgByte2); } //to deal with note-offs represented as a note-on with zero velocity else { removeNote(msgByte1); } noteOut(); midiVol(); break; case 128: removeNote(msgByte1); noteOut(); midiVol(); break; // control change case 176: controlChange(msgByte1,msgByte2); //LED_On(LED2); //midiVol(); break; // program change case 192: programChange(msgByte1); break; default: break; } }
// ****************************************** bool MidiOut::allNotesOff(unsigned char channel) { // ****************************************** return controlChange(channel,123,0); }
void pluginCore::processMidi(int status, int channel, int byte1, int byte2, long frames) { #if 0 m_logger->log(XML_LOGGER_TYPE_MIDI, channel, byte1, byte2, (int)frames); #endif // Most modern hosts will attempt to schedule MIDI events with a frame offset, so in this case, // we add the event to the wait queue and skip processing (for now). This feature requires the // PluginCore event handling module, which may be included by defining USE_PC_EVENTS #if USE_PC_EVENTS if(frames > 0) { tCoreEvent *ce = (tCoreEvent*)malloc(sizeof(tCoreEvent)); ce->action = EVT_ACTION_MIDI; ce->data.midi_data.status = status; ce->data.midi_data.channel = channel; ce->data.midi_data.byte1 = byte1; ce->data.midi_data.byte2 = byte2; m_events.addEvent(this, frames, ce, false); return; } #endif int index = -1; switch(status) { case 0x80: // Note off index = findMidiNoteIndex((int)byte1); if(index >= 0) { noteOff(m_midi_notes.at(index).number); deleteNote(index); } break; case 0x90: // Note on { index = findMidiNoteIndex((int)byte1); if((int)byte2) { if(index < 0) { tMidiNote note; note.channel = (int)channel; note.number = (int)byte1; note.velocity = (int)byte2; note.frequency = m_freq_table[note.number]; note.reserved = 0; m_midi_notes.push_back(note); ++m_midi_note_count; noteOn(note.number, note.velocity); break; } else { // Note has already been added, so just change the velocity m_midi_notes.at(index).velocity = (int)byte2; } } // Velocity of zero means to actually turn off the note else { if(index >= 0) { noteOff(m_midi_notes.at(index).number); deleteNote(index); } } break; } case 0xa0: // Aftertouch index = findMidiNoteIndex((int)byte1); if(index >= 0) { m_midi_notes.at(index).velocity = (int)byte2; } break; case 0xb0: // Control change { if((int)byte2 == 120 || (int)byte2 == 123) { // Emergency catch for all notes off m_midi_note_count = 0; m_midi_notes.clear(); break; } tMidiMessage cc; cc.channel = channel; cc.byte1 = byte1; cc.byte2 = byte2; cc.reserved = 0; m_midi_ccs.push(cc); controlChange(cc.byte1, cc.byte2); } break; case 0xc0: // Program change #if USE_PC_PRESET // For the moment, the channel number is ignored. Sometimes this is used to specify // the program bank, and then the first byte for the corresponding program number. // Instead, we will treat all channels the same and simply load the preset corresponding // to the respective byte1 value. No bounds checking is done here because the value // gets checked in loadPreset(). if(byte1) { loadPreset((int)byte1); } #endif break; case 0xd0: // Pressure change // Multiply the velocity of all existing notes by a factor for(int i = 0; i < m_midi_note_count; ++i) { m_midi_notes.at(i).velocity = (int)((float)(m_midi_notes.at(i).velocity * byte1) / 127.0); } break; case 0xe0: // Pitch wheel (currently not handled) break; default: break; } }
void sax_all_nsnnnn_fetch(snd_susp_type a_susp, snd_list_type snd_list) { sax_all_susp_type susp = (sax_all_susp_type) a_susp; int cnt = 0; /* how many samples computed */ int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; register struct instr * sax_reg; register double frequency_reg; register float breath_scale_reg; register float reed_scale_reg; register float noise_scale_reg; register float blow_scale_reg; register float offset_scale_reg; register sample_block_values_type reed_table_offset_ptr_reg; register sample_block_values_type blow_pos_ptr_reg; register sample_block_values_type noise_env_ptr_reg; register sample_block_values_type reed_stiffness_ptr_reg; register sample_type freq_env_scale_reg = susp->freq_env->scale; register sample_block_values_type freq_env_ptr_reg; register sample_block_values_type breath_env_ptr_reg; falloc_sample_block(out, "sax_all_nsnnnn_fetch"); out_ptr = out->samples; snd_list->block = out; while (cnt < max_sample_block_len) { /* outer loop */ /* first compute how many samples to generate in inner loop: */ /* don't overflow the output sample block: */ togo = max_sample_block_len - cnt; /* don't run past the breath_env input sample block: */ susp_check_term_samples(breath_env, breath_env_ptr, breath_env_cnt); togo = min(togo, susp->breath_env_cnt); /* don't run past the freq_env input sample block: */ susp_check_samples(freq_env, freq_env_ptr, freq_env_cnt); togo = min(togo, susp->freq_env_cnt); /* don't run past the reed_stiffness input sample block: */ susp_check_samples(reed_stiffness, reed_stiffness_ptr, reed_stiffness_cnt); togo = min(togo, susp->reed_stiffness_cnt); /* don't run past the noise_env input sample block: */ susp_check_samples(noise_env, noise_env_ptr, noise_env_cnt); togo = min(togo, susp->noise_env_cnt); /* don't run past the blow_pos input sample block: */ susp_check_samples(blow_pos, blow_pos_ptr, blow_pos_cnt); togo = min(togo, susp->blow_pos_cnt); /* don't run past the reed_table_offset input sample block: */ susp_check_samples(reed_table_offset, reed_table_offset_ptr, reed_table_offset_cnt); togo = min(togo, susp->reed_table_offset_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } n = togo; sax_reg = susp->sax; frequency_reg = susp->frequency; breath_scale_reg = susp->breath_scale; reed_scale_reg = susp->reed_scale; noise_scale_reg = susp->noise_scale; blow_scale_reg = susp->blow_scale; offset_scale_reg = susp->offset_scale; reed_table_offset_ptr_reg = susp->reed_table_offset_ptr; blow_pos_ptr_reg = susp->blow_pos_ptr; noise_env_ptr_reg = susp->noise_env_ptr; reed_stiffness_ptr_reg = susp->reed_stiffness_ptr; freq_env_ptr_reg = susp->freq_env_ptr; breath_env_ptr_reg = susp->breath_env_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ controlChange(sax_reg, 128, breath_scale_reg * *breath_env_ptr_reg++); controlChange(sax_reg, 2, reed_scale_reg * *reed_stiffness_ptr_reg++); controlChange(sax_reg, 4, noise_scale_reg * *noise_env_ptr_reg++); controlChange(sax_reg, 11, blow_scale_reg * *blow_pos_ptr_reg++); controlChange(sax_reg, 26, offset_scale_reg * *reed_table_offset_ptr_reg++); setFrequency(sax_reg, frequency_reg + (freq_env_scale_reg * *freq_env_ptr_reg++)); *out_ptr_reg++ = (sample_type) tick(sax_reg); } while (--n); /* inner loop */ susp->sax = sax_reg; /* using reed_table_offset_ptr_reg is a bad idea on RS/6000: */ susp->reed_table_offset_ptr += togo; /* using blow_pos_ptr_reg is a bad idea on RS/6000: */ susp->blow_pos_ptr += togo; /* using noise_env_ptr_reg is a bad idea on RS/6000: */ susp->noise_env_ptr += togo; /* using reed_stiffness_ptr_reg is a bad idea on RS/6000: */ susp->reed_stiffness_ptr += togo; /* using freq_env_ptr_reg is a bad idea on RS/6000: */ susp->freq_env_ptr += togo; /* using breath_env_ptr_reg is a bad idea on RS/6000: */ susp->breath_env_ptr += togo; out_ptr += togo; susp_took(breath_env_cnt, togo); susp_took(freq_env_cnt, togo); susp_took(reed_stiffness_cnt, togo); susp_took(noise_env_cnt, togo); susp_took(blow_pos_cnt, togo); susp_took(reed_table_offset_cnt, togo); cnt += togo; } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } } /* sax_all_nsnnnn_fetch */
sound_type snd_make_sax_all(double freq, sound_type breath_env, sound_type freq_env, double vibrato_freq, double vibrato_gain, sound_type reed_stiffness, sound_type noise_env, sound_type blow_pos, sound_type reed_table_offset, rate_type sr) { register sax_all_susp_type susp; /* sr specified as input parameter */ time_type t0 = breath_env->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, sax_all_susp_node, "snd_make_sax_all"); susp->sax = initInstrument(SAXOFONY, round(sr)); noteOn(susp->sax, freq, 1.0); controlChange(susp->sax, 29, SAX_CONTROL_CHANGE_CONST * vibrato_freq); controlChange(susp->sax, 1, SAX_CONTROL_CHANGE_CONST * vibrato_gain);; susp->frequency = freq; susp->breath_scale = breath_env->scale * SAX_CONTROL_CHANGE_CONST; susp->reed_scale = reed_stiffness->scale * SAX_CONTROL_CHANGE_CONST; susp->noise_scale = noise_env->scale * SAX_CONTROL_CHANGE_CONST; susp->blow_scale = blow_pos->scale * SAX_CONTROL_CHANGE_CONST; susp->offset_scale = reed_table_offset->scale * SAX_CONTROL_CHANGE_CONST; /* make sure no sample rate is too high */ if (breath_env->sr > sr) { sound_unref(breath_env); snd_badsr(); } else if (breath_env->sr < sr) breath_env = snd_make_up(sr, breath_env); if (freq_env->sr > sr) { sound_unref(freq_env); snd_badsr(); } else if (freq_env->sr < sr) freq_env = snd_make_up(sr, freq_env); if (reed_stiffness->sr > sr) { sound_unref(reed_stiffness); snd_badsr(); } else if (reed_stiffness->sr < sr) reed_stiffness = snd_make_up(sr, reed_stiffness); if (noise_env->sr > sr) { sound_unref(noise_env); snd_badsr(); } else if (noise_env->sr < sr) noise_env = snd_make_up(sr, noise_env); if (blow_pos->sr > sr) { sound_unref(blow_pos); snd_badsr(); } else if (blow_pos->sr < sr) blow_pos = snd_make_up(sr, blow_pos); if (reed_table_offset->sr > sr) { sound_unref(reed_table_offset); snd_badsr(); } else if (reed_table_offset->sr < sr) reed_table_offset = snd_make_up(sr, reed_table_offset); susp->susp.fetch = sax_all_nsnnnn_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < breath_env->t0) sound_prepend_zeros(breath_env, t0); if (t0 < freq_env->t0) sound_prepend_zeros(freq_env, t0); if (t0 < reed_stiffness->t0) sound_prepend_zeros(reed_stiffness, t0); if (t0 < noise_env->t0) sound_prepend_zeros(noise_env, t0); if (t0 < blow_pos->t0) sound_prepend_zeros(blow_pos, t0); if (t0 < reed_table_offset->t0) sound_prepend_zeros(reed_table_offset, t0); /* minimum start time over all inputs: */ t0_min = min(breath_env->t0, min(freq_env->t0, min(reed_stiffness->t0, min(noise_env->t0, min(blow_pos->t0, min(reed_table_offset->t0, t0)))))); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = sax_all_toss_fetch; } /* initialize susp state */ susp->susp.free = sax_all_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = sax_all_mark; susp->susp.print_tree = sax_all_print_tree; susp->susp.name = "sax_all"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->breath_env = breath_env; susp->breath_env_cnt = 0; susp->freq_env = freq_env; susp->freq_env_cnt = 0; susp->reed_stiffness = reed_stiffness; susp->reed_stiffness_cnt = 0; susp->noise_env = noise_env; susp->noise_env_cnt = 0; susp->blow_pos = blow_pos; susp->blow_pos_cnt = 0; susp->reed_table_offset = reed_table_offset; susp->reed_table_offset_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
int main(void) { // b. Umleiten der Standardausgabe stdout (Teil 2) //stdout = &mystdout; // Init everything // Init Touch & Potis DDRA = 0x00; // ADWandler-Pins auf Eingang schalten uint16_t ADC_val; ADC_Init(); // Init LED Matrix TLC5940_Init(); // Init SPI init_SPI(); // Init Timer timer_config(); TLC5940_SetAllDC(63); TLC5940_ClockInDC(); TLC5940_SetAllGS(0); // Init all 74hc595 init_74hc595(); // Init all 74hc165 init_74hc165(); // Enable Interrupts globally // TEMP TEMP TEMP DDRC |= 0b01000000; // Kalibriere Touchpanel calibrate(); sei(); // Init UART uart_init(); while (1) { static uint8_t current_potentiometer = 0; // POTENTIOMETER auslesen { /* switch( current_potentiometer ) { // case 1: // PORTC &= ~0b01000000; // break; case 2: PORTC |= 0b01000000; break; } */ // erstes Auslesen immer Fehlerhaft wegen Touchpanel evtl // zweiter Wert beinhaltet richtiges Ergebniss! // POTI_ADC_SAMPLES sollte daher 2 sein damit nach dem zweiten lesen in ADC_val das richtige ergebniss steht ADC_val = 0; for ( uint8_t count = 0 ; count < POTI_ADC_SAMPLES ; count++ ) ADC_val = ADC_Read(potentiometer[current_potentiometer].adc_channel); if( ADC_val > ( potentiometer[current_potentiometer].value + ADC_delta_for_change_poti ) || ( ADC_val < ( potentiometer[current_potentiometer].value - ADC_delta_for_change_poti ) ) ) // +- 8 von 1024 Quantisierungsstufen / 128 Midi Schritte . // if( ADC_val > ( potentiometer[current_potentiometer].value + 10 ) || ( ADC_val < ( potentiometer[current_potentiometer].value - 10 ) ) ) { potentiometer[current_potentiometer].value = ADC_val; controlChange(midi_channel, midi_poti_offset + current_potentiometer,ADC_val/8); //printf("%i. Poti %i\n", current_potentiometer , potentiometer[current_potentiometer].value ); } current_potentiometer++; if ( current_potentiometer == potentiometer_count) current_potentiometer = 0; } //Display_SetCross(4,2); // TOUCHPANEL auslesen read_touchscreen(); if(touchscreen.FLAG_Display_change) { TLC5940_SetAllGS(0); //Display_SetParabel(touchscreen.last_x , touchscreen.last_y ); Display_SetCross(touchscreen.last_LED_x,touchscreen.last_LED_y); touchscreen.FLAG_Display_change = 0; } } }
void flute_freq_ns_fetch(snd_susp_type a_susp, snd_list_type snd_list) { flute_freq_susp_type susp = (flute_freq_susp_type) a_susp; int cnt = 0; /* how many samples computed */ int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; register struct instr * myflute_reg; register float breath_scale_reg; register double frequency_reg; register sample_type freq_env_scale_reg = susp->freq_env->scale; register sample_block_values_type freq_env_ptr_reg; register sample_block_values_type breath_env_ptr_reg; falloc_sample_block(out, "flute_freq_ns_fetch"); out_ptr = out->samples; snd_list->block = out; while (cnt < max_sample_block_len) { /* outer loop */ /* first compute how many samples to generate in inner loop: */ /* don't overflow the output sample block: */ togo = max_sample_block_len - cnt; /* don't run past the breath_env input sample block: */ susp_check_term_samples(breath_env, breath_env_ptr, breath_env_cnt); togo = min(togo, susp->breath_env_cnt); /* don't run past the freq_env input sample block: */ susp_check_samples(freq_env, freq_env_ptr, freq_env_cnt); togo = min(togo, susp->freq_env_cnt); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo < 0) togo = 0; /* avoids rounding errros */ if (togo == 0) break; } n = togo; myflute_reg = susp->myflute; breath_scale_reg = susp->breath_scale; frequency_reg = susp->frequency; freq_env_ptr_reg = susp->freq_env_ptr; breath_env_ptr_reg = susp->breath_env_ptr; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ controlChange(myflute_reg, 128, breath_scale_reg * *breath_env_ptr_reg++); setFrequency(myflute_reg, frequency_reg + (freq_env_scale_reg * *freq_env_ptr_reg++)); *out_ptr_reg++ = (sample_type) tick(myflute_reg); } while (--n); /* inner loop */ susp->myflute = myflute_reg; /* using freq_env_ptr_reg is a bad idea on RS/6000: */ susp->freq_env_ptr += togo; /* using breath_env_ptr_reg is a bad idea on RS/6000: */ susp->breath_env_ptr += togo; out_ptr += togo; susp_took(breath_env_cnt, togo); susp_took(freq_env_cnt, togo); cnt += togo; } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } } /* flute_freq_ns_fetch */
void MidiDecoder::midiEventReceived(MidiEvent midiEvent) { int timbreIndex = 0; int timbres[4]; if (omniOn[0] || this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL1] == 0 || (this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL1]-1) == midiEvent.channel ) { timbres[timbreIndex++] = 0; } if (omniOn[1] || this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL2] == 0 || (this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL2]-1) == midiEvent.channel ) { timbres[timbreIndex++] = 1; } if (omniOn[2] || this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL3] == 0 || (this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL3]-1) == midiEvent.channel ) { timbres[timbreIndex++] = 2; } if (omniOn[3] || this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL4] == 0 || (this->synthState->fullState.midiConfigValue[MIDICONFIG_CHANNEL4]-1) == midiEvent.channel ) { timbres[timbreIndex++] = 3; } if (timbreIndex == 0) { // No accurate channel return; } switch (midiEvent.eventType) { case MIDI_NOTE_OFF: for (int tk = 0; tk< timbreIndex; tk++ ) { this->synth->noteOff(timbres[tk], midiEvent.value[0]); } break; case MIDI_NOTE_ON: if (midiEvent.value[1] == 0) { // Some keyboards send note-off this way for (int tk = 0; tk< timbreIndex; tk++ ) { this->synth->noteOff(timbres[tk], midiEvent.value[0]); } } else { for (int tk = 0; tk< timbreIndex; tk++ ) { this->synth->noteOn(timbres[tk], midiEvent.value[0], midiEvent.value[1]); visualInfo->noteOn(timbres[tk], true); } } break; case MIDI_CONTROL_CHANGE: for (int tk = 0; tk< timbreIndex; tk++ ) { controlChange(timbres[tk], midiEvent); } break; case MIDI_POLY_AFTER_TOUCH: // We don't do anything // this->synth->getMatrix()->setSource(MATRIX_SOURCE_AFTERTOUCH, midiEvent.value[1]); break; case MIDI_AFTER_TOUCH: for (int tk = 0; tk< timbreIndex; tk++ ) { this->synth->getTimbre(timbres[tk])->setMatrixSource(MATRIX_SOURCE_AFTERTOUCH, INV127*midiEvent.value[0]); } break; case MIDI_PITCH_BEND: for (int tk = 0; tk< timbreIndex; tk++ ) { int pb = ((int) midiEvent.value[1] << 7) + (int) midiEvent.value[0] - 8192; this->synth->getTimbre(timbres[tk])->setMatrixSource(MATRIX_SOURCE_PITCHBEND, (float)pb * .00012207031250000000f ); } break; case MIDI_PROGRAM_CHANGE: if (this->synthState->fullState.midiConfigValue[MIDICONFIG_PROGRAM_CHANGE]) { for (int tk = 0; tk< timbreIndex; tk++ ) { this->synth->loadPreenFMPatchFromMidi(timbres[tk], bankNumber[timbres[tk]], bankNumberLSB[timbres[tk]], midiEvent.value[0]); } } break; case MIDI_SONG_POSITION: this->songPosition = ((int) midiEvent.value[1] << 7) + midiEvent.value[0]; this->synth->midiClockSetSongPosition(this->songPosition); break; } }