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; } }
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); } }
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; } } }
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"); ; } }
/*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; }
/*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]; }
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(); } } }
/*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; }
/*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; }
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; }
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; }
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; }
/* * 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
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); } }
void play_note(int pitch, float length) { note_on (pitch, 100); usleep((int) (length * 1000000)); note_off(pitch, 100); }
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; }
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; }
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; }
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; }
void terminate( int ch, int num ) { note_off( ch, num ); }
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
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(); } } }
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; }