void Arponaut::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames) { // Mutex is already locked for us. ENoteLength noteLength = (ENoteLength) ((int(GetParam(kNoteLength)->Value())) + 1); EOctaves octaves = (EOctaves) ((int(GetParam(kOctaves)->Value())) + 1); EArpMode arpMode = (EArpMode) (int(GetParam(kArpMode)->Value())); EInsertMode insertMode = (EInsertMode) (int(GetParam(kInsertMode)->Value())); if (GetGUI()) { //GetGUI()->SetControlFromPlug(mMeterIdx_L, peakL); //GetGUI()->SetControlFromPlug(mMeterIdx_R, peakR); } int pos = GetSamplePos(); running_ = (pos != lastPos_); int tnum, tden; GetTimeSig(&tnum, &tden); if (keymap_.held() == 0) { NoteOff(); // only sent if a note is already playing } if (running_ && keymap_.held()) { sequence_->setOctaves(octaves); sequence_->setArpMode(arpMode); sequence_->setInsertMode(insertMode); double perBeat = GetSamplesPerBeat() / noteLength; // trigger? int ibar = static_cast<int>(double(pos) / perBeat); int ilastBar = static_cast<int>(double(lastPos_) / perBeat); if ((pos == 0 && ibar == 0) || (ibar != ilastBar)) { // Log("pos %d pb %f Num %d Den %d ibar %d lastbar %d\n", pos, perBeat, tnum, tden, ibar, ilastBar); NoteOff(); IMidiMsg* next = sequence_->next(); if (next && next->StatusMsg() == IMidiMsg::kNoteOn) { SendMidiMsg(next); playing_ = *next; } matrix->SetDirty(false); } } lastPos_ = pos; }
void Fl_MIDIKeyboard::release_key(uchar k) { if (pressed_keys[k]) { NoteOff(k); pressed_keys[k] = false; _npressed--; if (_npressed) { if (k == _maxpressed) { do k--; while (!pressed_keys[k]); _maxpressed = k; } else if (k == _minpressed) { do k++; while (!pressed_keys[k]); _minpressed = k; } } redraw(); if (when() & MKB_WHEN_RELEASE) { _callback_status = MKB_RELEASE | k; do_callback(); } //cout << "Released " << (char)k << " npressed = " << (int)_npressed << endl; } }
void TrashMIDI(void) { long Length; int J; /* If not logging, drop out */ if(!MIDIOut) return; /* Turn sound off */ for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J); /* End of track */ MIDIMessage(0xFF,0x2F,0x00); /* Put track length in file */ fseek(MIDIOut,0,SEEK_END); Length=ftell(MIDIOut)-22; fseek(MIDIOut,18,SEEK_SET); fputc((Length>>24)&0xFF,MIDIOut); fputc((Length>>16)&0xFF,MIDIOut); fputc((Length>>8)&0xFF,MIDIOut); fputc(Length&0xFF,MIDIOut); /* Done logging */ fclose(MIDIOut); Logging = MIDI_OFF; LastMsg = -1; TickCount = 0; MIDIOut = 0; }
void OCPiano::PressKey(const int Pitch, const bool Poly, const bool Tied) { emit NoteOn(Pitch); int NoteType=tsnote; if (Tied) NoteType=tstiednote; if (Poly) { Types.append(NoteType+2); Pitches.append(Pitch); CurrentPitch=0; } else { Types.append(NoteType); Pitches.append(Pitch); CurrentPitch=Pitch; QList<QPair<int,int> >Notes; for (int i=0;i<Pitches.count();i++) { Notes.append(qMakePair(Pitches[i],Types[i])); } emit TriggerNotes(Notes); for (int i=0;i<Pitches.count()-1;i++) { emit NoteOff(Pitches[i]); } Pitches.clear(); Types.clear(); } }
LRESULT CMainDlg::OnSave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { char fileName[MAX_PATH]; memset(fileName, 0, sizeof(fileName)); OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hWnd; ofn.lpstrFilter = "Sound Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0"; ofn.nFilterIndex = 1; ofn.lpstrFile = fileName; ofn.lpstrDefExt = ".wav"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_OVERWRITEPROMPT; if (GetSaveFileName (&ofn)) { WaveFile wvf; wvf.OpenWaveFile(fileName, 2); InitGen(); long totalSamples = (long) ((durTotal * synthParams.sampleRate) + 0.5); long atkSamples = (long) (durAtkSus * synthParams.sampleRate); long n; for (n = 0; n < atkSamples; n++) wvf.Output1(Generate()); NoteOff(); while (n++ < totalSamples) wvf.Output1(Generate()); for (n = 0; n < 440; n++) wvf.Output1(0); wvf.CloseWaveFile(); } return 0; }
void PedalReleased() { if(waitingForPedalRelease) { NoteOff(); waitingForPedalRelease=false; } }
void OCPiano::mouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); if (CurrentPitch>0) { emit NoteOff(CurrentPitch); CurrentPitch=0; } Paint(); }
bool Ims::Reset(void) { if (m_ims == NULL) return false; // YM3812ResetChip(ym3812p); ResetChip(); SndOutput(1, 0x20); // Enable waveform select (bit 5) SetMode(m_ims->header.nSoundMode); for (int i=0; i<MAX_VOICE; i++) { NoteOff(i); SetVoiceVolume(i, 0); } Rewind(); return true; }
void BMidiLocalConsumer::Data(uchar* data, size_t length, bool atomic, bigtime_t time) { if (atomic) { switch (data[0] & 0xF0) { case B_NOTE_OFF: { if (length == 3) NoteOff(data[0] & 0x0F, data[1], data[2], time); break; } case B_NOTE_ON: { if (length == 3) NoteOn(data[0] & 0x0F, data[1], data[2], time); break; } case B_KEY_PRESSURE: { if (length == 3) KeyPressure(data[0] & 0x0F, data[1], data[2], time); break; } case B_CONTROL_CHANGE: { if (length == 3) ControlChange(data[0] & 0x0F, data[1], data[2], time); break; } case B_PROGRAM_CHANGE: { if (length == 2) ProgramChange(data[0] & 0x0F, data[1], time); break; } case B_CHANNEL_PRESSURE: { if (length == 2) ChannelPressure(data[0] & 0x0F, data[1], time); break; } case B_PITCH_BEND: { if (length == 3) PitchBend(data[0] & 0x0F, data[1], data[2], time); break; } case 0xF0: { switch (data[0]) { case B_SYS_EX_START: { if (data[length - 1] == B_SYS_EX_END) { SystemExclusive(data + 1, length - 2, time); } else { // sysex-end is not required SystemExclusive(data + 1, length - 1, time); } break; } case B_TUNE_REQUEST: case B_SYS_EX_END: { if (length == 1) { SystemCommon(data[0], 0, 0, time); } break; } case B_CABLE_MESSAGE: case B_MIDI_TIME_CODE: case B_SONG_SELECT: { if (length == 2) { SystemCommon(data[0], data[1], 0, time); } break; } case B_SONG_POSITION: { if (length == 3) { SystemCommon(data[0], data[1], data[2], time); } break; } case B_TIMING_CLOCK: case B_START: case B_CONTINUE: case B_STOP: case B_ACTIVE_SENSING: { if (length == 1) { SystemRealTime(data[0], time); } break; } case B_SYSTEM_RESET: { if (length == 1) { SystemRealTime(data[0], time); } else if ((length == 6) && (data[1] == 0x51) && (data[2] == 0x03)) { int32 tempo = (data[3] << 16) | (data[4] << 8) | data[5]; TempoChange(60000000/tempo, time); } } } break; } } } }
void __cdecl main(int argc, char **argv) { HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); int running = 1; #ifdef WIN32 if (IsDebuggerPresent()) { // turn on floating-point exceptions unsigned int prev; _clearfp(); _controlfp_s(&prev, 0, _EM_ZERODIVIDE|_EM_INVALID); } #endif // check the correct BASS was loaded if (HIWORD(BASS_GetVersion()) != BASSVERSION) { fprintf(stderr, "An incorrect version of BASS.DLL was loaded"); return; } // set the window title SetConsoleTitle(TEXT(title_text)); // set the console buffer size static const COORD bufferSize = { 80, 50 }; SetConsoleScreenBufferSize(hOut, bufferSize); // set the console window size static const SMALL_RECT windowSize = { 0, 0, 79, 49 }; SetConsoleWindowInfo(hOut, TRUE, &windowSize); // clear the window Clear(hOut); // hide the cursor static const CONSOLE_CURSOR_INFO cursorInfo = { 100, FALSE }; SetConsoleCursorInfo(hOut, &cursorInfo); // set input mode SetConsoleMode(hIn, 0); // 10ms update period const DWORD STREAM_UPDATE_PERIOD = 10; BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, STREAM_UPDATE_PERIOD); // initialize BASS sound library const DWORD STREAM_FREQUENCY = 48000; if (!BASS_Init(-1, STREAM_FREQUENCY, BASS_DEVICE_LATENCY, 0, NULL)) Error("Can't initialize device"); // get device info BASS_GetInfo(&info); // if the device's output rate is unknown default to stream frequency if (!info.freq) info.freq = STREAM_FREQUENCY; // debug print info DebugPrint("frequency: %d (min %d, max %d)\n", info.freq, info.minrate, info.maxrate); DebugPrint("device latency: %dms\n", info.latency); DebugPrint("device minbuf: %dms\n", info.minbuf); DebugPrint("ds version: %d (effects %s)\n", info.dsver, info.dsver < 8 ? "disabled" : "enabled"); // default buffer size = update period + 'minbuf' + 1ms extra margin BASS_SetConfig(BASS_CONFIG_BUFFER, STREAM_UPDATE_PERIOD + info.minbuf + 1); DebugPrint("using a %dms buffer\r", BASS_GetConfig(BASS_CONFIG_BUFFER)); // create a stream, stereo so that effects sound nice stream = BASS_StreamCreate(info.freq, 2, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream, 0); // set channel to apply effects fx_channel = stream; #ifdef BANDLIMITED_SAWTOOTH // initialize bandlimited sawtooth tables InitSawtooth(); #endif // initialize waves InitWave(); // enable the first oscillator osc_config[0].enable = true; // reset all controllers Control::ResetAll(); // start playing the audio stream BASS_ChannelPlay(stream, FALSE); // get the number of midi devices UINT midiInDevs = Midi::Input::GetNumDevices(); DebugPrint("MIDI input devices: %d\n", midiInDevs); // print device names for (UINT i = 0; i < midiInDevs; ++i) { MIDIINCAPS midiInCaps; if (Midi::Input::GetDeviceCaps(i, midiInCaps) == 0) { DebugPrint("%d: %s\n", i, midiInCaps.szPname); } } // if there are any devices available... if (midiInDevs > 0) { // open and start midi input // TO DO: select device number via a configuration setting Midi::Input::Open(0); Midi::Input::Start(); } // initialize to middle c note_most_recent = 60; voice_note[voice_most_recent] = unsigned char(note_most_recent); DisplaySpectrumAnalyzer displaySpectrumAnalyzer; DisplayKeyVolumeEnvelope displayKeyVolumeEnvelope; DisplayOscillatorWaveform displayOscillatorWaveform; DisplayOscillatorFrequency displayOscillatorFrequency; DisplayLowFrequencyOscillator displayLowFrequencyOscillator; DisplayFilterFrequency displayFilterFrequency; // initialize spectrum analyzer displaySpectrumAnalyzer.Init(stream, info); // initialize key display displayKeyVolumeEnvelope.Init(hOut); // show output scale and key octave PrintOutputScale(hOut); PrintKeyOctave(hOut); PrintGoToEffects(hOut); PrintAntialias(hOut); // show main page Menu::SetActivePage(hOut, Menu::PAGE_MAIN); while (running) { // if there are any pending input events... DWORD numEvents = 0; while (GetNumberOfConsoleInputEvents(hIn, &numEvents) && numEvents > 0) { // get the next input event INPUT_RECORD keyin; ReadConsoleInput(hIn, &keyin, 1, &numEvents); if (keyin.EventType == KEY_EVENT) { // handle interface keys if (keyin.Event.KeyEvent.bKeyDown) { WORD code = keyin.Event.KeyEvent.wVirtualKeyCode; DWORD modifiers = keyin.Event.KeyEvent.dwControlKeyState; if (code == VK_ESCAPE) { running = 0; break; } else if (code == VK_OEM_MINUS || code == VK_SUBTRACT) { Menu::UpdatePercentageProperty(output_scale, -1, modifiers, 0, 4); PrintOutputScale(hOut); } else if (code == VK_OEM_PLUS || code == VK_ADD) { Menu::UpdatePercentageProperty(output_scale, +1, modifiers, 0, 4); PrintOutputScale(hOut); } else if (code == VK_OEM_4) // '[' { if (keyboard_octave > 1) { for (int k = 0; k < KEYS; ++k) { if (key_down[k]) NoteOff(k + keyboard_octave * 12); } --keyboard_octave; for (int k = 0; k < KEYS; ++k) { if (key_down[k]) NoteOn(k + keyboard_octave * 12); } PrintKeyOctave(hOut); } } else if (code == VK_OEM_6) // ']' { if (keyboard_octave < 9) { for (int k = 0; k < KEYS; ++k) { if (key_down[k]) NoteOff(k + keyboard_octave * 12); } ++keyboard_octave; for (int k = 0; k < KEYS; ++k) { if (key_down[k]) NoteOn(k + keyboard_octave * 12); } PrintKeyOctave(hOut); } } else if (code == VK_F12) { use_antialias = !use_antialias; PrintAntialias(hOut); } else if (code >= VK_F1 && code < VK_F10) { Menu::SetActiveMenu(hOut, code - VK_F1); } else if (code == VK_F10) { PrintGoToEffects(hOut); Menu::SetActivePage(hOut, Menu::PAGE_MAIN); } else if (code == VK_F11) { PrintGoToMain(hOut); Menu::SetActivePage(hOut, Menu::PAGE_FX); } else if (code == VK_TAB) { if (modifiers & SHIFT_PRESSED) Menu::PrevMenu(hOut); else Menu::NextMenu(hOut); } else if (code == VK_UP || code == VK_DOWN || code == VK_RIGHT || code == VK_LEFT) { Menu::Handler(hOut, code, modifiers); } } // handle note keys for (int k = 0; k < KEYS; k++) { if (keyin.Event.KeyEvent.wVirtualKeyCode == keys[k]) { // key down bool down = (keyin.Event.KeyEvent.bKeyDown != 0); // if key down state changed... if (key_down[k] != down) { // update state key_down[k] = down; // if pressing the key if (down) { // note on NoteOn(k + keyboard_octave * 12); } else { // note off NoteOff(k + keyboard_octave * 12); } } break; } } } } // center frequency of the zeroth semitone band // (one octave down from the lowest key) float const freq_min = powf(2, float(keyboard_octave - 6)) * middle_c_frequency; // update the spectrum analyzer display displaySpectrumAnalyzer.Update(hOut, stream, info, freq_min); // update note key volume envelope display displayKeyVolumeEnvelope.Update(hOut); if (Menu::active_page == Menu::PAGE_MAIN) { // update the oscillator waveform display displayOscillatorWaveform.Update(hOut, info, voice_most_recent); // update the oscillator frequency displays for (int o = 0; o < NUM_OSCILLATORS; ++o) { if (osc_config[o].enable) displayOscillatorFrequency.Update(hOut, voice_most_recent, o); } // update the low-frequency oscillator display displayLowFrequencyOscillator.Update(hOut); // update the filter frequency display if (flt_config.enable) displayFilterFrequency.Update(hOut, voice_most_recent); } // show CPU usage PrintConsole(hOut, { 73, 49 }, "%6.2f%%", BASS_GetCPU()); // sleep for 1/60th of second Sleep(16); } if (midiInDevs) { // stop and close midi input Midi::Input::Stop(); Midi::Input::Close(); } // clean up spectrum analyzer displaySpectrumAnalyzer.Cleanup(stream); // clear the window Clear(hOut); BASS_Free(); }
int MIDILogging(int Switch) { static const char MThd[] = "MThd\0\0\0\006\0\0\0\1"; /* ID DataLen Fmt Trks */ static const char MTrk[] = "MTrk\0\0\0\0"; /* ID TrkLen */ int J,I; /* Toggle logging if requested */ if(Switch==MIDI_TOGGLE) Switch=!Logging; if((Switch==MIDI_ON)||(Switch==MIDI_OFF)) if(Switch^Logging) { /* When turning logging off, silence all channels */ if(!Switch&&MIDIOut) for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J); /* When turning logging on, open MIDI file */ if(Switch&&!MIDIOut&&LogName) { /* No messages have been sent yet */ LastMsg=-1; /* Clear all storage */ for(J=0;J<MIDI_CHANNELS;J++) MidiCH[J].Note=MidiCH[J].Pitch=MidiCH[J].Level=-1; /* Open new file and write out the header */ MIDIOut=fopen(LogName,"wb"); if(!MIDIOut) return(MIDI_OFF); if(fwrite(MThd,1,12,MIDIOut)!=12) { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); } fputc((MIDI_DIVISIONS>>8)&0xFF,MIDIOut); fputc(MIDI_DIVISIONS&0xFF,MIDIOut); if(fwrite(MTrk,1,8,MIDIOut)!=8) { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); } /* Write out the tempo */ WriteTempo(MIDI_DIVISIONS); } /* Turn logging off on failure to open MIDIOut */ if(!MIDIOut) Switch=MIDI_OFF; /* Assign new switch value */ Logging=Switch; /* If switching logging on... */ if(Switch) { /* Start logging without a pause */ TickCount=0; /* Write instrument changes */ for(J=0;J<MIDI_CHANNELS;J++) if((MidiCH[J].Type>=0)&&(MidiCH[J].Type&0x10000)) { I=MidiCH[J].Type&~0x10000; MidiCH[J].Type=-1; MIDISetSound(J,I); } } }
int Ims::PlayEvent(void) { static unsigned char stCode; unsigned char curCode; int delay, delayTime = 0; int voice, note, volume, index; int *paramArray; unsigned short int pitchBend; int instIndexInBnk; again: curCode = m_ims->songData[m_songDataIndex]; //fflush(stdout); //return (nElapsed * MAX_SLIDER_PROGRESS / m_cbImsDataSize); // 0x7F == 127 if (curCode > 0x7F) { m_songDataIndex++; stCode = curCode; } else curCode = stCode; voice = curCode & 0x0F; // 오른쪽 4비트를 얻는다 (채널 번호) // 왼쪽 4비트에 이벤트 종류가 저장되어 있다 switch (curCode & 0xF0) { case 0x80: // note off note = m_ims->songData[m_songDataIndex]; volume = m_ims->songData[m_songDataIndex + 1]; NoteOff(voice); SetVoiceVolume(voice, volume); NoteOn(voice, note); m_songDataIndex += 2; break; case 0x90: // note on note = m_ims->songData[m_songDataIndex]; volume = m_ims->songData[m_songDataIndex + 1]; NoteOff(voice); if (volume) { SetVoiceVolume(voice, volume); NoteOn(voice, note); } m_songDataIndex += 2; break; case 0xA0: // Set volume volume = m_ims->songData[m_songDataIndex]; SetVoiceVolume(voice, volume); m_songDataIndex++; break; case 0xC0: // Set Instrument index = m_ims->songData[m_songDataIndex]; instIndexInBnk = m_ims->instIndex[index].index; // 악기가 있다면.. if ( instIndexInBnk >= 0 && instIndexInBnk < m_ims->m_bnk->header.totalEntry) { paramArray = &m_ims->m_bnk->instRecord32[instIndexInBnk].op1.keyScaleLevel; SetVoiceTimbre(voice, paramArray); } else { /* printf("%d/%d\n", instIndexInBnk, m_ims->m_bnk->header.totalEntry); fflush(stdout); */ } m_songDataIndex++; break; case 0xE0: // Set Pitch memcpy(&pitchBend, &m_ims->songData[m_songDataIndex], sizeof(unsigned short int)); pitchBend = pitchBend / 2; SetVoicePitch(voice, pitchBend); m_songDataIndex += sizeof(unsigned short int); break; case 0xF0: // Set Tempo m_songDataIndex += 2; m_basicTempo = (m_ims->header.nBasicTempo * m_ims->songData[m_songDataIndex]); m_basicTempo += m_ims->header.nBasicTempo * m_ims->songData[m_songDataIndex + 1] / 128; m_songDataIndex += 3; break; } while (1) { delay = m_ims->songData[m_songDataIndex]; m_songDataIndex++; // IMS finish code if (m_ims->songData[m_songDataIndex] == 0xFC) { if ( m_repeatMode == REPEAT_THIS ) { Rewind(); } else { m_playMode=SONG_END; break; } delayTime += delay; return delayTime; } if (delay == 0xF8) delayTime += 240; else break; } delayTime += delay; if (delayTime == 0) goto again; else m_tick += delayTime; return delayTime; }
//-------------------------------------------------------------- void testApp::keyReleased(int key) { switch(key) { // send pgm change on arrow keys case OF_KEY_UP: currentPgm = (int) ofClamp(currentPgm+1, 0, 127); midiOut.sendProgramChange(synthChan, currentPgm); break; case OF_KEY_DOWN: currentPgm = (int) ofClamp(currentPgm-1, 0, 127); midiOut << ProgramChange(synthChan, currentPgm); // stream interface break; case OF_KEY_LEFT: currentPgm = (int) ofClamp(currentPgm+1, 0, 127); midiOut.sendProgramChange(effectsChan, currentPgm); break; case OF_KEY_RIGHT: currentPgm = (int) ofClamp(currentPgm-1, 0, 127); midiOut << ProgramChange(effectsChan, currentPgm); // stream interface break; // aftertouch case '[': touch = 64; midiOut.sendAftertouch(channel, touch); break; case ']': touch = 127; midiOut << Aftertouch(channel, touch); // stream interface break; // poly aftertouch case '<': polytouch = 64; midiOut.sendPolyAftertouch(channel, 64, polytouch); break; case '>': polytouch = 127; midiOut << PolyAftertouch(channel, 64, polytouch); // stream interface break; // sysex using raw bytes (use shift + s) case 'S': { // send a pitch change to Part 1 of a MULTI on an Akai sampler // from http://troywoodfield.tripod.com/sysex.html // // do you have an S2000 to try? // // note: this is probably not as efficient as the next two methods // since it sends only one byte at a time, instead of all // at once // midiOut.sendMidiByte(MIDI_SYSEX); midiOut.sendMidiByte(0x47); // akai manufacturer code midiOut.sendMidiByte(0x00); // channel 0 midiOut.sendMidiByte(0x42); // MULTI midiOut.sendMidiByte(0x48); // using an Akai S2000 midiOut.sendMidiByte(0x00); // Part 1 midiOut.sendMidiByte(0x00); // transpose midiOut.sendMidiByte(0x01); // Access Multi Parts midiOut.sendMidiByte(0x4B); // offset midiOut.sendMidiByte(0x00); // offset midiOut.sendMidiByte(0x01); // Field size = 1 midiOut.sendMidiByte(0x00); // Field size = 1 midiOut.sendMidiByte(0x04); // pitch value = 4 midiOut.sendMidiByte(0x00); // offset midiOut.sendMidiByte(MIDI_SYSEX_END); // send again using a vector // // sends all bytes within one message // vector<unsigned char> sysexMsg; sysexMsg.push_back(MIDI_SYSEX); sysexMsg.push_back(0x47); sysexMsg.push_back(0x00); sysexMsg.push_back(0x42); sysexMsg.push_back(0x48); sysexMsg.push_back(0x00); sysexMsg.push_back(0x00); sysexMsg.push_back(0x01); sysexMsg.push_back(0x4B); sysexMsg.push_back(0x00); sysexMsg.push_back(0x01); sysexMsg.push_back(0x00); sysexMsg.push_back(0x04); sysexMsg.push_back(0x00); sysexMsg.push_back(MIDI_SYSEX_END); midiOut.sendMidiBytes(sysexMsg); // send again with the byte stream interface // // builds the message, then sends it on FinishMidi() // midiOut << StartMidi() << MIDI_SYSEX << 0x47 << 0x00 << 0x42 << 0x48 << 0x00 << 0x00 << 0x01 << 0x4B << 0x00 << 0x01 << 0x00 << 0x04 << 0x00 << MIDI_SYSEX_END << FinishMidi(); break; } // print the port list case '?': midiOut.listPorts(); break; // note off using raw bytes case ' ': // send with the byte stream interface, noteoff for note 60 midiOut << StartMidi() << 0x80 << 0x3C << 0x40 << FinishMidi(); break; default: // send a note off if the key is a letter or a number if(isalnum(key)) { note = ofMap(key, 48, 122, 0, 127); velocity = 0; midiOut << NoteOff(channel, note, velocity); // stream interface } break; } }
int CMainDlg::PlayFM(int loop) { WAVEFORMATEX wf; wf.wFormatTag = WAVE_FORMAT_PCM; wf.nChannels = 1; wf.nSamplesPerSec = synthParams.isampleRate; wf.nAvgBytesPerSec = wf.nSamplesPerSec * 2; wf.nBlockAlign = 2; wf.wBitsPerSample = 16; wf.cbSize = 0; StopPlaying(); InitGen(); DWORD atkSusSamples = (DWORD) (durAtkSus * synthParams.sampleRate); DWORD totalSamples = (DWORD) (durTotal * synthParams.sampleRate); // add room for silence at end to minimize "click" when player turns off. DWORD bufSize = totalSamples + (DWORD) (0.1 * synthParams.sampleRate); SampleValue *samples; #ifdef USE_DIRECTSOUND HRESULT hr; if (dirSndObj == NULL) { hr = DirectSoundCreate(NULL, &dirSndObj, NULL); if (hr == S_OK) { hr = dirSndObj->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL); if (hr != S_OK) { dirSndObj->Release(); dirSndObj = NULL; MessageBox("Cannot open direct sound output", "Error", MB_OK|MB_ICONSTOP); return -1; } } } void *pAudio1 = NULL; void *pAudio2 = NULL; DWORD dwAudio1 = 0; DWORD dwAudio2 = 0; DSBUFFERDESC dsbd; dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = 0; dsbd.dwBufferBytes = bufSize * 2; dsbd.dwReserved = 0; dsbd.lpwfxFormat = &wf; hr = dirSndObj->CreateSoundBuffer(&dsbd, &dirSndBuf, NULL); if (hr != S_OK) return -1; hr = dirSndBuf->Lock(0, bufSize, &pAudio1, &dwAudio1, NULL, NULL, DSBLOCK_ENTIREBUFFER); if (hr != S_OK) { MessageBox("Cannot create direct sound buffer", "Error", MB_OK|MB_ICONSTOP); return -1; } samples = (SampleValue *) pAudio1; #else MMRESULT res; if (woHandle == NULL) { res = waveOutOpen(&woHandle, WAVE_MAPPER, &wf, (DWORD) m_hWnd, 0, CALLBACK_WINDOW); if (res != MMSYSERR_NOERROR) { MessageBox("Cannot open wave output", "Error", MB_OK|MB_ICONSTOP); return -1; } } memset(&wh, 0, sizeof(wh)); wh.dwBufferLength = bufSize * sizeof(SampleValue); wh.lpData = (LPSTR) malloc(wh.dwBufferLength); if (wh.lpData == NULL) { MessageBox("Cannot create wave out buffer", "Error", MB_OK|MB_ICONSTOP); return -1; } res = waveOutPrepareHeader(woHandle, &wh, sizeof(wh)); samples = (SampleValue *) wh.lpData; #endif DWORD n = 0; while (n++ < atkSusSamples) *samples++ = (SampleValue) (Generate() * synthParams.sampleScale); NoteOff(); while (!gen1EG.IsFinished() && n++ < bufSize) *samples++ = (SampleValue) (Generate() * synthParams.sampleScale); while (n++ < bufSize) *samples++ = 0; #ifdef USE_DIRECTSOUND dirSndBuf->Unlock(pAudio1, dwAudio1, pAudio2, dwAudio2); dirSndBuf->Play(0, 0, loop ? DSBPLAY_LOOPING : 0); if (!loop) idTimer = SetTimer(1, (UINT) (durTotal * 1000.0) + 500); #else if (loop) { wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP; wh.dwLoops = 100; } waveOutWrite(woHandle, &wh, sizeof(wh)); #endif return 0; }