13 IPlug
* gPluginInstance
;
15 RtMidiIn
*gMidiIn
= 0;
16 RtMidiOut
*gMidiOut
= 0;
20 AppState
*gActiveState
;
22 char *gINIPath
= new char[200]; // path of ini file
24 unsigned int gIOVS
= 512;
25 unsigned int gSigVS
= 32;
26 unsigned int gBufIndex
= 0; // Loops 0 to SigVS
27 unsigned int gVecElapsed
= 0;
28 double gFadeMult
= 0.; // Fade multiplier
30 std::vector
<unsigned int> gAudioInputDevs
;
31 std::vector
<unsigned int> gAudioOutputDevs
;
32 std::vector
<std::string
> gMIDIInputDevNames
;
33 std::vector
<std::string
> gMIDIOutputDevNames
;
34 std::vector
<std::string
> gAudioIDDevNames
;
38 char buf
[100]; // temp buffer for writing integers to profile strings
40 sprintf(buf
, "%u", gState
->mAudioDriverType
);
41 WritePrivateProfileString("audio", "driver", buf
, gINIPath
);
43 WritePrivateProfileString("audio", "indev", gState
->mAudioInDev
, gINIPath
);
44 WritePrivateProfileString("audio", "outdev", gState
->mAudioOutDev
, gINIPath
);
46 sprintf(buf
, "%u", gState
->mAudioInChanL
);
47 WritePrivateProfileString("audio", "in1", buf
, gINIPath
);
48 sprintf(buf
, "%u", gState
->mAudioInChanR
);
49 WritePrivateProfileString("audio", "in2", buf
, gINIPath
);
50 sprintf(buf
, "%u", gState
->mAudioOutChanL
);
51 WritePrivateProfileString("audio", "out1", buf
, gINIPath
);
52 sprintf(buf
, "%u", gState
->mAudioOutChanR
);
53 WritePrivateProfileString("audio", "out2", buf
, gINIPath
);
54 sprintf(buf
, "%u", gState
->mAudioInIsMono
);
55 WritePrivateProfileString("audio", "monoinput", buf
, gINIPath
);
57 WritePrivateProfileString("audio", "iovs", gState
->mAudioIOVS
, gINIPath
);
58 WritePrivateProfileString("audio", "sigvs", gState
->mAudioSigVS
, gINIPath
);
60 WritePrivateProfileString("audio", "sr", gState
->mAudioSR
, gINIPath
);
62 WritePrivateProfileString("midi", "indev", gState
->mMidiInDev
, gINIPath
);
63 WritePrivateProfileString("midi", "outdev", gState
->mMidiOutDev
, gINIPath
);
65 sprintf(buf
, "%u", gState
->mMidiInChan
);
66 WritePrivateProfileString("midi", "inchan", buf
, gINIPath
);
67 sprintf(buf
, "%u", gState
->mMidiOutChan
);
68 WritePrivateProfileString("midi", "outchan", buf
, gINIPath
);
71 // returns the device name. Core Audio device names are truncated
72 std::string
GetAudioDeviceName(int idx
)
74 return gAudioIDDevNames
.at(idx
);
77 // returns the rtaudio device ID, based on the (truncated) device name
78 int GetAudioDeviceID(char* deviceNameToTest
)
82 for(int i
= 0; i
< gAudioIDDevNames
.size(); i
++)
84 if(!strcmp(deviceNameToTest
, gAudioIDDevNames
.at(i
).c_str() ))
91 unsigned int GetMIDIInPortNumber(const char* nameToTest
)
95 if(!strcmp(nameToTest
, "off")) return 0;
99 if(!strcmp(nameToTest
, "virtual input")) return 1;
102 for (int i
= 0; i
< gMidiIn
->getPortCount(); i
++)
104 if(!strcmp(nameToTest
, gMidiIn
->getPortName(i
).c_str()))
111 unsigned int GetMIDIOutPortNumber(const char* nameToTest
)
115 if(!strcmp(nameToTest
, "off")) return 0;
119 if(!strcmp(nameToTest
, "virtual output")) return 1;
122 for (int i
= 0; i
< gMidiOut
->getPortCount(); i
++)
124 if(!strcmp(nameToTest
, gMidiOut
->getPortName(i
).c_str()))
131 // find out which devices have input channels & which have output channels, add their ids to the lists
136 RtAudio::DeviceInfo info
;
138 gAudioInputDevs
.clear();
139 gAudioOutputDevs
.clear();
140 gAudioIDDevNames
.clear();
142 unsigned int nDevices
= gDAC
->getDeviceCount();
144 for (int i
=0; i
<nDevices
; i
++)
146 info
= gDAC
->getDeviceInfo(i
);
147 std::string deviceName
= info
.name
;
150 size_t colonIdx
= deviceName
.rfind(": ");
152 if(colonIdx
!= std::string::npos
&& deviceName
.length() >= 2)
153 deviceName
= deviceName
.substr(colonIdx
+ 2, deviceName
.length() - colonIdx
- 2);
157 gAudioIDDevNames
.push_back(deviceName
);
159 if ( info
.probed
== false )
160 std::cout
<< deviceName
<< ": Probe Status = Unsuccessful\n";
161 else if ( !strcmp("Generic Low Latency ASIO Driver", deviceName
.c_str() ))
162 std::cout
<< deviceName
<< ": Probe Status = Unsuccessful\n";
165 if(info
.inputChannels
> 0)
166 gAudioInputDevs
.push_back(i
);
168 if(info
.outputChannels
> 0)
169 gAudioOutputDevs
.push_back(i
);
176 if ( !gMidiIn
|| !gMidiOut
)
180 int nInputPorts
= gMidiIn
->getPortCount();
182 gMIDIInputDevNames
.push_back("off");
185 gMIDIInputDevNames
.push_back("virtual input");
188 for (int i
=0; i
<nInputPorts
; i
++ )
190 gMIDIInputDevNames
.push_back(gMidiIn
->getPortName(i
));
193 int nOutputPorts
= gMidiOut
->getPortCount();
195 gMIDIOutputDevNames
.push_back("off");
198 gMIDIOutputDevNames
.push_back("virtual output");
201 for (int i
=0; i
<nOutputPorts
; i
++ )
203 gMIDIOutputDevNames
.push_back(gMidiOut
->getPortName(i
));
204 //This means the virtual output port wont be added as an input
209 bool AudioSettingsInStateAreEqual(AppState
* os
, AppState
* ns
)
211 if (os
->mAudioDriverType
!= ns
->mAudioDriverType
) return false;
212 if (strcmp(os
->mAudioInDev
, ns
->mAudioInDev
)) return false;
213 if (strcmp(os
->mAudioOutDev
, ns
->mAudioOutDev
)) return false;
214 if (strcmp(os
->mAudioSR
, ns
->mAudioSR
)) return false;
215 if (strcmp(os
->mAudioIOVS
, ns
->mAudioIOVS
)) return false;
216 if (strcmp(os
->mAudioSigVS
, ns
->mAudioSigVS
)) return false;
217 if (os
->mAudioInChanL
!= ns
->mAudioInChanL
) return false;
218 if (os
->mAudioInChanR
!= ns
->mAudioInChanR
) return false;
219 if (os
->mAudioOutChanL
!= ns
->mAudioOutChanL
) return false;
220 if (os
->mAudioOutChanR
!= ns
->mAudioOutChanR
) return false;
221 if (os
->mAudioInIsMono
!= ns
->mAudioInIsMono
) return false;
226 bool MIDISettingsInStateAreEqual(AppState
* os
, AppState
* ns
)
228 if (strcmp(os
->mMidiInDev
, ns
->mMidiInDev
)) return false;
229 if (strcmp(os
->mMidiOutDev
, ns
->mMidiOutDev
)) return false;
230 if (os
->mMidiInChan
!= ns
->mMidiInChan
) return false;
231 if (os
->mMidiOutChan
!= ns
->mMidiOutChan
) return false;
236 void MIDICallback( double deltatime
, std::vector
< unsigned char > *message
, void *userData
)
238 if ( message
->size() )
242 switch (message
->size())
245 myMsg
= new IMidiMsg(0, message
->at(0), 0, 0);
248 myMsg
= new IMidiMsg(0, message
->at(0), message
->at(1), 0);
251 myMsg
= new IMidiMsg(0, message
->at(0), message
->at(1), message
->at(2));
254 DBGMSG("NOT EXPECTING %d midi callback msg len\n", (int) message
->size());
258 IMidiMsg
msg(*myMsg
);
262 // filter midi messages based on channel, if gStatus.mMidiInChan != all (0)
263 if (gState
->mMidiInChan
)
265 if (gState
->mMidiInChan
== msg
.Channel() + 1 )
266 gPluginInstance
->ProcessMidiMsg(&msg
);
270 gPluginInstance
->ProcessMidiMsg(&msg
);
275 int AudioCallback(void *outputBuffer
,
277 unsigned int nFrames
,
279 RtAudioStreamStatus status
,
283 std::cout
<< "Stream underflow detected!" << std::endl
;
285 double* inputBufferD
= (double*)inputBuffer
;
286 double* outputBufferD
= (double*)outputBuffer
;
288 int inRightOffset
= 0;
290 if(!gState
->mAudioInIsMono
)
291 inRightOffset
= nFrames
;
293 if (gVecElapsed
> N_VECTOR_WAIT
) // wait N_VECTOR_WAIT * iovs before processing audio, to avoid clicks
295 for (int i
=0; i
<nFrames
; i
++)
301 double* inputs
[2] = {inputBufferD
+ i
, inputBufferD
+ inRightOffset
+ i
};
302 double* outputs
[2] = {outputBufferD
+ i
, outputBufferD
+ nFrames
+ i
};
304 gPluginInstance
->LockMutexAndProcessDoubleReplacing(inputs
, outputs
, gSigVS
);
310 gFadeMult
+= (1. / nFrames
);
313 outputBufferD
[i
] *= gFadeMult
;
314 outputBufferD
[i
+ nFrames
] *= gFadeMult
;
316 outputBufferD
[i
] *= APP_MULT
;
317 outputBufferD
[i
+ nFrames
] *= APP_MULT
;
324 memset(outputBuffer
, 0, nFrames
* 2 * sizeof(double));
332 bool TryToChangeAudioDriverType()
338 if (gDAC
->isStreamOpen())
347 if(gState
->mAudioDriverType
== DAC_ASIO
)
348 gDAC
= new RtAudio(RtAudio::WINDOWS_ASIO
);
350 gDAC
= new RtAudio(RtAudio::WINDOWS_DS
);
352 if(gState
->mAudioDriverType
== DAC_COREAUDIO
)
353 gDAC
= new RtAudio(RtAudio::MACOSX_CORE
);
355 //gDAC = new RtAudio(RtAudio::UNIX_JACK);
364 bool TryToChangeAudio()
372 if(gState
->mAudioDriverType
== DAC_ASIO
)
373 inputID
= GetAudioDeviceID(gState
->mAudioOutDev
);
375 inputID
= GetAudioDeviceID(gState
->mAudioInDev
);
377 inputID
= GetAudioDeviceID(gState
->mAudioInDev
);
380 outputID
= GetAudioDeviceID(gState
->mAudioOutDev
);
382 int samplerate
= atoi(gState
->mAudioSR
);
383 int iovs
= atoi(gState
->mAudioIOVS
);
385 if (inputID
!= -1 && outputID
!= -1)
387 return InitialiseAudio(inputID
, outputID
, samplerate
, iovs
, NUM_CHANNELS
, gState
->mAudioInChanL
- 1, gState
->mAudioOutChanL
- 1);
393 bool InitialiseAudio(unsigned int inId
,
398 unsigned int inChanL
,
399 unsigned int outChanL
404 if (gDAC
->isStreamOpen())
406 if (gDAC
->isStreamRunning())
421 RtAudio::StreamParameters iParams
, oParams
;
422 iParams
.deviceId
= inId
;
423 iParams
.nChannels
= chnls
;
424 iParams
.firstChannel
= inChanL
;
426 oParams
.deviceId
= outId
;
427 oParams
.nChannels
= chnls
;
428 oParams
.firstChannel
= outChanL
;
430 gIOVS
= iovs
; // gIOVS may get changed by stream
431 gSigVS
= atoi(gState
->mAudioSigVS
); // This is done here so that it changes when the callback is stopped
433 DBGMSG("\ntrying to start audio stream @ %i sr, %i iovs, %i sigvs\nindev = %i:%s\noutdev = %i:%s\n", sr
, iovs
, gSigVS
, inId
, GetAudioDeviceName(inId
).c_str(), outId
, GetAudioDeviceName(outId
).c_str());
435 RtAudio::StreamOptions options
;
436 options
.flags
= RTAUDIO_NONINTERLEAVED
;
437 // options.streamName = BUNDLE_NAME; // JACK stream name, not used on other streams
443 gPluginInstance
->SetBlockSize(gSigVS
);
444 gPluginInstance
->SetSampleRate(sr
);
445 gPluginInstance
->Reset();
450 gDAC
->openStream( &oParams
, &iParams
, RTAUDIO_FLOAT64
, sr
, &gIOVS
, &AudioCallback
, NULL
, &options
);
453 memcpy(gActiveState
, gState
, sizeof(AppState
)); // copy state to active state
464 bool InitialiseMidi()
468 gMidiIn
= new RtMidiIn();
470 catch ( RtError
&error
)
473 error
.printMessage();
479 gMidiOut
= new RtMidiOut();
481 catch ( RtError
&error
)
484 error
.printMessage();
488 gMidiIn
->setCallback( &MIDICallback
);
489 gMidiIn
->ignoreTypes( !ENABLE_SYSEX
, !ENABLE_MIDICLOCK
, !ENABLE_ACTIVE_SENSING
);
494 bool ChooseMidiInput(const char* pPortName
)
496 unsigned int port
= GetMIDIInPortNumber(pPortName
);
500 strcpy(gState
->mMidiInDev
, "off");
506 msg.MakeControlChangeMsg(IMidiMsg::kAllNotesOff, 127, 0);
508 std::vector<unsigned char> message;
509 message.push_back( msg.mStatus );
510 message.push_back( msg.mData1 );
511 message.push_back( msg.mData2 );
513 gPluginInstance->ProcessMidiMsg(&msg);
517 gMidiIn
->closePort();
526 gMidiIn
->openPort(port
-1);
532 std::string virtualMidiInputName
= "To ";
533 virtualMidiInputName
+= BUNDLE_NAME
;
534 gMidiIn
->openVirtualPort(virtualMidiInputName
);
539 gMidiIn
->openPort(port
-2);
548 bool ChooseMidiOutput(const char* pPortName
)
550 unsigned int port
= GetMIDIOutPortNumber(pPortName
);
554 strcpy(gState
->mMidiOutDev
, "off");
563 msg.MakeControlChangeMsg(IMidiMsg::kAllNotesOff, 127, 0);
565 std::vector<unsigned char> message;
566 message.push_back( msg.mStatus );
567 message.push_back( msg.mData1 );
568 message.push_back( msg.mData2 );
570 gMidiOut->sendMessage( &message );
572 gMidiOut
->closePort();
581 gMidiOut
->openPort(port
-1);
587 std::string virtualMidiOutputName
= "From ";
588 virtualMidiOutputName
+= BUNDLE_NAME
;
589 gMidiOut
->openVirtualPort(virtualMidiOutputName
);
594 gMidiOut
->openPort(port
-2);
603 extern bool AttachGUI()
605 IGraphics
* pGraphics
= gPluginInstance
->GetGUI();
610 if (!pGraphics
->OpenWindow(gHWND
))
613 if (!pGraphics
->OpenWindow(gHWND
))
618 gPluginInstance
->OnGUIOpen();
628 TryToChangeAudioDriverType(); // will init RTAudio with an API type based on gState->mAudioDriverType
629 ProbeAudioIO(); // find out what audio IO devs are available and put their IDs in the global variables gAudioInputDevs / gAudioOutputDevs
630 InitialiseMidi(); // creates RTMidiIn and RTMidiOut objects
631 ProbeMidiIO(); // find out what midi IO devs are available and put their names in the global variables gMidiInputDevs / gMidiOutputDevs
633 // Initialise the plugin
634 gPluginInstance
= MakePlug(gMidiOut
, &gState
->mMidiOutChan
);
635 gPluginInstance
->RestorePreset(0);
637 ChooseMidiInput(gState
->mMidiInDev
);
638 ChooseMidiOutput(gState
->mMidiOutDev
);
655 gMidiIn
->cancelCallback();
656 gMidiIn
->closePort();
657 gMidiOut
->closePort();
659 if ( gDAC
->isStreamOpen() ) gDAC
->closeStream();
661 delete gPluginInstance
;
672 int WINAPI
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpszCmdParam
, int nShowCmd
)
674 // first check to make sure this is the only instance running
675 // http://www.bcbjournal.org/articles/vol3/9911/Single-instance_applications.htm
678 // Try to open the mutex.
679 HANDLE hMutex
= OpenMutex(
680 MUTEX_ALL_ACCESS
, 0, BUNDLE_NAME
);
682 // If hMutex is 0 then the mutex doesn't exist.
684 hMutex
= CreateMutex(0, 0, BUNDLE_NAME
);
687 // This is a second instance. Bring the
688 // original instance to the top.
689 HWND hWnd
= FindWindow(0, BUNDLE_NAME
);
690 SetForegroundWindow(hWnd
);
697 InitCommonControls();
698 gScrollMessage
= RegisterWindowMessage("MSWHEEL_ROLLMSG");
700 gState
= new AppState();
701 gTempState
= new AppState();
702 gActiveState
= new AppState();
704 if (SHGetFolderPathA( NULL
, CSIDL_LOCAL_APPDATA
, NULL
, 0, gINIPath
) != S_OK
)
706 DBGMSG("could not retrieve the user's application data directory!\n");
712 sprintf(gINIPath
, "%s\\%s", gINIPath
, BUNDLE_NAME
); // Add the app name to the path
715 if(stat(gINIPath
, &st
) == 0) // if directory exists
717 sprintf(gINIPath
, "%s\\%s", gINIPath
, "settings.ini"); // add file name to path
719 if(stat(gINIPath
, &st
) == 0) // if settings file exists read values into state
721 gState
->mAudioDriverType
= GetPrivateProfileInt("audio", "driver", 0, gINIPath
);
723 GetPrivateProfileString("audio", "indev", DEFAULT_INPUT_DEV
, gState
->mAudioInDev
, 100, gINIPath
);
724 GetPrivateProfileString("audio", "outdev", DEFAULT_OUTPUT_DEV
, gState
->mAudioOutDev
, 100, gINIPath
);
727 gState
->mAudioInChanL
= GetPrivateProfileInt("audio", "in1", 1, gINIPath
); // 1 is first audio input
728 gState
->mAudioInChanR
= GetPrivateProfileInt("audio", "in2", 2, gINIPath
);
729 gState
->mAudioOutChanL
= GetPrivateProfileInt("audio", "out1", 1, gINIPath
); // 1 is first audio output
730 gState
->mAudioOutChanR
= GetPrivateProfileInt("audio", "out2", 2, gINIPath
);
731 gState
->mAudioInIsMono
= GetPrivateProfileInt("audio", "monoinput", 0, gINIPath
);
733 GetPrivateProfileString("audio", "iovs", "512", gState
->mAudioIOVS
, 100, gINIPath
);
734 GetPrivateProfileString("audio", "sigvs", "32", gState
->mAudioSigVS
, 100, gINIPath
);
735 GetPrivateProfileString("audio", "sr", "44100", gState
->mAudioSR
, 100, gINIPath
);
738 GetPrivateProfileString("midi", "indev", "no input", gState
->mMidiInDev
, 100, gINIPath
);
739 GetPrivateProfileString("midi", "outdev", "no output", gState
->mMidiOutDev
, 100, gINIPath
);
741 gState
->mMidiInChan
= GetPrivateProfileInt("midi", "inchan", 0, gINIPath
); // 0 is any
742 gState
->mMidiOutChan
= GetPrivateProfileInt("midi", "outchan", 0, gINIPath
); // 1 is first chan
744 UpdateINI(); // this will write over any invalid values in the file
746 else // settings file doesn't exist, so populate with default values
753 // folder doesn't exist - make folder and make file
754 CreateDirectory(gINIPath
, NULL
);
755 sprintf(gINIPath
, "%s%s", gINIPath
, "settings.ini"); // add file name to path
756 UpdateINI(); // will write file if doesn't exist
761 CreateDialog(gHINST
,MAKEINTRESOURCE(IDD_DIALOG_MAIN
),GetDesktopWindow(),MainDlgProc
);
766 int vvv
= GetMessage(&msg
,NULL
,0,0);
776 DispatchMessage(&msg
);
780 if (gHWND
&& IsDialogMessage(gHWND
,&msg
)) continue;
782 // default processing for other dialogs
783 HWND hWndParent
=NULL
;
784 HWND temphwnd
= msg
.hwnd
;
787 if (GetClassLong(temphwnd
, GCW_ATOM
) == (INT
)32770)
790 if (!(GetWindowLong(temphwnd
,GWL_STYLE
)&WS_CHILD
)) break; // not a child, exit
793 while (temphwnd
= GetParent(temphwnd
));
795 if (hWndParent
&& IsDialogMessage(hWndParent
,&msg
)) continue;
797 TranslateMessage(&msg
);
798 DispatchMessage(&msg
);
802 // in case gHWND didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly
803 if (gHWND
) DestroyWindow(gHWND
);
807 ReleaseMutex(hMutex
);
811 //TODO proper error catching
812 DBGMSG("another instance running");
818 extern HMENU SWELL_app_stocksysmenu
;
821 INT_PTR
SWELLAppMain(int msg
, INT_PTR parm1
, INT_PTR parm2
)
825 case SWELLAPP_ONLOAD
:
827 gState
= new AppState();
828 gTempState
= new AppState();
829 gActiveState
= new AppState();
831 homeDir
= getenv("HOME");
832 sprintf(gINIPath
, "%s/Library/Application Support/%s/", homeDir
, BUNDLE_NAME
);
835 if(stat(gINIPath
, &st
) == 0) // if directory exists
837 sprintf(gINIPath
, "%s%s", gINIPath
, "settings.ini"); // add file name to path
839 if(stat(gINIPath
, &st
) == 0) // if settings file exists read values into state
841 gState
->mAudioDriverType
= GetPrivateProfileInt("audio", "driver", 0, gINIPath
);
843 GetPrivateProfileString("audio", "indev", "Built-in Input", gState
->mAudioInDev
, 100, gINIPath
);
844 GetPrivateProfileString("audio", "outdev", "Built-in Output", gState
->mAudioOutDev
, 100, gINIPath
);
847 gState
->mAudioInChanL
= GetPrivateProfileInt("audio", "in1", 1, gINIPath
); // 1 is first audio input
848 gState
->mAudioInChanR
= GetPrivateProfileInt("audio", "in2", 2, gINIPath
);
849 gState
->mAudioOutChanL
= GetPrivateProfileInt("audio", "out1", 1, gINIPath
); // 1 is first audio output
850 gState
->mAudioOutChanR
= GetPrivateProfileInt("audio", "out2", 2, gINIPath
);
851 gState
->mAudioInIsMono
= GetPrivateProfileInt("audio", "monoinput", 0, gINIPath
);
853 GetPrivateProfileString("audio", "iovs", "512", gState
->mAudioIOVS
, 100, gINIPath
);
854 GetPrivateProfileString("audio", "sigvs", "32", gState
->mAudioSigVS
, 100, gINIPath
);
855 GetPrivateProfileString("audio", "sr", "44100", gState
->mAudioSR
, 100, gINIPath
);
858 GetPrivateProfileString("midi", "indev", "no input", gState
->mMidiInDev
, 100, gINIPath
);
859 GetPrivateProfileString("midi", "outdev", "no output", gState
->mMidiOutDev
, 100, gINIPath
);
861 gState
->mMidiInChan
= GetPrivateProfileInt("midi", "inchan", 0, gINIPath
); // 0 is any
862 gState
->mMidiOutChan
= GetPrivateProfileInt("midi", "outchan", 0, gINIPath
); // 1 is first chan
864 UpdateINI(); // this will write over any invalid values in the file
866 else // settings file doesn't exist, so populate with default values
872 else // folder doesn't exist - make folder and make file
874 // http://blog.tremend.ro/2008/10/06/create-directories-in-c-using-mkdir-with-proper-permissions/
876 mode_t process_mask
= umask(0);
877 int result_code
= mkdir(gINIPath
, S_IRWXU
| S_IRWXG
| S_IRWXO
);
880 if(result_code
) return 1;
883 sprintf(gINIPath
, "%s%s", gINIPath
, "settings.ini"); // add file name to path
884 UpdateINI(); // will write file if doesn't exist
889 case SWELLAPP_LOADED
:
893 HMENU menu
= SWELL_GetCurrentMenu();
897 // other windows will get the stock (bundle) menus
898 //SWELL_SetDefaultModalWindowMenu(menu);
899 //SWELL_SetDefaultWindowMenu(menu);
901 // work on a new menu
902 menu
= SWELL_DuplicateMenu(menu
);
903 HMENU src
= LoadMenu(NULL
,MAKEINTRESOURCE(IDR_MENU1
));
905 for (x
=0; x
<GetMenuItemCount(src
)-1; x
++)
907 HMENU sm
= GetSubMenu(src
,x
);
911 MENUITEMINFO mii
= {sizeof(mii
),MIIM_TYPE
,};
915 GetMenuItemInfo(src
,x
,TRUE
,&mii
);
916 MENUITEMINFO mi
= {sizeof(mi
),MIIM_STATE
|MIIM_SUBMENU
|MIIM_TYPE
,MFT_STRING
,0,0,SWELL_DuplicateMenu(sm
),NULL
,NULL
,0,str
};
917 InsertMenuItem(menu
,x
+1,TRUE
,&mi
);
924 HMENU sm
=GetSubMenu(menu
,1);
925 DeleteMenu(sm
,ID_QUIT
,MF_BYCOMMAND
); // remove QUIT from our file menu, since it is in the system menu on OSX
926 DeleteMenu(sm
,ID_PREFERENCES
,MF_BYCOMMAND
); // remove PREFERENCES from the file menu, since it is in the system menu on OSX
928 // remove any trailing separators
929 int a
= GetMenuItemCount(sm
);
930 while (a
> 0 && GetMenuItemID(sm
,a
-1)==0) DeleteMenu(sm
,--a
,MF_BYPOSITION
);
932 DeleteMenu(menu
,1,MF_BYPOSITION
); // delete file menu
935 // if we want to set any default modifiers for items in the menus, we can use:
936 // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc.
938 HWND hwnd
= CreateDialog(gHINST
,MAKEINTRESOURCE(IDD_DIALOG_MAIN
),NULL
,MainDlgProc
);
941 SetMenu(hwnd
, menu
); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL
942 SWELL_SetDefaultModalWindowMenu(menu
); // other windows will get the stock (bundle) menus
944 // we need to set it manually (and obviously we've edited the menu anyway)
947 if(!AttachGUI()) DBGMSG("couldn't attach gui\n"); //todo error
950 case SWELLAPP_ONCOMMAND
:
951 // this is to catch commands coming from the system menu etc
952 if (gHWND
&& (parm1
&0xffff)) SendMessage(gHWND
,WM_COMMAND
,parm1
&0xffff,0);
955 case SWELLAPP_DESTROY
:
957 if (gHWND
) DestroyWindow(gHWND
);
960 case SWELLAPP_PROCESSMESSAGE
: // can hook keyboard input here
961 // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to
971 #include "swell-dlggen.h"
973 #define SET_IDD_SCALE 1.
974 #define SET_IDD_STYLE SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_NOAUTOSIZE
976 SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG_MAIN
, SET_IDD_STYLE
, BUNDLE_NAME
, GUI_WIDTH
, GUI_HEIGHT
, SET_IDD_SCALE
)
978 // EDITTEXT IDC_EDIT1,59,50,145,14,ES_AUTOHSCROLL
979 // LTEXT "Enter some text here:",IDC_STATIC,59,39,73,8
981 SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG_MAIN
)
983 SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG_PREF
,SET_IDD_STYLE
,"Preferences",320,420,SET_IDD_SCALE
)
985 GROUPBOX
"Audio Settings", IDC_STATIC
, 5, 10, 300, 230
987 LTEXT
"Driver Type", IDC_STATIC
, 20, 32, 60, 20
988 COMBOBOX IDC_COMBO_AUDIO_DRIVER
, 20, 50, 150, 100, CBS_DROPDOWNLIST
990 LTEXT
"Input Device", IDC_STATIC
, 20, 75, 80, 20
991 COMBOBOX IDC_COMBO_AUDIO_IN_DEV
, 20, 90, 150, 100, CBS_DROPDOWNLIST
993 LTEXT
"Output Device", IDC_STATIC
, 20, 115, 80, 20
994 COMBOBOX IDC_COMBO_AUDIO_OUT_DEV
, 20, 130, 150, 100, CBS_DROPDOWNLIST
996 LTEXT
"In 1 (L)", IDC_STATIC
, 20, 155, 90, 20
997 COMBOBOX IDC_COMBO_AUDIO_IN_L
, 20, 170, 46, 100, CBS_DROPDOWNLIST
999 LTEXT
"In 2 (R)", IDC_STATIC
, 75, 155, 90, 20
1000 COMBOBOX IDC_COMBO_AUDIO_IN_R
, 75, 170, 46, 100, CBS_DROPDOWNLIST
1002 CHECKBOX
"Mono", IDC_CB_MONO_INPUT
, 125, 128, 56, 100, 0
1004 LTEXT
"Out 1 (L)", IDC_STATIC
, 20, 195, 60, 20
1005 COMBOBOX IDC_COMBO_AUDIO_OUT_L
, 20, 210, 46, 100, CBS_DROPDOWNLIST
1007 LTEXT
"Out 2 (R)", IDC_STATIC
, 75, 195, 60, 20
1008 COMBOBOX IDC_COMBO_AUDIO_OUT_R
, 75, 210, 46, 100, CBS_DROPDOWNLIST
1010 LTEXT
"IO Vector Size", IDC_STATIC
, 200, 32, 80, 20
1011 COMBOBOX IDC_COMBO_AUDIO_IOVS
, 200, 50, 90, 100, CBS_DROPDOWNLIST
1013 LTEXT
"Signal Vector Size", IDC_STATIC
, 200, 75, 100, 20
1014 COMBOBOX IDC_COMBO_AUDIO_SIGVS
, 200, 90, 90, 100, CBS_DROPDOWNLIST
1016 LTEXT
"Sampling Rate", IDC_STATIC
, 200, 115, 80, 20
1017 COMBOBOX IDC_COMBO_AUDIO_SR
, 200, 130, 90, 100, CBS_DROPDOWNLIST
1019 PUSHBUTTON
"Audio Midi Setup...", IDC_BUTTON_ASIO
, 180, 170, 110, 40
1021 GROUPBOX
"MIDI Settings", IDC_STATIC
, 5, 255, 300, 120
1023 LTEXT
"Input Device", IDC_STATIC
, 20, 275, 100, 20
1024 COMBOBOX IDC_COMBO_MIDI_IN_DEV
, 20, 293, 150, 100, CBS_DROPDOWNLIST
1026 LTEXT
"Output Device", IDC_STATIC
, 20, 320, 100, 20
1027 COMBOBOX IDC_COMBO_MIDI_OUT_DEV
, 20, 338, 150, 100, CBS_DROPDOWNLIST
1029 LTEXT
"Input Channel", IDC_STATIC
, 200, 275, 100, 20
1030 COMBOBOX IDC_COMBO_MIDI_IN_CHAN
, 200, 293, 90, 100, CBS_DROPDOWNLIST
1032 LTEXT
"Output Channel", IDC_STATIC
, 200, 320, 100, 20
1033 COMBOBOX IDC_COMBO_MIDI_OUT_CHAN
, 200, 338, 90, 100, CBS_DROPDOWNLIST
1035 DEFPUSHBUTTON
"OK", IDOK
, 192, 383, 50, 20
1036 PUSHBUTTON
"Apply", IDAPPLY
, 132, 383, 50, 20
1037 PUSHBUTTON
"Cancel", IDCANCEL
, 252, 383, 50, 20
1039 SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG_PREF
)
1041 #include "swell-menugen.h"
1043 SWELL_DEFINE_MENU_RESOURCE_BEGIN(IDR_MENU1
)
1046 // MENUITEM SEPARATOR
1047 MENUITEM
"Preferences...", ID_PREFERENCES
1048 MENUITEM
"&Quit", ID_QUIT
1052 MENUITEM
"&About", ID_ABOUT
1054 SWELL_DEFINE_MENU_RESOURCE_END(IDR_MENU1
)