//************************************************************************ BOOL OptionsSceneInit (HWND hWnd, HWND hWndControl, LPARAM lParam) //************************************************************************ { StartMidi( NO ); StartWave( NO ); // Init. the midi and wave volume slider positions // Volume range of each channel -> 0x0000 to 0xffff, right channel volume is // in the high word, left channel is in the low word, if high word is zero, // the device is mono, so we'll just use the left value and assume they're the same // Midi volume DWORD dwVol = MCIGetVolume ((LPSTR)MCI_DEVTYPE_SEQUENCER); WORD wLeft = LOWORD(dwVol); wLeft &= 32767; // for some reason, the 32K bit is always on (in Win95) long lPosition = (100L * wLeft) / 32767L; SendDlgItemMessage( hWnd, IDC_SLIDER_MIDIVOL, SM_SETPOSITION, 0, lPosition ); // Wave volume dwVol = MCIGetVolume ((LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO); wLeft = LOWORD(dwVol); wLeft &= 32767; // for some reason, the 32K bit is always on (in Win95) lPosition = (100L * wLeft) / 32767L; SendDlgItemMessage( hWnd, IDC_SLIDER_WAVVOL, SM_SETPOSITION, 0, lPosition ); iVolumeState = 1; // Initialize the options bOption[0] = App.bOptionTransitions; bOption[1] = App.bOptionAutoTarget; bOption[2] = App.bOptionFireBack; bOption[3] = App.bOptionMusic; bOption[4] = App.bOptionBarricades; //bOption[] = App.bOptionTaunts; for (int i=0; i<MAX_OPTIONS; i++) { SendDlgItemMessage(hWnd, IDC_OPTION1+(i*2), SM_SETSTATE, bOption[i], 0L); SendDlgItemMessage(hWnd, IDC_OPTSTATE1+(i*2), SM_SETSTATE, bOption[i], 0L); EnableWindow(GetDlgItem(hWnd, IDC_OPTSTATE1+(i*2)), FALSE); } return (TRUE); }
//-------------------------------------------------------------- void AppCore::setup(const int numOutChannels, const int numInChannels, const int sampleRate, const int ticksPerBuffer) { ofSetFrameRate(60); ofSetVerticalSync(true); //ofSetLogLevel(OF_LOG_VERBOSE); // double check where we are ... cout << ofFilePath::getCurrentWorkingDirectory() << endl; if(!pd.init(numOutChannels, numInChannels, sampleRate, ticksPerBuffer)) { ofLog(OF_LOG_ERROR, "Could not init pd"); OF_EXIT_APP(1); } midiChan = 1; // midi channels are 1-16 // subscribe to receive source names pd.subscribe("toOF"); pd.subscribe("env"); // add message receiver, disables polling (see processEvents) pd.addReceiver(*this); // automatically receives from all subscribed sources pd.ignore(*this, "env"); // don't receive from "env" //pd.ignore(*this); // ignore all sources //pd.receive(*this, "toOF"); // receive only from "toOF" // add midi receiver pd.addMidiReceiver(*this); // automatically receives from all channels //pd.ignoreMidi(*this, 1); // ignore midi channel 1 //pd.ignoreMidi(*this); // ignore all channels //pd.receiveMidi(*this, 1); // receive only from channel 1 // add the data/pd folder to the search path pd.addToSearchPath("pd"); // audio processing on pd.start(); cout << endl << "BEGIN Patch Test" << endl; // open patch Patch patch = pd.openPatch("test.pd"); cout << patch << endl; // close patch pd.closePatch(patch); cout << patch << endl; // open patch patch = pd.openPatch("test.pd"); cout << patch << endl; cout << "FINISH Patch Test" << endl; cout << endl << "BEGIN Message Test" << endl; // test basic atoms pd.sendBang("fromOF"); pd.sendFloat("fromOF", 100); pd.sendSymbol("fromOF", "test string"); // stream interface pd << Bang("fromOF") << Float("fromOF", 100) << Symbol("fromOF", "test string"); // send a list pd.startMessage(); pd.addFloat(1.23); pd.addSymbol("a symbol"); pd.finishList("fromOF"); // send a message to the $0 receiver ie $0-toOF pd.startMessage(); pd.addFloat(1.23); pd.addSymbol("a symbol"); pd.finishList(patch.dollarZeroStr()+"-fromOF"); // send a list using the List object List testList; testList.addFloat(1.23); testList.addSymbol("sent from a List object"); pd.sendList("fromOF", testList); pd.sendMessage("fromOF", "msg", testList); // stream interface for list pd << StartMessage() << 1.23 << "sent from a streamed list" << FinishList("fromOF"); cout << "FINISH Message Test" << endl; cout << endl << "BEGIN MIDI Test" << endl; // send functions pd.sendNoteOn(midiChan, 60); pd.sendControlChange(midiChan, 0, 64); pd.sendProgramChange(midiChan, 100); // note: pgm num range is 1 - 128 pd.sendPitchBend(midiChan, 2000); // note: ofxPd uses -8192 - 8192 while [bendin] returns 0 - 16383, // so sending a val of 2000 gives 10192 in pd pd.sendAftertouch(midiChan, 100); pd.sendPolyAftertouch(midiChan, 64, 100); pd.sendMidiByte(0, 239); // note: pd adds +2 to the port number from [midiin], [sysexin], & [realtimein] pd.sendSysex(0, 239); // so sending to port 0 gives port 2 in pd pd.sendSysRealTime(0, 239); // stream pd << NoteOn(midiChan, 60) << ControlChange(midiChan, 100, 64) << ProgramChange(midiChan, 100) << PitchBend(midiChan, 2000) << Aftertouch(midiChan, 100) << PolyAftertouch(midiChan, 64, 100) << StartMidi(0) << 239 << Finish() << StartSysex(0) << 239 << Finish() << StartSysRealTime(0) << 239 << Finish(); cout << "FINISH MIDI Test" << endl; cout << endl << "BEGIN Array Test" << endl; // array check length cout << "array1 len: " << pd.arraySize("array1") << endl; // read array std::vector<float> array1; pd.readArray("array1", array1); // sets array to correct size cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; // write array for(int i = 0; i < array1.size(); ++i) array1[i] = i; pd.writeArray("array1", array1); // ready array pd.readArray("array1", array1); cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; // clear array pd.clearArray("array1", 10); // ready array pd.readArray("array1", array1); cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; cout << "FINISH Array Test" << endl; cout << endl << "BEGIN PD Test" << endl; pd.sendSymbol("fromOF", "test"); cout << "FINISH PD Test" << endl << endl; cout << endl << "BEGIN Event Polling Test" << endl; // clear receivers, enable polling pd.clearReceivers(); pd.clearMidiReceivers(); pd.sendSymbol("fromOF", "test"); processEvents(); // <-- manually poll for events // re-add receivers, disable polling pd.addReceiver(*this); pd.addMidiReceiver(*this); pd.ignore(*this, "env"); cout << "FINISH Event Polling Test" << endl << endl; // play a tone by sending a list // [list tone pitch 72 ( pd.startMessage(); pd.addSymbol("pitch"); pd.addFloat(72); pd.finishList("tone"); pd.sendBang("tone"); }
//-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); //ofSetLogLevel("Pd", OF_LOG_VERBOSE); // see verbose info inside // double check where we are ... cout << ofFilePath::getCurrentWorkingDirectory() << endl; // the number of libpd ticks per buffer, // used to compute the audio buffer len: tpb * blocksize (always 64) #ifdef TARGET_LINUX_ARM // longer latency for Raspberry PI int ticksPerBuffer = 32; // 32 * 64 = buffer len of 2048 int numInputs = 0; // no built in mic #else int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512 int numInputs = 1; #endif // setup OF sound stream ofSoundStreamSetup(2, numInputs, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3); // setup Pd // // set 4th arg to true for queued message passing using an internal ringbuffer, // this is useful if you need to control where and when the message callbacks // happen (ie. within a GUI thread) // // note: you won't see any message prints until update() is called since // the queued messages are processed there, this is normal // if(!pd.init(2, numInputs, 44100, ticksPerBuffer, false)) { OF_EXIT_APP(1); } midiChan = 1; // midi channels are 1-16 // subscribe to receive source names pd.subscribe("toOF"); pd.subscribe("env"); // add message receiver, required if you want to recieve messages pd.addReceiver(*this); // automatically receives from all subscribed sources pd.ignoreSource(*this, "env"); // don't receive from "env" //pd.ignoreSource(*this); // ignore all sources //pd.receiveSource(*this, "toOF"); // receive only from "toOF" // add midi receiver, required if you want to recieve midi messages pd.addMidiReceiver(*this); // automatically receives from all channels //pd.ignoreMidiChannel(*this, 1); // ignore midi channel 1 //pd.ignoreMidiChannel(*this); // ignore all channels //pd.receiveMidiChannel(*this, 1); // receive only from channel 1 // add the data/pd folder to the search path pd.addToSearchPath("pd/abs"); // audio processing on pd.start(); // ----------------------------------------------------- cout << endl << "BEGIN Patch Test" << endl; // open patch Patch patch = pd.openPatch("pd/test.pd"); cout << patch << endl; // close patch pd.closePatch(patch); cout << patch << endl; // open patch again patch = pd.openPatch(patch); cout << patch << endl; cout << "FINISH Patch Test" << endl; // ----------------------------------------------------- cout << endl << "BEGIN Message Test" << endl; // test basic atoms pd.sendBang("fromOF"); pd.sendFloat("fromOF", 100); pd.sendSymbol("fromOF", "test string"); // stream interface pd << Bang("fromOF") << Float("fromOF", 100) << Symbol("fromOF", "test string"); // send a list pd.startMessage(); pd.addFloat(1.23); pd.addSymbol("a symbol"); pd.finishList("fromOF"); // send a message to the $0 receiver ie $0-fromOF pd.startMessage(); pd.addFloat(1.23); pd.addSymbol("a symbol"); pd.finishList(patch.dollarZeroStr()+"-fromOF"); // send a list using the List object List testList; testList.addFloat(1.23); testList.addSymbol("sent from a List object"); pd.sendList("fromOF", testList); pd.sendMessage("fromOF", "msg", testList); // stream interface for list pd << StartMessage() << 1.23 << "sent from a streamed list" << FinishList("fromOF"); cout << "FINISH Message Test" << endl; // ----------------------------------------------------- cout << endl << "BEGIN MIDI Test" << endl; // send functions pd.sendNoteOn(midiChan, 60); pd.sendControlChange(midiChan, 0, 64); pd.sendProgramChange(midiChan, 100); // note: pgm num range is 1 - 128 pd.sendPitchBend(midiChan, 2000); // note: ofxPd uses -8192 - 8192 while [bendin] returns 0 - 16383, // so sending a val of 2000 gives 10192 in pd pd.sendAftertouch(midiChan, 100); pd.sendPolyAftertouch(midiChan, 64, 100); pd.sendMidiByte(0, 239); // note: pd adds +2 to the port number from [midiin], [sysexin], & [realtimein] pd.sendSysex(0, 239); // so sending to port 0 gives port 2 in pd pd.sendSysRealTime(0, 239); // stream pd << NoteOn(midiChan, 60) << ControlChange(midiChan, 100, 64) << ProgramChange(midiChan, 100) << PitchBend(midiChan, 2000) << Aftertouch(midiChan, 100) << PolyAftertouch(midiChan, 64, 100) << StartMidi(0) << 239 << Finish() << StartSysex(0) << 239 << Finish() << StartSysRealTime(0) << 239 << Finish(); cout << "FINISH MIDI Test" << endl; // ----------------------------------------------------- cout << endl << "BEGIN Array Test" << endl; // array check length cout << "array1 len: " << pd.arraySize("array1") << endl; // read array std::vector<float> array1; pd.readArray("array1", array1); // sets array to correct size cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; // write array for(int i = 0; i < array1.size(); ++i) array1[i] = i; pd.writeArray("array1", array1); // ready array pd.readArray("array1", array1); cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; // clear array pd.clearArray("array1", 10); // ready array pd.readArray("array1", array1); cout << "array1 "; for(int i = 0; i < array1.size(); ++i) cout << array1[i] << " "; cout << endl; cout << "FINISH Array Test" << endl; // ----------------------------------------------------- cout << endl << "BEGIN PD Test" << endl; pd.sendSymbol("fromOF", "test"); cout << "FINISH PD Test" << endl << endl; // ----------------------------------------------------- cout << endl << "BEGIN Instance Test" << endl; // open 10 instances for(int i = 0; i < 10; ++i) { Patch p = pd.openPatch("pd/instance.pd"); instances.push_back(p); } // send a hello bang to each instance individually using the dollarZero // to [r $0-instance] which should print the instance dollarZero unique id // and a unique random number for(int i = 0; i < instances.size(); ++i) { pd.sendBang(instances[i].dollarZeroStr()+"-instance"); } // send a random float between 0 and 100 for(int i = 0; i < instances.size(); ++i) { pd.sendFloat(instances[i].dollarZeroStr()+"-instance", int(ofRandom(0, 100))); } // send a symbol for(int i = 0; i < instances.size(); ++i) { pd.sendSymbol(instances[i].dollarZeroStr()+"-instance", "howdy dude"); } // close all instances for(int i = 0; i < instances.size(); ++i) { pd.closePatch(instances[i]); } instances.clear(); cout << "FINISH Instance Test" << endl; // ----------------------------------------------------- // play a tone by sending a list // [list tone pitch 72 ( pd.startMessage(); pd.addSymbol("pitch"); pd.addFloat(72); pd.finishList("tone"); pd.sendBang("tone"); }
//-------------------------------------------------------------- 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; } }
//************************************************************************ void OptionsSceneCommand( HWND hWnd, int id, HWND hControl, UINT codeNotify ) //************************************************************************ { UINT loWord = (UINT)hControl; UINT hiWord = codeNotify; LPSCENE lpScene = NULL; LPOFFSCREEN lpOffScreen = NULL; switch (id) { case IDC_OPTION1: case IDC_OPTION2: case IDC_OPTION3: case IDC_OPTION4: case IDC_OPTION5: { int i = id - (int)IDC_OPTION1; BOOL bState = !(1 & (int)SendDlgItemMessage(hWnd, id, SM_GETSTATE, 1, 0L)); SendDlgItemMessage(hWnd, IDC_OPTSTATE1+i, SM_SETSTATE, bState, 0L); SendDlgItemMessage(hWnd, id, SM_SETSTATE, bState, 0L); LPSOUND pSound = new CSound(); if (pSound) { pSound->StartResourceID( IDC_OPTSWITCH, NO/*bLoop*/, -1/*iChannel*/, GetApp()->GetInstance(), TRUE ); delete(pSound); } break; } case IDC_EXIT: case IDC_RETURN: { for (int i=0; i<MAX_OPTIONS; i++) bOption[i] = (BOOL)SendDlgItemMessage(hWnd, IDC_OPTION1+(i*2), SM_GETSTATE, 1, 0L); // Assign the options to the values being controlled App.bOptionTransitions = bOption[0]; App.bOptionAutoTarget = bOption[1]; App.bOptionFireBack = bOption[2]; App.bOptionMusic = bOption[3]; App.bOptionBarricades = bOption[4]; //App.bOptionTaunts = bOption[]; if ( App.bOptionsfromGame ) ResumeGame( hWnd, 0 ); else GetApp()->GotoScene (hWnd, 2); // Return to main screen break; } case IDC_VOLUME0: { //iVolumeState = SendDlgItemMessage( hWnd, IDC_VOLUME0, SM_GETSTATE, 0, 0L ); if (iVolumeState == 4) { iVolumeState = 0; SendDlgItemMessage( hWnd, IDC_VOLUME0, SM_SETSTATE, iVolumeState, 0L ); } else { iVolumeState++; SendDlgItemMessage( hWnd, IDC_VOLUME0, SM_SETSTATE, iVolumeState, 0L); } break; } case IDC_SLIDER_MIDIVOL: { // Start and stop the looping sound StartMidi( !loWord ); // loWord is 1, on slider up WORD wVolume = (WORD)(( 32767L * (DWORD)hiWord ) / 100L); MCISetVolume ((LPSTR)MCI_DEVTYPE_SEQUENCER, wVolume | 0x8000, wVolume | 0x8000); break; } case IDC_SLIDER_WAVVOL: { // Start and stop the looping sound StartWave( !loWord ); // loWord is 1, on slider up WORD wVolume = (WORD)(( 32767L * (DWORD)hiWord ) / 100L); MCISetVolume ((LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO, wVolume | 0x8000, wVolume | 0x8000); break; } default: break; } }