/*=========================================================================== external functions implementation =========================================================================== */ MidiEvPtr MidiStreamPutEvent (Ev2StreamPtr f, MidiEvPtr e) { if (f->count) return e; if (EvType(e) == typeNote) { (f->lin[EvType(e)]) (e, f); EvType(e) = typeKeyOn; Vel(e) = 0; Date(e) += Dur(e); return e; } (f->lin[EvType(e)]) (e, f); return 0; }
void TrsfTempoSeq(MidiSeqPtr s, double ticks) { double tt; // dur?e d'un ticks (micro sec) double t1; // temps du dernier changement de tempo (micro sec) double t2; // temps actuel (micro sec) long d1; // date du dernier changement de tempo (ticks) MidiEvPtr e; t1 = 0.0; tt = 500000.0 / ticks; d1 = 0; e = First(s); while (e) { t2 = t1 + tt * (Date(e) - d1); if (EvType(e) == typeTempo) { tt = MidiGetField(e, 0) / ticks; d1 = Date(e); t1 = t2; } Date(e) = (long) (t2 / 1000.0); e = Link(e); } }
/* ------------------------------------------------------------------------- */ static char * DatasToText(MidiEvPtr e , char *buff) { char *ptr= buff; int i, max; *ptr= 0; switch (EvType(e)) { case typeTextual: case typeCopyright: case typeSeqName: case typeInstrName: case typeLyric: case typeMarker: case typeCuePoint: for( i=0, max= min(MidiCountFields(e), 18); i< max; i++) *ptr++= (char)MidiGetField(e, i); *ptr= 0; break; case typeSMPTEOffset: for( i=0; i< 6; i++, ptr+=3) sprintf( ptr, "%-2ld ", MidiGetField(e, i)); break; default: for( i=0, max= min(MidiCountFields(e), 5); i< max; i++, ptr+=4) sprintf( ptr, "%-3ld ", MidiGetField(e, i)); } return buff; }
//_________________________________________________________ static void SendSysEx(SlotPtr slot, MidiEvPtr e) { slot->remaining = (EvType(e) == typeSysEx) ? (MidiCountFields(e)+2) : MidiCountFields(e); // Write event to be sent MidiStreamPutEvent (&slot->outsysex, e); SendSysExAux(slot); }
void TExtEventReceiver::ReceiveEvents(MidiEvPtr e) { switch (EvType(e)) { case typeTempo: ReceiveTempo(e); break; } TEventReceiver::ReceiveEvents(e); }
static inline void LinearizeCommon (int i, MidiEvPtr e, Ev2UDPStreamPtr f) { f->data[i--] = EvType(e); LinearizeDate (i, e, f); i -= kDateSize; f->data[i--] = Port(e); f->data[i] = Chan(e); }
long DurSeq(MidiSeqPtr s) { long dur = 0; MidiEvPtr e = Last(s); if (e) { dur = Date(e); if (EvType(e) == typeNote) dur+=Dur(e); } return dur; }
//_____________________________________________________________________________ static MidiEvPtr rcvChan (UDPStreamPtr f, Byte c) { // UDPParseMethodPtr next = f->rcv[EvType(f->ptrCur)]; // MidiEvPtr e = 0; f->length--; Chan(f->ptrCur) = c; if (!f->length) return parseComplete (f); f->parse = f->rcv[EvType(f->ptrCur)]; f->next = 0; return 0; }
/*__________________________________________________________________________________*/ static MidiEvPtr NewSmallEv( lifo* fl, short typeNum) { MidiEvPtr ev = MSNewCell( fl); if( ev) { Link(ev)= 0; Date(ev)= defaultTime; EvType(ev)= (uchar)typeNum; RefNum(ev)= 0xff; Chan(ev) = Port(ev) = 0; ev->info.longField = 0; } return ev; }
//________________________________________________________________________________________ bool MS2MM(short refNum, SlotPtr slot, MidiEvPtr e) { int type = EvType(e); if ((type == typeSysEx) || (type == typeStream)) { MidiSetRcvAlarm(refNum,0); SendSysEx(slot,e); return false; }else{ SendSmallEv(slot,e,&slot->state); return true; } }
/* -------------------------------------------------------- Application receive alarm -------------------------------------------------------- */ void MSALARMAPI ReceiveEvents ( short r) { MidiEvPtr e; unsigned long d; while (e = MidiGetEv(r)) { d = Date(e) + MSParam[kDelay]; if ( (MSParam[kChan]!=0) && (MSParam[kChan]!=Chan(e)+1) ) MidiFreeEv(e); else if ( EvType(e) == typeNote ) { if( !MidiTask(EchoTask,d,r,(long)e,0,0)) MidiFreeEv(e); } else if ( Vel(e) > 0 ) { EvType(e) = typeNote; Dur(e) = 100; if( !MidiTask(EchoTask,d,r,(long)e,0,0)) MidiFreeEv(e); } else MidiFreeEv(e); } }
static void rcv_alarm (short refnum) { MidiEvPtr e = MidiGetEv (refnum); while (e) { switch (EvType(e)) { case typeStart: start(TRUE); break; case typeStop: stop(TRUE); break; case typeReset: reset(); break; } MidiFreeEv (e); e = MidiGetEv (refnum); } }
/* ------------------------------------------------------------------------- */ static char * EvToText ( MidiEvPtr e, char *buff) { unsigned long mn, sec; unsigned int h, ms; char sDatas[50]; sec = Date(e)/1000; ms = Date(e)%1000; mn = sec / 60; sec %= 60; h = mn / 60; mn %= 60; *buff= 0; sprintf (buff, "%02d:%02d:%02d:%03d %s %-3d %-2d %s", h, (int)mn, (int)sec, ms, TblLibEv[EvType(e)], (int)Port(e), (int)Chan(e), DatasToText(e, sDatas)); return buff; }
void transposeAndDelay (short aRefNum) { MidiEvPtr e; while (e = MidiGetEv(aRefNum)) { switch (EvType(e)) { case typeNote: case typeKeyOn: case typeKeyOff: MidiSetField(e, 0, 7 + MidiGetField(e,0)); // transpose pitch + 7 Date(e) += 1000; // delay 1000 ms MidiSend(aRefNum, e); break; default: MidiFreeEv(e); } } }
void MidiInputDeviceMidiShare::ReceiveEvents(short ref) { MidiInputDeviceMidiShare* driver = (MidiInputDeviceMidiShare*)MidiGetInfo(ref); MidiEvPtr ev; while ((ev = MidiGetEv(ref))) switch(EvType(ev)) { case typeCtrlChange: if (MidiGetField(ev,0) == 0) driver->DispatchBankSelectMsb(MidiGetField(ev,0),Chan(ev)); else if (MidiGetField(ev,0) == 32) driver->DispatchBankSelectLsb(MidiGetField(ev,0),Chan(ev)); else driver->DispatchControlChange(MidiGetField(ev,0),MidiGetField(ev,0),Chan(ev)); MidiFreeEv(ev); break; case typePitchWheel: driver->DispatchPitchbend(((MidiGetField(ev,0)+(MidiGetField(ev,1) << 7)) - 8192),Chan(ev)); MidiFreeEv(ev); break; case typeNote: driver->DispatchNoteOn(Pitch(ev),Vel(ev),Chan(ev)); MidiTask(KeyOffTask,Date(ev)+Dur(ev),ref,(long)ev,0,0); break; case typeKeyOn: if (Vel(ev) > 0) driver->DispatchNoteOn(Pitch(ev),Vel(ev),Chan(ev)); else driver->DispatchNoteOff(Pitch(ev),Vel(ev),Chan(ev)); MidiFreeEv(ev); break; case typeKeyOff: driver->DispatchNoteOff(Pitch(ev),Vel(ev),Chan(ev)); MidiFreeEv(ev); break; } }
/*__________________________________________________________________________________*/ static MidiEvPtr NewPrivateEv( lifo* fl, short typeNum) { MidiEvPtr ev = MSNewCell( fl); if( ev) { MidiSTPtr ext= (MidiSTPtr)MSNewCell(fl); if ( !ext) { MSFreeCell (ev, fl); return 0; } /* creates a clear extension block */ ext->val[0]= ext->val[1]= ext->val[2]= ext->val[3]= 0; Link(ev)= 0; /* initialize the header */ Date(ev)= defaultTime; EvType(ev)= (uchar)typeNum; RefNum(ev)= 0xff; Chan(ev) = Port(ev) = 0; LinkST(ev)= ext; /* link the extension block */ } return ev; }
void ChapterCWriter::notifyCommand ( MidiEvPtr command ) { /* CtrlChange */ if ( EvType ( command ) == typeCtrlChange ) { list<TCtrlInfo>::iterator i; for ( i = _history.begin ( ) ; i != _history.end ( ) ; i++ ) { if ( ( * i ).number == Data ( command ) [0] ) { TCtrlInfo ctrlInfo; ctrlInfo.number = ( * i ).number; if ( ( IsOn ( ( * i ).value ) && IsOff ( Data ( command ) [1] ) ) || ( IsOff ( ( * i ).value ) && IsOn ( Data ( command ) [1] ) ) ) { ctrlInfo.toggle = ( ( * i ).toggle + 1 ) % 64; } else { ctrlInfo.toggle = ( * i ).toggle; } ctrlInfo.value = Data ( command ) [1]; ctrlInfo.count = ( ( * i ).count + 1 ) % 64; ctrlInfo.payload = currentPayloadNumber ( ); _history.erase ( i ); _history.push_back ( ctrlInfo ); break; } } if ( i == _history.end ( ) ) { TCtrlInfo ctrlInfo; ctrlInfo.number = Data ( command ) [0]; ctrlInfo.value = Data ( command ) [1]; ctrlInfo.toggle = IsOn ( Data ( command ) [1] ); ctrlInfo.count = 1; ctrlInfo.payload = currentPayloadNumber ( ); _history.push_back ( ctrlInfo ); } } }
void ChapterAWriter::notifyResetCommand ( MidiEvPtr command, short resetType ) { /* Reset N-Active */ if ( resetType == RESET_STATE || resetType == RESET_N_ACTIVE ) { _history.clear ( ); } /* For X bit */ if ( EvType ( command ) == typeCtrlChange && ( ( short ) Data ( command ) [0] == 120 || ( short ) Data ( command ) [0] == 123 || ( short ) Data ( command ) [0] == 124 || ( short ) Data ( command ) [0] == 125 || ( short ) Data ( command ) [0] == 126 || ( short ) Data ( command ) [0] == 127 ) ) { for ( list<TNotePressInfo>::iterator i = _history.begin ( ) ; i != _history.end ( ) ; i++ ) { ( * i ).x = 1; } } }
void ChapterAWriter::notifyCommand ( MidiEvPtr command ) { /* KeyPress */ if ( EvType ( command ) == typeKeyPress ) { for ( list<TNotePressInfo>::iterator i = _history.begin ( ) ; i != _history.end ( ) ; i++ ) { if ( ( * i ).pitch == Pitch ( command ) ) { _history.erase ( i ); break; } } TNotePressInfo newNotePress; newNotePress.pitch = Pitch ( command ); newNotePress.press = Vel ( command ); newNotePress.x = 0; newNotePress.payload = currentPayloadNumber ( ); _history.push_back ( newNotePress ); } }
/*=========================================================================== external functions implementation =========================================================================== */ MidiEvPtr UDPStreamPutEvent (Ev2UDPStreamPtr f, MidiEvPtr e) { if (f->count) return e; (f->lin[EvType(e)]) (e, f); return 0; }
short MIDISHAREAPI MidiGetType (MidiEvPtr e) { return EvType(e); }
MSFunctionType(void) MSAddField (MidiEvPtr e, long v, lifo* freelist) { if ( e) AddFieldMethodTbl[EvType(e)](freelist, e, v); }
MSFunctionType(long) MSCountFields (MidiEvPtr e) { return e ? CountFieldsMethodTbl[EvType(e)](e) : kCountFieldsError; }
MSFunctionType(long) MSGetField (MidiEvPtr e, long f) { return e ? GetFieldMethodTbl[EvType(e)]( e, f) : kGetFieldError; }
MSFunctionType(void) MSSetField (MidiEvPtr e, unsigned long f, long v) { if( e) SetFieldMethodTbl[EvType(e)]( e, f, v); }
MSFunctionType(MidiEvPtr) MSCopyEv (MidiEvPtr e, lifo* freelist) { return e ? CopyEvMethodTbl[EvType(e)]( freelist, e) : e; }
MSFunctionType(void) MSFreeEv (MidiEvPtr e, lifo* freelist) { if( e) FreeEvMethodTbl[EvType(e)]( freelist, e); }
void MIDISHAREAPI MidiSetType (MidiEvPtr e, short t) { EvType(e) = (Byte)t; }
/* * fluid_midishare_midi_driver_receive */ static void fluid_midishare_midi_driver_receive(short ref) { fluid_midishare_midi_driver_t* dev = (fluid_midishare_midi_driver_t*)MidiGetInfo(ref); fluid_midi_event_t new_event; MidiEvPtr e; int count, i; while ((e = MidiGetEv (ref))) { switch (EvType (e)) { case typeNote: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, NOTE_ON); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_pitch(&new_event, Pitch(e)); fluid_midi_event_set_velocity(&new_event, Vel(e)); /* and send it on its way to the router */ (*dev->driver.handler)(dev->driver.data, &new_event); #if defined(MACINTOSH) && defined(MACOS9) MidiTask(dev->upp_task_ptr, MidiGetTime()+Dur(e), ref, (long)e, 0, 0); #else MidiTask(fluid_midishare_keyoff_task, MidiGetTime()+Dur(e), ref, (long)e, 0, 0); #endif /* e gets freed in fluid_midishare_keyoff_task */ continue; case typeKeyOn: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, NOTE_ON); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_pitch(&new_event, Pitch(e)); fluid_midi_event_set_velocity(&new_event, Vel(e)); break; case typeKeyOff: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, NOTE_OFF); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_pitch(&new_event, Pitch(e)); fluid_midi_event_set_velocity(&new_event, Vel(e)); /* release vel */ break; case typeCtrlChange: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, CONTROL_CHANGE); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_control(&new_event, MidiGetField(e,0)); fluid_midi_event_set_value(&new_event, MidiGetField(e,1)); break; case typeProgChange: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, PROGRAM_CHANGE); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_program(&new_event, MidiGetField(e,0)); break; case typePitchWheel: /* Copy the data to fluid_midi_event_t */ fluid_midi_event_set_type(&new_event, PITCH_BEND); fluid_midi_event_set_channel(&new_event, Chan(e)); fluid_midi_event_set_value(&new_event, ((MidiGetField(e,0) + (MidiGetField(e,1) << 7)) - 8192)); break; case typeSysEx: count = MidiCountFields (e); /* Discard empty or too large SYSEX messages */ if (count == 0 || count > FLUID_MIDI_PARSER_MAX_DATA_SIZE) { MidiFreeEv (e); continue; } /* Copy SYSEX data, one byte at a time */ for (i = 0; i < count; i++) dev->sysexbuf[i] = MidiGetField (e, i); fluid_midi_event_set_sysex (&new_event, dev->sysexbuf, count, FALSE); break; default: MidiFreeEv (e); continue; } MidiFreeEv (e); /* Send the MIDI event */ (*dev->driver.handler)(dev->driver.data, &new_event); } }
/*---------------------------------------------------*/ void STS_WriteScore (long s, ScorePtr sp) { MidiEvPtr e = 0; float p2, p3; long param; int ref, chan, type; FILE *f; char scoreline[1024]; char str[25]; char str2[25]; if((f = fopen(sp->scorefile, "wt")) != NULL){ if(sp->addinfile != "NULL") STS_AppendToScoreFile(sp->addinfile, f); e = FirstEv(s); if(e){ while(e){ type = EvType(e); if(!sp->events[type]){e = Link(e); continue;} if(sp->ab == abTrack){ ref = RefNum(e); if(sp->shiftref) ref += 1; if(!sp->trkchn[ref]){e = Link(e); continue;} else sprintf(scoreline, "i%u \t", ref); } if(sp->ab == abChan){ chan = Chan(e); if(!sp->trkchn[chan]){e = Link(e); continue;} else sprintf(scoreline, "i%u \t", chan + 1); } p2 = (float)Date(e) / 1000.; sprintf(str, "%.3f \t", p2); strcat(scoreline, str); switch(type){ case typeNote: p3 = (float)MidiGetField(e, 2) / 1000.; sprintf(str, "%.3f \t", p3); strcat(scoreline, str); STS_ConvertPitch(sp, str, MidiGetField(e, 0)); STS_ConvertAmpli(sp, str2, MidiGetField(e, 1)); STS_OrderParams(sp, scoreline, str, str2); break; case typeKeyPress: sprintf(str, "%.3f \t", sp->defdur / 1000.); strcat(scoreline, str); STS_ConvertPitch(sp, str, MidiGetField(e, 0)); STS_ConvertAmpli(sp, str2, MidiGetField(e, 1)); STS_OrderParams(sp, scoreline, str, str2); break; case typeCtrlChange: case typeCtrl14b: case typeNonRegParam: case typeRegParam: sprintf(str, "%.3f \t", sp->defdur / 1000.); strcat(scoreline, str); sprintf(str, "%03u \t", MidiGetField(e, 0)); strcat(scoreline, str); sprintf(str, "%03u \t", MidiGetField(e, 1)); strcat(scoreline, str); break; case typeProgChange: case typeChanPress: sprintf(str, "%.3f \t", sp->defdur / 1000.); strcat(scoreline, str); sprintf(str, "%03u \t", MidiGetField(e, 0)); strcat(scoreline, str); break; case typePitchWheel: sprintf(str, "%.3f \t", sp->defdur / 1000.); strcat(scoreline, str); param = STS_Build14BitValue((long)e) - 8192; sprintf(str, "%03li \t", param); strcat(scoreline, str); break; default: if(type >= typePrivate && type <= typeLastPrivate){ sprintf(str, "%.3f \t", sp->defdur / 1000.); strcat(scoreline, str); sp->CFunc(sp, str, (long)e); strcat(scoreline, str); } break; } strcat(scoreline, "\n"); fputs(scoreline, f); e = Link(e); } } if(sp->writesection){ if(sp->padout > 0.){ sprintf(str, "f0 %.3f\n", sp->padout / 1000.); fputs(str, f); } fputs("s", f); } else fputs("e", f); fclose(f); } }