示例#1
0
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);
}
示例#2
0
// ******************************************
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);
    }
}
示例#3
0
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);
}
示例#4
0
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;
	}
}
示例#5
0
// ******************************************
bool MidiOut::allNotesOff(unsigned char channel) {
// ******************************************
    return controlChange(channel,123,0);
}
示例#6
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;
  }
}
示例#7
0
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 */
示例#8
0
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);
}
示例#9
0
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;
		  }	
	
  	}

	
}
示例#10
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 */
示例#11
0
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;
    }
}