void sn76_noise_voicer::midi_message(unsigned char message,unsigned char data1, unsigned char data2)
{
	switch(message)
		{
			case 0x90: //note on
				if(data2 == 0)
				{
					note_off(data1,data2);
				}
				else
				{
					note_on(data1,data2);
				}
			break;
			case 0x80: //note off
				note_off(data1,data2);
			break;
			case 0xC0: //prog change
				patch_change(data1);
			break;
			case 0xF8: //TICK
				tick();
			default:
				//std::cout<<"unknown msg, status: 0x" << std::hex <<(unsigned int)status<<std::endl;
			break;
		}
}
Example #2
0
static void 
scan_freqs() {

  int note, j;
  real_t power;

  for ( note = lo_note; note<hi_note; note++ ) {

	power = get_power(note);

	// harmonic compensation
	if ( use_harm_comp ) {
	  j = note-12;
	  while ( j > lo_note ) {
		if (act_freq[j]) {
		  power = -10000.0;
		  break;
		}
		j -= 12;
	  }
	}

	if ( act_freq[note] ) act_freq[note] =max(act_freq[note], power);

	if ( power > threshold && !act_freq[note] ) 
	  note_on(note, power);

	if (power < (threshold / hysteresis) && act_freq[note] ) 
	  note_off(note, power);
  }
}
Example #3
0
jack_read_midi(jack_nframes_t nframes) {
	jack_nframes_t i;

	midi_buf=jack_port_get_buffer(midi_port, nframes);
	jack_nframes_t  num_events=jack_midi_get_event_count(midi_buf);
	for(i=0; i<num_events; i++) {
		if(jack_midi_event_get(&midi_event, midi_buf, i)) return;
		int status=midi_event.buffer[0];
		jack_midi_data_t param=midi_event.buffer[1];
		jack_midi_data_t value=midi_event.buffer[2];
		//printf("JACK MIDI event: %x %x %x\n", status, param, value);

		int ev_type=status&0xf0;
		int channel=status&0x0f;

		switch(ev_type) {
			case SND_SEQ_EVENT_CONTROLLER:
				if(!midi_channels[channel].in_use) break;
				if(param==64) {
					if(value>64) midi_channels[channel].sustain=1;
					else midi_channels[channel].sustain=0;
				} else if(param==1) {
					// modulation controlling vibrato: value=0-127
					midi_channels[channel].vibrato=value;
					//printf("%d\n", value);
					midi_channels[channel].vibrato_changed=1;
				}
				break;
			// case SND_SEQ_EVENT_KEYPRESS:
			case SND_SEQ_EVENT_CHANPRESS:
				if(!midi_channels[channel].in_use) break;
				midi_channels[channel].chanpress=value;
				midi_channels[channel].chanpress_changed=1;
				break;
			case SND_SEQ_EVENT_NOTEON:
				if(!midi_channels[channel].in_use) break;
				note_on(channel, param, value);
				break;
			case SND_SEQ_EVENT_NOTEOFF:
				if(!midi_channels[channel].in_use) break;
				note_off(channel, param);
				break;
			case SND_SEQ_EVENT_PITCHBEND:
				// value=-8192 to +8191
				if(!midi_channels[channel].in_use) break;
				//int pitchbend=(value*128)|(param&0x7f);
				int pitchbend=(((value&0x7f)<<7)|(param&0x7f))-8192;
				//printf("got pitchbend %x %x: %x %d\n", param, value, pitchbend, pitchbend);
				midi_channels[channel].pitchbend=pitchbend;
				break;
			case SND_SEQ_EVENT_PGMCHANGE:
				if(midi_channels[channel].program==-1) break;
				//printf("prg change %d\n", value);
				midi_channels[channel].program=param;
				break;
		}
	}
}
Example #4
0
void Channel::event(uint8_t a, uint8_t b, uint8_t c)
{
	switch(a & 0xF0)
	{
		case 0x80: note_off(b); break;
		case 0x90: note_on(b,c); break;
		case 0xA0: break; //IMPLEMENTME: polyphonic aftertouch (note, dynamic)
		case 0xB0: set_controller(b,c); break;
		case 0xC0: set_program(b); break;
		case 0xD0: break; //IMPLEMENTME: monotonic aftertouch (dynamic)
		case 0xE0: set_pitch_bend( ( (((b&0x7F) + ((c&0x7F)<<7)) - 8192) / 8192.0 ) * max_pitchbend ); break;
		case 0xF0: break; //own controls/sysex (to be implemented) IMPLEMENTME
		default: output_verbose("NOTE: got unknown command "+ IntToStrHex(a&0xF0) +", ignoring it\n");
		;
	}
}
Example #5
0
/*When a note on message is received that note's node is added to the start of
 *the noteBuffer linked list and made the head*/
void note_on(uint8_t noteIndex)
{
	//Cross Reference: check if this note is already being played
	//note off must have been lost in speed of FTDI header buffer
	if (notesOn[noteIndex] == 0xFF) {
		//Note was already on, turn it off
		note_off(noteIndex);
	}
	tempHead = noteNodes[noteIndex];
	tempHead->previous = NULL;
	tempHead->next = head;
	head->previous = tempHead;
	head = tempHead;
	//Set the note on array
	notesOn[noteIndex] = 0xFF;
}
Example #6
0
/*Reads the UART buffer and completes operation set by the 
 *Control Byte*/
void read_uart(void)
{
	//Reset Count back to 0;
	uartCount = 0;
	//Byte1 is config
	if (uartBuffer[0] == 0xF0) {
		UDR0 = uartBuffer[1];
		note_on(uartBuffer[1]);
	} else if (uartBuffer [0] == 0x80) {
		note_off(uartBuffer[1]);
	} else if ((uartBuffer[0] & 0xF0) == 0b10100000) {
		//Button Setting message
		set_save_button((uartBuffer[0] & 0x0F), uartBuffer[1]);
	}
	//Update the playing notes linked list
	tword1 = tune[head->name];
	tword2 = tune[head->next->name];
	tword3 = tune[head->next->next->name];
}
Example #7
0
void Channel::set_hold_pedal(bool newstate)
{
	if (hold_pedal_pressed!=newstate)
	{
		hold_pedal_pressed=newstate;
		
		if (newstate==false)
		{
			//check for all held keys: is the key not pressed any more?
			//                         is the key not in sostenuto_keys?
			//if both conditions are fulfilled, release that note
			for (set<int>::iterator it=held_keys.begin(); it!=held_keys.end(); ++it)
				if ( (pressed_keys.find(*it)==pressed_keys.end()) &&
					   (sostenuto_keys.find(*it)==sostenuto_keys.end()) )
						note_off(*it);
			
			held_keys.clear();
		}
	}
}
Example #8
0
/*Checks buttons 4 to 7 on the lower nibble of PINB*/
void check_high_buttons(void)
{
	//Check buttons 5 - 8 on lower Nibble of PINB
	buttonState2 = (PINB & 0x0F);
	for (uint8_t pin2 = 0; pin2 <= 3; ++pin2) {
		if ((buttonState2 & (1 << pin2)) && !(prevButtonState2 & (1 << pin2))) {
			//Button Now On
			note_on(get_upper_button_tword((1<<pin2)));
			tword1 = tune[head->name];
			tword2 = tune[head->next->name];
			tword3 = tune[head->next->next->name];
			break;
		}
		if (!(buttonState2 & (1 << pin2)) && (prevButtonState2 & (1 << pin2))) {
			//Button Now Off
			note_off(get_upper_button_tword((1<<pin2)));
			tword1 = tune[head->name];
			tword2 = tune[head->next->name];
			tword3 = tune[head->next->next->name];
			break;
		}
	}
	prevButtonState2 = buttonState2;
}
Example #9
0
/*Checks buttons 0 to 3 on the lower nibble of PINA*/
void check_low_buttons(void)
{
	//Check buttons 1 - 4 lower Nibble of PINA
	buttonState1 = (PINA & 0x0F);
	for (uint8_t pin = 0; pin <= 3; ++pin) {
		if ((buttonState1 & (1 << pin)) && !(prevButtonState1 & (1 << pin))) {
			//Button Now On
			note_on(get_lower_button_tword((1 << pin)));
			tword1 = tune[head->name];
			tword2 = tune[head->next->name];
			tword3 = tune[head->next->next->name];
			break;
		}
		if (!(buttonState1 & (1 << pin)) && (prevButtonState1 & (1 << pin))) {
			//Button Now Off
			note_off(get_lower_button_tword((1 << pin)));
			tword1 = tune[head->name];
			tword2 = tune[head->next->name];
			tword3 = tune[head->next->next->name];
			break;
		}
	}
	prevButtonState1 = buttonState1;
}
Example #10
0
int
mdx_parse_mml_ym2151_async(songdata *data)
{
  int i;
  long count;
  int infinite_loops;
  __GETSELF(data)

  pcm8_clear_buffer_flush_flag(data);
 loop:
  if (self->all_track_finished==FLAG_TRUE) {
    return FLAG_FALSE;
  }

  if ( self->fade_out > 0 ) {
    if ( self->fade_out_wait==0 ) { self->fade_out_wait = self->fade_out; }
    self->fade_out_wait--;
    if ( self->fade_out_wait==0 ) { self->master_volume--; }
    if ( self->master_volume==0 ) { return FLAG_FALSE; }
  }
  ym2151_set_master_volume( self->master_volume * self->mdx->fm_volume / 127, data );
  pcm8_set_master_volume( self->master_volume * self->mdx->pcm_volume / 127, data );

  self->all_track_finished=FLAG_TRUE;
  infinite_loops = 32767; /* large enough */

  for ( i=0 ; i<self->mdx->tracks ; i++ ) {

    if ( self->mdx->track[i].waiting_sync == FLAG_TRUE )
      { continue; }

    count = self->mdx->track[i].counter;
    if ( count < 0 ) { continue; } /* this track has finished */
    self->all_track_finished=FLAG_FALSE;
    
    self->mdx->track[i].gate--;
    if ( self->mdx->track[i].gate == 0 ) { note_off( i, data ); }
    
    if ( i<8 ) {
      ym2151_set_freq_volume( i, data ); /* do portament, lfo, detune */
    }

    count--;
    while ( count == 0 ) {
      count=set_new_event( i, data );
    }

    self->mdx->track[i].counter = count;
    if ( infinite_loops > self->mdx->track[i].infinite_loop_times ) {
      infinite_loops = self->mdx->track[i].infinite_loop_times;
    }
  }

  if ( self->mdx->max_infinite_loops > 0 ) {
    if ( infinite_loops >= self->mdx->max_infinite_loops ) {
      self->fade_out = self->mdx->fade_out_speed;
    }
  }

  /* timer count */

  self->mdx->total_count++;
  self->mdx->elapsed_time += 1000*1024*(256 - self->mdx->tempo)/4000;

  return FLAG_TRUE;
}
Example #11
0
int main(int argc, char ** argv)
{
  static msg_block_t msg;
  memset((void *)&msg, 0, sizeof(msg));
  struct timespec time;
  double time0, time1;
  uint32_t notes[SCALE_PATTERN][NOTES_SIZE];
  uint32_t scales[SCALE_PATTERN][SCALE_SIZE] = {
    {0,4,7,9,},
    {0,5,7,9,},
    {2,4,7,11,},
    {2,5,7,9,},
    {2,5,7,11,},
    {0,2,4,7,},
    {0,2,5,7,},
    {0,2,5,9,},
  };
  uint32_t instruments[] = {
    0, 4, 5, 6, 8, 9, 11, 14, 15, 16, 17, 19, 24,
    25, 26, 30, 40, 42, 46, 48, 51, 52, 56, 57, 60,
    61, 63, 64, 65, 68, 69, 70, 73, 88, 89, 91, 93,
    94, 95, 98, 99, 103, 104, 110, 
  };
  uint32_t insts = sizeof(instruments) / sizeof(uint32_t);

  int fb = open(FBDEV, O_RDWR);
  if (fb > 0)
  {
    struct fb_fix_screeninfo fbfsi;
    struct fb_var_screeninfo fbvsi;
    if (ioctl(fb, FBIOGET_FSCREENINFO, &fbfsi) == 0)
    {
      msg.fbinfo.smem_start = fbfsi.smem_start;
      msg.fbinfo.smem_len = fbfsi.smem_len;
      msg.fbinfo.line_length = fbfsi.line_length;
    }
    if (ioctl(fb, FBIOGET_VSCREENINFO, &fbvsi) == 0)
    {
      msg.fbinfo.xres = fbvsi.xres;
      msg.fbinfo.yres = fbvsi.yres;
      msg.fbinfo.xres_virtual = fbvsi.xres_virtual;
      msg.fbinfo.yres_virtual = fbvsi.yres_virtual;
      msg.fbinfo.xoffset = fbvsi.xoffset;
      msg.fbinfo.yoffset = fbvsi.yoffset;
      msg.fbinfo.bits_per_pixel = fbvsi.bits_per_pixel;
    }
    close(fb);
  }

  long pagesize = (sysconf(_SC_PAGESIZE));
  int fdmem = open(MEMDEV, O_RDWR | O_SYNC);
  uint32_t *frame_buffer = NULL;
  size_t mapsize = 0;
  if ((fdmem > 0) && (msg.fbinfo.smem_start != 0))
  {
    off_t physical_page = msg.fbinfo.smem_start & (~(pagesize - 1));
    unsigned long offset = msg.fbinfo.smem_start - (unsigned long)physical_page;
    mapsize = msg.fbinfo.smem_len + offset;
    frame_buffer = mmap(NULL, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fdmem, physical_page);
    if (frame_buffer == MAP_FAILED)
    {
      perror("Framebuffer Map Failed");
    }
  }

  struct timespec time_start;
  clock_gettime(CLOCK_MONOTONIC_RAW, &time_start);
  srand((uint32_t)time_start.tv_nsec);

  seq_context_t seq;

  if (open_sequencer(&seq) == FALSE)
  {
    exit(EXIT_FAILURE);
  }
  program_change(&seq, 0, 48);
  control_change(&seq, 0, 91, 127);

  static rt_context_t rtx;
  memset((void *)&rtx, 0, sizeof(rtx));

  int width = msg.fbinfo.xres_virtual;
  int height = msg.fbinfo.yres_virtual;
  rtx.objnum = OBJNUM;
  rtx.light.pos = vec3_set(-4.0f, 8.0f, 2.0f);
  rtx.light.col = vec3_set(1.0f, 1.0f, 1.0f);
  rtx.eye = vec3_set(0.0f, 0.0f, -7.0f);
  rtx.swidth = 10.0f * (float)width / (float)height;
  rtx.sheight = 10.0f;
  rtx.width = width / SCALE;
  rtx.height = height / SCALE;
  rtx.xoff = 0;
  rtx.yoff = 0;
  rtx.ax = rtx.swidth / (float)rtx.width;
  rtx.ayc = rtx.sheight / (float)rtx.height;
  rtx.ay = rtx.sheight / (float)rtx.height;

  uint32_t i, j;
  for (i = 0; i < SCALE_PATTERN; i++)
  {
    for (j = 0; j < NOTES_SIZE; j++)
    {
      notes[i][j] = scales[i][j % SCALE_SIZE] + (j / SCALE_SIZE) * 12;
    }
  }

  for (i = 0; i < rtx.objnum; i++)
  {
    rtx.obj[i].type = SPHERE;
    rtx.obj[i].pos = vec3_set(0.0f, -100.0f, 0.0f);
    rtx.obj[i].rad = 1.0f;
    rtx.obj[i].col = vec3_set(randf(), randf(), randf());
    rtx.obj[i].flag_shadow = TRUE;
    rtx.obj[i].flag_refrect = TRUE;
    rtx.obj[i].spd = vec3_set(0.0f, 0.0f, 0.0f);
    rtx.obj[i].note = 0;
  }

  rtx.obj[0].type = PLANE;
  rtx.obj[0].norm = normalize(vec3_set(0.0f, 1.0f, 0.0f));
  rtx.obj[0].dist = 2.0f;
  rtx.obj[0].col = vec3_set(0.1f, 0.3f, 0.6f);
  rtx.obj[0].flag_shadow = TRUE;
  rtx.obj[0].flag_refrect = TRUE;
  rtx.obj[0].spd = vec3_set(0.0f, 0.0f, 0.0f);

  uint32_t scale = 0;
  uint32_t curobj = 0;
  float next_note_time = get_elapsed(time_start) + 3.0f;
  float next_scale_time = get_elapsed(time_start) + 15.0f + randf() * 15.0f;
  float time_now = get_elapsed(time_start);
  float time_quit = time_now + 3600.0f;
  uint32_t retry_count = 0;
  uint32_t counter = 0;
  float time_prev = 0.0f;
  while(time_now < time_quit)
  {
    uint32_t e;
    for (e = 1; e < rtx.objnum; e++)
    {
      rtx.obj[e].pos = vec3_add(rtx.obj[e].pos, rtx.obj[e].spd);
    }
    time_now = get_elapsed(time_start);
    if (time_now > next_note_time)
    {
      e = (curobj % (rtx.objnum - 1)) + 1;
      rtx.obj[e].pos = vec3_set(randf()*8.0f-4.0f, randf()*6.0f-1.0f, randf()*8.0+0.0f);
      rtx.obj[e].col = vec3_set(randf(), randf(), randf());
      rtx.obj[e].spd = vec3_set(randf()*0.1f-0.05f,randf()*0.1f-0.05f,randf()*0.1f-0.05f);
      note_off(&seq, 0, rtx.obj[e].note);
      rtx.obj[e].note = notes[scale][(uint32_t)(randf() * 17.0f) + 12];
      note_on(&seq, 0, rtx.obj[e].note, 127 - rtx.obj[e].note);
      curobj++;
      float len = (randf() + 0.5f);
      next_note_time = time_now + len * len * len;
    }
    if (time_now > next_scale_time)
    {
      scale = (uint32_t)(randf() * (float)SCALE_PATTERN);
      program_change(&seq, 0, instruments[(uint32_t)(randf() * ((float)insts + 0.99f))]);
      rtx.obj[0].col = vec3_set(randf(), randf(), randf());
      rtx.light.pos = vec3_set(randf() * 8.0f - 4.0f, 8.0f, randf() * 4.0f);
      next_scale_time = time_now + (randf() + 0.1f) * 40.0f;
    }

    render(&msg, &rtx, frame_buffer);

    counter++;
    if (counter > 100)
    {
      //printf("FPS: %.2f\n", 100.0f / (time_now - time_prev));
      time_prev = time_now;
      counter = 0;
    }
  }

  close_sequencer(&seq);
  munmap(frame_buffer, mapsize);
  close(fdmem);
  return 0;
}
Example #12
0
int mdx_parse_mml_ym2151_async(void* in_self)
{
    int i;
    long count;
    struct timeval st,et;
    int infinite_loops;
    mdxmml_ym2151_instances* self = (mdxmml_ym2151_instances *)in_self;

    pcm8_clear_buffer_flush_flag();
    gettimeofday(&st, NULL);
    gettimeofday(&et, NULL);

loop:
    if (self->all_track_finished==FLAG_TRUE) {
        return FLAG_FALSE;
    }

    if ( self->fade_out > 0 ) {
        if ( self->fade_out_wait==0 ) {
            self->fade_out_wait = self->fade_out;
        }
        self->fade_out_wait--;
        if ( self->fade_out_wait==0 ) {
            self->master_volume--;
        }
        if ( self->master_volume==0 ) {
            return FLAG_FALSE;
        }
    }
    ym2151_set_master_volume( self->master_volume * self->mdx->fm_volume / 127 );
    pcm8_set_master_volume( self->master_volume * self->mdx->pcm_volume / 127 );

    self->all_track_finished=FLAG_TRUE;
    infinite_loops = 32767; /* large enough */

    for ( i=0 ; i<self->mdx->tracks ; i++ ) {

        if ( self->mdx->track[i].waiting_sync == FLAG_TRUE )
        {
            continue;
        }

        count = self->mdx->track[i].counter;
        if ( count < 0 ) {
            continue;    /* this track has finished */
        }
        self->all_track_finished=FLAG_FALSE;

        self->mdx->track[i].gate--;
        if ( self->mdx->track[i].gate == 0 ) {
            note_off( i );
        }

        if ( i<8 ) {
            ym2151_set_freq_volume( i ); /* do portament, lfo, detune */
        }

        count--;
        while ( count == 0 ) {
            count=set_new_event( i );
        }

        self->mdx->track[i].counter = count;
        if ( infinite_loops > self->mdx->track[i].infinite_loop_times ) {
            infinite_loops = self->mdx->track[i].infinite_loop_times;
        }
    }

    if ( self->mdx->max_infinite_loops > 0 ) {
        if ( infinite_loops >= self->mdx->max_infinite_loops ) {
            self->fade_out = self->mdx->fade_out_speed;
        }
    }

    /* timer count */

    self->mdx->total_count++;
    self->mdx->elapsed_time += 1000*1024*(256 - self->mdx->tempo)/4000;

    /*  st.tv_usec += 1000* 1024*(256 - self->mdx->tempo)/4000;
      while ( st.tv_usec >= 1000*1000 ) {
        st.tv_usec-=1000*1000;
        st.tv_sec++;
      }

      while( timercmp(&st,&et,>) ) {
        do_pcm8();
        et.tv_usec += PCM8_SYSTEM_RATE*1000;
        while ( et.tv_usec >= 1000*1000 ) {
          et.tv_usec-=1000*1000;
          et.tv_sec++;
        }
      }

      if (pcm8_buffer_flush_flag()==FLAG_FALSE) {
        goto loop;
      }*/

    return FLAG_TRUE;
}
Example #13
0
/*
 * Process an event in a driver independent way.  This means dealing
 * with RPN, NRPN, SysEx etc that are defined for common midi applications
 * such as GM, GS and XG.
 * There modes that this module will run in are:
 *   Generic MIDI - no interpretation at all, it will just save current values
 *                  of controllers etc.
 *   GM - You can use all gm_ prefixed elements of chan.  Controls, RPN, NRPN,
 *        SysEx will be interpreded as defined in General Midi.
 *   GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
 *        interpreted.
 *   XG - You can use all xg_ prefixed elements of chan.  Codes for XG will
 *        be interpreted.
 */
void
snd_midi_process_event(struct snd_midi_op *ops,
		       struct snd_seq_event *ev,
		       struct snd_midi_channel_set *chanset)
{
	struct snd_midi_channel *chan;
	void *drv;
	int dest_channel = 0;

	if (ev == NULL || chanset == NULL) {
		pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n");
		return;
	}
	if (chanset->channels == NULL)
		return;

	if (snd_seq_ev_is_channel_type(ev)) {
		dest_channel = ev->data.note.channel;
		if (dest_channel >= chanset->max_channels) {
			pr_debug("ALSA: seq_midi_emul: dest channel is %d, max is %d\n",
				   dest_channel, chanset->max_channels);
			return;
		}
	}

	chan = chanset->channels + dest_channel;
	drv  = chanset->private_data;

	/* EVENT_NOTE should be processed before queued */
	if (ev->type == SNDRV_SEQ_EVENT_NOTE)
		return;

	/* Make sure that we don't have a note on that should really be
	 * a note off */
	if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
		ev->type = SNDRV_SEQ_EVENT_NOTEOFF;

	/* Make sure the note is within array range */
	if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
	    ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
	    ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
		if (ev->data.note.note >= 128)
			return;
	}

	switch (ev->type) {
	case SNDRV_SEQ_EVENT_NOTEON:
		if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
			if (ops->note_off)
				ops->note_off(drv, ev->data.note.note, 0, chan);
		}
		chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
		if (ops->note_on)
			ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
		break;
	case SNDRV_SEQ_EVENT_NOTEOFF:
		if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
			break;
		if (ops->note_off)
			note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
		break;
	case SNDRV_SEQ_EVENT_KEYPRESS:
		if (ops->key_press)
			ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
		break;
	case SNDRV_SEQ_EVENT_CONTROLLER:
		do_control(ops, drv, chanset, chan,
			   ev->data.control.param, ev->data.control.value);
		break;
	case SNDRV_SEQ_EVENT_PGMCHANGE:
		chan->midi_program = ev->data.control.value;
		break;
	case SNDRV_SEQ_EVENT_PITCHBEND:
		chan->midi_pitchbend = ev->data.control.value;
		if (ops->control)
			ops->control(drv, MIDI_CTL_PITCHBEND, chan);
		break;
	case SNDRV_SEQ_EVENT_CHANPRESS:
		chan->midi_pressure = ev->data.control.value;
		if (ops->control)
			ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
		break;
	case SNDRV_SEQ_EVENT_CONTROL14:
		/* Best guess is that this is any of the 14 bit controller values */
		if (ev->data.control.param < 32) {
			/* set low part first */
			chan->control[ev->data.control.param + 32] =
				ev->data.control.value & 0x7f;
			do_control(ops, drv, chanset, chan,
				   ev->data.control.param,
				   ((ev->data.control.value>>7) & 0x7f));
		} else
Example #14
0
void Channel::note_on(int note, int vel)
{
	list<NoteSkel*>::iterator it;
	if (vel>0) //note on
	{
		pressed_keys.insert(note);
		
		if (program_lock[program]==false)
		{		
			if ( (n_voices==1) && (!notes.empty()) ) //we're in monomode
			{
				//no need to create a new note; reuse the existing
				NoteSkel *n; //i'm lazy
				n= *(notes.begin());
				
				if (n->get_program() != program)
				{
					//if the program has changed, kill the previous note and
					//create a new one
					n->destroy();
					notes.clear();
					
					NoteSkel *newnote=NULL;
					if (curr_prg.create_func==NULL)
						newnote = new Note(note,(float)vel/128.0,
															 curr_prg,
															 portamento_frames, pitchbend, 
															 program,
															 curr_vol_factor);
					else
						newnote = curr_prg.create_func(note,(float)vel/128.0,
																					 curr_prg,
																					 portamento_frames, pitchbend, 
																					 program,
																					 curr_vol_factor);

					notes.push_back(newnote);
				}
				else //program did not change
				{
					//if not still active, don't do portamento
					n->set_note(note,n->still_active());
					n->set_vel((float)vel/128.0);
					if ((legato_pedal_pressed==false) || !n->still_active()) n->reattack();
					n->set_vol_factor(curr_vol_factor);
					//no need to push back. would become #1 instead of #1
				}
			}
			else //we're in polymode
			{
				bool neednewnote=true;
				//if (always_reattack) always_reattack is always true when in polymode
					for (it=notes.begin(); it!=notes.end(); ++it)
						if ( ((*it)->get_note()==note) && ((*it)->get_program()==program) )
						{
							neednewnote=false;
							(*it)->reattack();
							(*it)->set_vel((float)vel/128.0);
							(*it)->set_vol_factor(curr_vol_factor);
							notes.push_back(*it); //reorder notes
							notes.erase(it);
							break;
						}

				if (neednewnote)
				{
					NoteSkel *newnote=NULL;
					if (curr_prg.create_func==NULL)
						newnote = new Note(note,(float)vel/128.0,
															 curr_prg,
															 portamento_frames, pitchbend, 
															 program,
															 curr_vol_factor);
					else
						newnote = curr_prg.create_func(note,(float)vel/128.0,
																					 curr_prg,
																					 portamento_frames, pitchbend, 
																					 program,
																					 curr_vol_factor);

					notes.push_back(newnote);
				}

				apply_voice_limit();
			}
		}
		// else (if the program is locked) simply ignore the note-on
	}                                                  
	else //note off
	{
		note_off(note);
	}
		
}
Example #15
0
void play_note(int pitch, float length) {
  note_on (pitch, 100);
  usleep((int) (length * 1000000));
  note_off(pitch, 100);
}
Example #16
0
int mdx_parse_mml_ym2151( MDX_DATA *orig_mdx, PDX_DATA *orig_pdx ) {
    int i;
    long count;

    struct timeval st,et;
    int fade_out_wait;
    int master_volume;
    int infinite_loops;

    __GETSELF;

    self->mdx = orig_mdx;
    self->pdx = orig_pdx;

    mdx_init_track_work_area_ym2151();

    self->pcm8_disable=FLAG_TRUE;
    if ( pcm8_open(self->mdx)==0 ) {
        self->pcm8_disable=FLAG_FALSE;
    }

    if (!ym2151_reg_init( self->mdx )) {
        /* failed to initialize opm! */
        pcm8_close();
        return 1;
    }

    /* start parsing */

    all_track_finished=FLAG_FALSE;
    fade_out_wait=0;
    master_volume=127;

    gettimeofday(&st, NULL);
    srand((int)st.tv_usec%65536);
    gettimeofday(&et, NULL);

    while(all_track_finished==FLAG_FALSE) {

        if ( self->fade_out > 0 ) {
            if ( fade_out_wait==0 ) {
                fade_out_wait = self->fade_out;
            }
            fade_out_wait--;
            if ( fade_out_wait==0 ) {
                master_volume--;
            }
            if ( master_volume==0 ) {
                break;
            }
        }
        ym2151_set_master_volume( master_volume * self->mdx->fm_volume / 127 );
        pcm8_set_master_volume( master_volume * self->mdx->pcm_volume / 127 );

        all_track_finished=FLAG_TRUE;
        infinite_loops = 32767; /* large enough */
        for ( i=0 ; i<self->mdx->tracks ; i++ ) {

            if ( self->mdx->track[i].waiting_sync == FLAG_TRUE )
            {
                continue;
            }

            count = self->mdx->track[i].counter;
            if ( count < 0 ) {
                continue;    /* this track has finished */
            }
            all_track_finished=FLAG_FALSE;

            self->mdx->track[i].gate--;
            if ( self->mdx->track[i].gate == 0 ) {
                note_off( i );
            }

            if ( i<8 ) {
                ym2151_set_freq_volume( i ); /* do portament, lfo, detune */
            }

            count--;
            while ( count == 0 ) {
                count=set_new_event( i );
            }

            self->mdx->track[i].counter = count;
            if ( infinite_loops > self->mdx->track[i].infinite_loop_times ) {
                infinite_loops = self->mdx->track[i].infinite_loop_times;
            }
        }

        if ( self->mdx->max_infinite_loops > 0 ) {
            if ( infinite_loops >= self->mdx->max_infinite_loops ) {
                self->fade_out = self->mdx->fade_out_speed;
            }
        }

        /* timer count */

        self->mdx->total_count++;
        self->mdx->elapsed_time += 1000*1024*(256 - self->mdx->tempo)/4000;

        st.tv_usec += 1000* 1024*(256 - self->mdx->tempo)/4000;
        while ( st.tv_usec >= 1000*1000 ) {
            st.tv_usec-=1000*1000;
            st.tv_sec++;
        }

        while( timercmp(&st,&et,>) ) {
            do_pcm8(0);
            et.tv_usec += 1000;//PCM8_SYSTEM_RATE*1000;
            while ( et.tv_usec >= 1000*1000 ) {
                et.tv_usec-=1000*1000;
                et.tv_sec++;
            }
        }
    }
    //for (i=0;i<1000;i++)	do_pcm8(0);
    do_pcm8(1);

    ym2151_all_note_off();
    pcm8_close();
    mdx_ym2151_shutdown();

    return 0;
}
Example #17
0
int mdx_get_length( MDX_DATA *orig_mdx, PDX_DATA *orig_pdx ) {
    int i;
    long count;

    struct timeval st;
    int infinite_loops;
    int fade_out_wait;
    int length_ms,master_volume;

    __GETSELF;

    length_ms=0;

    self->mdx = orig_mdx;
    self->pdx = orig_pdx;

    mdx_init_track_work_area_ym2151();

    /* start parsing */

    all_track_finished=FLAG_FALSE;
    fade_out_wait=0;
    master_volume=127;

    gettimeofday(&st, NULL);
    srand((int)st.tv_usec%65536);

    while(all_track_finished==FLAG_FALSE) {

        if ( self->fade_out > 0 ) {
            if ( fade_out_wait==0 ) {
                fade_out_wait = self->fade_out;
            }
            fade_out_wait--;
            if ( fade_out_wait==0 ) {
                master_volume--;
            }
            if ( master_volume==0 ) {
                break;
            }
        }

        all_track_finished=FLAG_TRUE;
        infinite_loops = 32767; /* large enough */
        for ( i=0 ; i<self->mdx->tracks ; i++ ) {

            if ( self->mdx->track[i].waiting_sync == FLAG_TRUE )
            {
                continue;
            }

            count = self->mdx->track[i].counter;
            if ( count < 0 ) {
                continue;    /* this track has finished */
            }
            all_track_finished=FLAG_FALSE;

            self->mdx->track[i].gate--;
            if ( self->mdx->track[i].gate == 0 ) {
                note_off( i );
            }

            if ( i<8 ) {
                ym2151_set_freq_volume( i ); /* do portament, lfo, detune */
            }

            count--;
            while ( count == 0 ) {
                count=set_new_event( i );
            }

            self->mdx->track[i].counter = count;
            if ( infinite_loops > self->mdx->track[i].infinite_loop_times ) {
                infinite_loops = self->mdx->track[i].infinite_loop_times;
            }
        }

        if ( self->mdx->max_infinite_loops > 0 ) {
            if ( infinite_loops >= self->mdx->max_infinite_loops ) {
                self->fade_out = self->mdx->fade_out_speed;
            }
        }

        /* timer count */

        self->mdx->total_count++;
        self->mdx->elapsed_time += 1000*1024*(256 - self->mdx->tempo)/4000;

        st.tv_usec += 1000* 1024*(256 - self->mdx->tempo)/4000;
        length_ms += 1024*(256 - self->mdx->tempo)/4000;
        while ( st.tv_usec >= 1000*1000 ) {
            st.tv_usec-=1000*1000;
            st.tv_sec++;
        }
    }

    return length_ms;
}
Example #18
0
int main(void)
{
  unsigned char cf,key_data;
  int vol = 127;

  ROMEMU();
  da_init();
  timer_init();

  P6DDR &= ~0x07;  /* P60,1,2   入力 */
  PADDR |= 0x0f;   /* PA0,1,2,3 出力 */

  tone_init();
  
  while (1)
  {
	key_data = 0;

    //key 1,2,3
    PADR = 0x07; // PA3 = L
    cf = P6DR;   // データ入力
    cf = ~cf;    // cfの反転
    cf &= 0x07;  // P60,1,2のみ見る
    switch(cf) {
    case 1 : key_data = '1'; break;
    case 2 : key_data = '2'; break;
    case 4 : key_data = '3'; break;
    }  
      
    //key 4,5,6
    PADR = 0x0b;
    cf = P6DR;
    cf = ~cf;
    cf &= 0x07;
    switch(cf) {
    case 1 : key_data = '4'; break;
    case 2 : key_data = '5'; break;
    case 4 : key_data = '6'; break;
    }  
      
    //key 7,8,9
    PADR = 0x0d; /* This is a mistake code. */
    cf = P6DR;
    cf = ~cf;
    cf &= 0x07;
    switch(cf) {
    case 1 : key_data = '7'; break;
    case 2 : key_data = '8'; break;
    case 4 : key_data = '9'; break;
    }  
      
    //key *,0,#
    PADR = 0x0e;
    cf = P6DR;
    cf = ~cf;
    cf &= 0x07;
    switch(cf) {
    case 1 : key_data = '*'; break;
    case 2 : key_data = '0'; break;
    case 4 : key_data = '#'; break;
    } 

	switch(key_data)
	{
    case '1':
      note_on(DO_L,vol);
      break;
    case '2':
      note_on(RE,vol);
      break;
    case '3':
      note_on(MI,vol);
      break;
    case '4':
      note_on(FA,vol);
      break;
    case '5':
      note_on(SO,vol);
      break;
    case '6':
      note_on(RA,vol);
      break;
    case '7':
      note_on(SI,vol);
      break;
    case '8':
      note_on(DO_H,vol);
      break;
    default:
	  note_off();
	  break;
	}
  }
  return 1;
}
Example #19
0
static int
set_new_event( int t )
{
    int ptr;
    unsigned char *data;
    int count;
    int follower;
    __GETMDX;

    data = mdx->data;
    ptr = mdx->track[t].current_mml_ptr;
    count = 0;
    follower = 0;

#if 0
    if ( ptr+1 <= mdx->length && t>7 ) {
        fprintf(stderr,"%2d %2x %2x\n",t,data[ptr],data[ptr+1]);
        fflush(stderr);
    }
#endif

    if ( data[ptr] <= MDX_MAX_REST ) {  /* rest */
        note_off(t);
        count = data[ptr]+1;
        mdx->track[t].gate = count+1;
        follower=0;

    } else if ( data[ptr] <= MDX_MAX_NOTE ) { /* note */
        note_on( t, data[ptr]);
        count = data[ptr+1]+1;
        do_quantize( t, count );
        follower = 1;

    } else {
        switch ( data[ptr] ) {

        case MDX_SET_TEMPO:
            set_tempo( data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_OPM_REG:
            set_opm_reg( t, data[ptr+1], data[ptr+2] );
            follower = 2;
            break;

        case MDX_SET_VOICE:
            set_voice( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_PHASE:
            set_phase( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_VOLUME:
            set_volume( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_VOLUME_DEC:
            dec_volume( t );
            follower = 0;
            break;

        case MDX_VOLUME_INC:
            inc_volume( t );
            follower = 0;
            break;

        case MDX_SET_QUANTIZE:
            set_quantize( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_KEYOFF:
            set_keyoff( t );
            follower = 0;
            break;

        case MDX_REPEAT_START:
            mdx->track[t].loop_counter[mdx->track[t].loop_depth] = data[ptr+1];
            if ( mdx->track[t].loop_depth < MDX_MAX_LOOP_DEPTH )
                mdx->track[t].loop_depth++;
            follower = 2;
            break;

        case MDX_REPEAT_END:
            if (--mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 0 ) {
                if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0;
            } else {
                if ( data[ptr+1] >= 0x80 ) {
                    ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2;
                } else {
                    ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] - 2;
                }
            }
            follower = 2;
            break;

        case MDX_REPEAT_BREAK:
            if ( mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 1 ) {
                if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0;
                ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] -2 +2;
            }
            follower = 2;
            break;

        case MDX_SET_DETUNE:
            set_detune( t, data[ptr+1], data[ptr+2] );
            follower = 2;
            break;

        case MDX_SET_PORTAMENT:
            set_portament( t, data[ptr+1], data[ptr+2] );
            follower = 2;
            break;

        case MDX_DATA_END:
            if ( data[ptr+1] == 0x00 ) {
                count = -1;
                note_off(t);
                follower = 1;
            } else {
                ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2;
                mdx->track[t].infinite_loop_times++;
                follower = 2;
            }
            break;

        case MDX_KEY_ON_DELAY:
            follower = 1;
            break;

        case MDX_SEND_SYNC:
            send_sync( data[ptr+1] );
            follower = 1;
            break;

        case MDX_RECV_SYNC:
            recv_sync( t );
            follower = 0;
            count = 1;
            break;

        case MDX_SET_FREQ:
            set_freq( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_PLFO:
            if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) {
                set_plfo_onoff( t, data[ptr+1]-0x80 );
                follower = 1;
            } else {
                set_plfo( t,
                          data[ptr+1], data[ptr+2], data[ptr+3],
                          data[ptr+4], data[ptr+5] );
                follower = 5;
            }
            break;

        case MDX_SET_ALFO:
            if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) {
                set_alfo_onoff( t, data[ptr+1]-0x80 );
                follower = 1;
            } else {
                set_alfo( t,
                          data[ptr+1], data[ptr+2], data[ptr+3],
                          data[ptr+4], data[ptr+5] );
                follower = 5;
            }
            break;

        case MDX_SET_OPMLFO:
            if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) {
                set_hlfo_onoff( t, data[ptr+1]-0x80 );
                follower = 1;
            } else {
                set_hlfo( t,
                          data[ptr+1], data[ptr+2], data[ptr+3],
                          data[ptr+4], data[ptr+5] );
                follower = 5;
            }
            break;

        case MDX_SET_LFO_DELAY:
            set_lfo_delay( t, data[ptr+1] );
            follower = 1;
            break;

        case MDX_SET_PCM8_MODE:
            follower = 0;
            break;

        case MDX_FADE_OUT:
            if ( data[ptr+1]==0x00 ) {
                follower = 1;
                set_fade_out( 5 );
            } else {
                follower = 2;
                set_fade_out( data[ptr+2] );
            }
            break;

        default:
            count = -1;
            break;
        }
    }

    ptr += 1+follower;
    mdx->track[t].current_mml_ptr = ptr;

    return count;
}
Example #20
0
 void terminate( int ch, int num ) {
   note_off( ch, num );
 }
Example #21
0
int 
main(int argc, char** argv) {


  int c, i, rd, j;
  long bytes_read = 0;
  int samples_per_tick;
  div_t rest;
  rdfun input_read;
  char* input = "alsa:default";

  while ( ( c = getopt(argc, argv, "vphN:o:g:k:r:c:lS:i:t:s") ) != -1) 
	switch (c) {
	case 'v': debug++; break;
	case 'p': print_freqs = 1; break;
	case 'h': use_harm_comp = 1; break;
	case 'N': N = atoi(optarg); break;
	case 'g': gain = atof(optarg); break;
	case 'o': 
	  if (strcmp(optarg, "seq") == 0 ) use_sequencer = 1;
	  else midi_filename =strdup(optarg); 
	  break;
	case 'k': hysteresis = atof(optarg); break;
	case 'r': ringsize = atoi(optarg); break;
	case 'c': midi_channel = atoi(optarg); break;
	case 'i': input = strdup(optarg); break;
	case 'S': SR = atoi(optarg); break;
	case 's': print_statistics = 1; break;
	case 't': threshold = atof(optarg); break;
	default: usage();
	}

  if ( debug > 0 )
	fprintf(stderr, 
			"ringbuffersize: %d ringbuffermask:0x%08x\n"
			"gain: %f\n",
			RINGBUFFERSIZE, RINGBUFFERMASK, gain);



  print_prologoue(N, SR);

  input_read = input_open(input);

  // allocate buffers

  buffer_f = (real_t**)malloc ( RINGBUFFERSIZE * sizeof(real_t*) );
  for ( j = 0; j < RINGBUFFERSIZE; j++ ) {
	buffer_f[j] = malloc ( N * sizeof(real_t) );
	for ( i = 0; i < N ; i ++ )
	  buffer_f[j][i] = 0.0;
  }


  // prepare midi file
  if (midi_filename != NULL ) {
	midi_file = midi_write_open(midi_filename);
	midi_write_header(midi_timeDivision, 1, midi_file);
	midi_write_track_header(midi_file);
  }

  if ( use_sequencer )
	midi_connect_sequencer();


  // prebuffer everthing
  precalculate();

  samples_per_tick = samples_per_midi_tick(SR, midi_bpm, midi_timeDivision);
  rest.rem = 0;

  // process data
  while ( (rd = input_read(buffer_f[current_buffer], N)) ) { 

	bytes_read += rd;

	rest = div(rest.rem + N, samples_per_tick);

	if (midi_file != NULL )
	  midi_write_increase_difftime(rest.quot, midi_file);

	absolute_time += N;

 	scan_freqs(); 

	// advance buffer:
	current_buffer = (current_buffer+1) & RINGBUFFERMASK;
  }



  for ( j = lo_note; j < hi_note; j++ ) {
	if ( act_freq[j] )
	  note_off(j, 0);
  }

  // free stuff
  for ( j = 0; j < RINGBUFFERSIZE; j++ ) free(buffer_f[j]);
  free(buffer_f);
  for (i = 0; i< NTONES; i++ ) free(cos_precalc[i]);

  // fixup midi
  if (midi_file != NULL ) {
	midi_write_track_end(midi_file);
	midi_write_close(midi_file);
  }


  if ( print_statistics ) {

	// octave style output of powers over frequency
	// first row: frequencies
	// second row: power for that freq
	fprintf(stderr, "freqs = [");
	for (j=lo_note;j<hi_note-1;j++) fprintf(stderr, "%.2f,", midi_note_to_hertz(j));
	fprintf(stderr, "%.2f", midi_note_to_hertz(j));
	fprintf(stderr, ";");
	for (j=lo_note;j<hi_note-1;j++) fprintf(stderr, "%.2f,", max_powers[j]);
	fprintf(stderr, "%.2f", max_powers[j]);
	fprintf(stderr, "];\n");
	
	fprintf(stderr, 
			"\n\n note_ons:%ld bytes_read:%ld playtime:%ld:%ld\n", 
			stats_note_ons, bytes_read, bytes_read/(SR*60), (bytes_read / SR)%60 );
  }


  input_close();

  print_epilogue();

  return 0;
}
void
snd_midi_process_event(struct snd_midi_op *ops,
                       struct snd_seq_event *ev,
                       struct snd_midi_channel_set *chanset)
{
    struct snd_midi_channel *chan;
    void *drv;
    int dest_channel = 0;

    if (ev == NULL || chanset == NULL) {
        snd_printd("ev or chanbase NULL (snd_midi_process_event)\n");
        return;
    }
    if (chanset->channels == NULL)
        return;

    if (snd_seq_ev_is_channel_type(ev)) {
        dest_channel = ev->data.note.channel;
        if (dest_channel >= chanset->max_channels) {
            snd_printd("dest channel is %d, max is %d\n",
                       dest_channel, chanset->max_channels);
            return;
        }
    }

    chan = chanset->channels + dest_channel;
    drv  = chanset->private_data;


    if (ev->type == SNDRV_SEQ_EVENT_NOTE)
        return;

    if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
        ev->type = SNDRV_SEQ_EVENT_NOTEOFF;


    if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
            ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
            ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
        if (ev->data.note.note >= 128)
            return;
    }

    switch (ev->type) {
    case SNDRV_SEQ_EVENT_NOTEON:
        if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
            if (ops->note_off)
                ops->note_off(drv, ev->data.note.note, 0, chan);
        }
        chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
        if (ops->note_on)
            ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
        break;
    case SNDRV_SEQ_EVENT_NOTEOFF:
        if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
            break;
        if (ops->note_off)
            note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
        break;
    case SNDRV_SEQ_EVENT_KEYPRESS:
        if (ops->key_press)
            ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
        break;
    case SNDRV_SEQ_EVENT_CONTROLLER:
        do_control(ops, drv, chanset, chan,
                   ev->data.control.param, ev->data.control.value);
        break;
    case SNDRV_SEQ_EVENT_PGMCHANGE:
        chan->midi_program = ev->data.control.value;
        break;
    case SNDRV_SEQ_EVENT_PITCHBEND:
        chan->midi_pitchbend = ev->data.control.value;
        if (ops->control)
            ops->control(drv, MIDI_CTL_PITCHBEND, chan);
        break;
    case SNDRV_SEQ_EVENT_CHANPRESS:
        chan->midi_pressure = ev->data.control.value;
        if (ops->control)
            ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
        break;
    case SNDRV_SEQ_EVENT_CONTROL14:

        if (ev->data.control.param < 32) {

            chan->control[ev->data.control.param + 32] =
                ev->data.control.value & 0x7f;
            do_control(ops, drv, chanset, chan,
                       ev->data.control.param,
                       ((ev->data.control.value>>7) & 0x7f));
        } else
Example #23
0
void do_keyboard_mode(void) {
  signed int shift = 0;
  uint8_t accent=0, slide=0;
  uint8_t i, last_bank;
  
  // turn tempo off!
  turn_off_tempo();
  
  clear_bank_leds();

  read_switches();
  last_bank = bank;
  has_bank_knob_changed(); // ignore startup change

  while (1) {
    read_switches();

    if (function_changed) {
      midi_notesoff();           // turn all notes off
      return;
    }
  
    // show the current MIDI address
    if (!is_bank_led_set(midi_out_addr)) {
      clear_bank_leds();
      set_bank_led(midi_out_addr);
    }

    if (has_bank_knob_changed()) {
      // bank knob was changed, which means they want a different
      // midi addr... OK then!
      midi_out_addr = bank;

      // set the new midi address (burn to EEPROM)
      internal_eeprom_write8(MIDIOUT_ADDR_EEADDR, midi_out_addr);

      last_bank = bank;
    }

    // show the octave
    display_octave_shift(shift);

    for (i=0; i<13; i++) {
      // check if any notes were just pressed
      if (just_pressed(notekey_tab[i])) {
	note_on((C2+i) + shift*OCTAVE, slide, accent);
	midi_send_note_on( ((C2+i) + shift*OCTAVE) | (accent << 6));
	slide = TRUE;

	// turn on that LED
	set_notekey_led(i);	
      }
      
      // check if any notes were released
      if (just_released(notekey_tab[i])) {
	midi_send_note_off( ((C2+i) + shift*OCTAVE) | (accent << 6));

	// turn off that LED
	clear_notekey_led(i);
      }
    }

    if (just_pressed(KEY_UP)) {
      if (shift < 2)
	shift++;
    } else if (just_pressed(KEY_DOWN)) {
      if (shift > -1)
	shift--;
    } 

    // check if they turned accent on
    if (just_pressed(KEY_ACCENT)) {
      accent = !accent;
      if (accent)
	set_led(LED_ACCENT);
      else
	clear_led(LED_ACCENT);
    }
    
    // if no keys are held down and there was a note just playing
    // turn off the note.
    if ((NOTE_PIN & 0x3F) && no_keys_pressed()) {
      note_off(0);
      slide = FALSE;
      clear_notekey_leds();
    }
  }
}
Example #24
0
int
mdx_parse_mml_ym2151( MDX_DATA *orig_mdx, PDX_DATA *orig_pdx, songdata *data )
{
  int i;
  long count;
  int all_track_finished;
  int fade_out_wait;
  int master_volume;
  int infinite_loops;

  __GETSELF(data);

  self->mdx = orig_mdx;
  self->pdx = orig_pdx;

  mdx_init_track_work_area_ym2151(data);

  self->pcm8_disable=FLAG_TRUE;
  if ( pcm8_open(self->mdx, data)==0 ) {
    self->pcm8_disable=FLAG_FALSE;
  }

  if (!ym2151_reg_init( self->mdx, data )) {
    /* failed to initialize opm! */
    return 1;
  }

  /* start parsing */

  all_track_finished=FLAG_FALSE;
  fade_out_wait=0;
  master_volume=127;

  while(all_track_finished==FLAG_FALSE) {

    if ( self->fade_out > 0 ) {
      if ( fade_out_wait==0 ) { fade_out_wait = self->fade_out; }
      fade_out_wait--;
      if ( fade_out_wait==0 ) { master_volume--; }
      if ( master_volume==0 ) { break; }
    }
    ym2151_set_master_volume( master_volume * self->mdx->fm_volume / 127, data );
    pcm8_set_master_volume( master_volume * self->mdx->pcm_volume / 127, data );

    all_track_finished=FLAG_TRUE;
    infinite_loops = 32767; /* large enough */
    for ( i=0 ; i<self->mdx->tracks ; i++ ) {

      if ( self->mdx->track[i].waiting_sync == FLAG_TRUE )
	{ continue; }

      count = self->mdx->track[i].counter;
      if ( count < 0 ) { continue; } /* this track has finished */
      all_track_finished=FLAG_FALSE;

      self->mdx->track[i].gate--;
      if ( self->mdx->track[i].gate == 0 ) { note_off( i, data ); }

      if ( i<8 ) {
	ym2151_set_freq_volume( i, data ); /* do portament, lfo, detune */
      }

      count--;
      while ( count == 0 ) {
	count=set_new_event( i, data );
      }

      self->mdx->track[i].counter = count;
      if ( infinite_loops > self->mdx->track[i].infinite_loop_times ) {
	infinite_loops = self->mdx->track[i].infinite_loop_times;
      }
    }

    if ( self->mdx->max_infinite_loops > 0 ) {
      if ( infinite_loops >= self->mdx->max_infinite_loops ) {
	self->fade_out = self->mdx->fade_out_speed;
      }
    }

    /* timer count */

    self->mdx->total_count++;
    self->mdx->elapsed_time += 1000*1024*(256 - self->mdx->tempo)/4000;

	do_pcm8(NULL,-1, data);
    
	}

  ym2151_all_note_off(data);
  pcm8_close(data);
  ym2151_shutdown(data);

  return 0;
}