1717using namespace std ;
1818
1919
20- libusb_device_handle* SteamController_OpenAndClaim (int *interface_num){
20+ struct ParamsStruct {
21+ const char * midiSong;
22+ unsigned int intervalUSec;
23+ int libusbDebugLevel;
24+ bool repeatSong;
25+ };
26+
27+ struct SteamControllerInfos {
28+ libusb_device_handle* dev_handle;
29+ int interfaceNum;
30+ };
31+
32+ SteamControllerInfos steamController1;
33+
34+
35+ bool SteamController_OpenAndClaim (SteamControllerInfos* controller){
36+ if (!controller)
37+ return false ;
38+
2139 libusb_device_handle* dev_handle;
2240 // Open Steam Controller device
2341 if ((dev_handle = libusb_open_device_with_vid_pid (NULL , 0x28DE , 0x1102 )) != NULL ){ // Wired Steam Controller
2442 cout<<" Found wired Steam Controller" <<endl;
25- (*interface_num) = 2 ;
43+ controller->dev_handle = dev_handle;
44+ controller->interfaceNum = 2 ;
2645 }
2746 else if ((dev_handle = libusb_open_device_with_vid_pid (NULL , 0x28DE , 0x1142 )) != NULL ){ // Steam Controller dongle
2847 cout<<" Found Steam Dongle, will attempt to use the first Steam Controller" <<endl;
29- (*interface_num) = 1 ;
48+ controller->dev_handle = dev_handle;
49+ controller->interfaceNum = 1 ;
3050 }
3151 else {
3252 cout<<" No device found" <<endl;
33- std::cin.ignore ();
34- return NULL ;
53+ return false ;
3554 }
3655
3756 // On Linux, automatically detach and reattach kernel module
38- libusb_set_auto_detach_kernel_driver (dev_handle,1 );
57+ libusb_set_auto_detach_kernel_driver (controller-> dev_handle ,1 );
3958
4059 // Claim the USB interface controlling the haptic actuators
41- int r = libusb_claim_interface (dev_handle,(*interface_num) );
60+ int r = libusb_claim_interface (controller-> dev_handle ,controller-> interfaceNum );
4261 if (r < 0 ) {
4362 cout<<" Interface claim Error " <<r<<endl;
4463 std::cin.ignore ();
45- libusb_close (dev_handle);
46- return NULL ;
64+ libusb_close (controller-> dev_handle );
65+ return false ;
4766 }
4867
49- return dev_handle;
68+ return true ;
69+ }
70+
71+ void SteamController_Close (SteamControllerInfos* controller){
72+ int r = libusb_release_interface (controller->dev_handle ,controller->interfaceNum );
73+ if (r < 0 ) {
74+ cout<<" Interface release Error " <<r<<endl;
75+ std::cin.ignore ();
76+ return ;
77+ }
78+ libusb_close (controller->dev_handle );
5079}
5180
5281
53- int SteamController_PlayNote (libusb_device_handle *dev_handle , int haptic, unsigned int note,double duration = DURATION_MAX){
82+ int SteamController_PlayNote (SteamControllerInfos* controller , int haptic, unsigned int note,double duration = DURATION_MAX){
5483 double midiFrequency[128] = {8.1758, 8.66196, 9.17702, 9.72272, 10.3009, 10.9134, 11.5623, 12.2499, 12.9783, 13.75, 14.5676, 15.4339, 16.3516, 17.3239, 18.354, 19.4454, 20.6017, 21.8268, 23.1247, 24.4997, 25.9565, 27.5, 29.1352, 30.8677, 32.7032, 34.6478, 36.7081, 38.8909, 41.2034, 43.6535, 46.2493, 48.9994, 51.9131, 55, 58.2705, 61.7354, 65.4064, 69.2957, 73.4162, 77.7817, 82.4069, 87.3071, 92.4986, 97.9989, 103.826, 110, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767, 1046.5, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760, 1864.66, 1975.53, 2093, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520, 3729.31, 3951.07, 4186.01, 4434.92, 4698.64, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040, 7458.62, 7902.13, 8372.02, 8869.84, 9397.27, 9956.06, 10548.1, 11175.3, 11839.8, 12543.9};
5584
5685 unsigned char dataBlob[64 ] = {0x8f ,
@@ -90,7 +119,7 @@ int SteamController_PlayNote(libusb_device_handle *dev_handle, int haptic, unsig
90119 dataBlob[8 ] = repeatCount / 0xff ;
91120
92121 int r;
93- r = libusb_control_transfer (dev_handle,0x21 ,9 ,0x0300 ,2 ,dataBlob,64 ,1000 );
122+ r = libusb_control_transfer (controller-> dev_handle ,0x21 ,9 ,0x0300 ,2 ,dataBlob,64 ,1000 );
94123 if (r < 0 ) {
95124 cout<<" Command Error " <<r<< endl;
96125 return 1 ;
@@ -144,15 +173,15 @@ void displayCurrentNote(int channel, unsigned int note){
144173 cout.flush ();
145174}
146175
147- void playSong (libusb_device_handle *steamcontroller_handle, const char * songfile, unsigned int sleepIntervalUsec ){
176+ void playSong (SteamControllerInfos* controller, const ParamsStruct params ){
148177
149178 MidiFile_t midifile;
150179
151180 // Open Midi File
152- midifile = MidiFile_load (songfile );
181+ midifile = MidiFile_load (params. midiSong );
153182
154183 if (midifile == NULL ){
155- cout << " Unable to open song file " << songfile << endl;
184+ cout << " Unable to open song file " << params. midiSong << endl;
156185 return ;
157186 }
158187
@@ -163,7 +192,7 @@ void playSong(libusb_device_handle *steamcontroller_handle, const char* songfile
163192 }
164193
165194 // Waiting for user to press enter
166- cout << " Starting playback of " <<songfile << endl;
195+ cout << " Starting playback of " <<params. midiSong << endl;
167196 sleep (1 );
168197
169198 // Get current time point, will be used to know elapsed time
@@ -172,7 +201,7 @@ void playSong(libusb_device_handle *steamcontroller_handle, const char* songfile
172201 // Iterate through events
173202 MidiFileEvent_t currentEvent = MidiFile_getFirstEvent (midifile);
174203 while (currentEvent != NULL ){
175- usleep (sleepIntervalUsec );
204+ usleep (params. intervalUSec );
176205
177206 // We now need to play all events with tick < currentTime
178207 long currentTick = MidiFile_getTickFromTime (midifile,timeElapsedSince (tOrigin));
@@ -213,7 +242,7 @@ void playSong(libusb_device_handle *steamcontroller_handle, const char* songfile
213242 eventNote = MidiFileNoteStartEvent_getNote (selectedEvent);
214243 }
215244
216- SteamController_PlayNote (steamcontroller_handle ,currentChannel,eventNote);
245+ SteamController_PlayNote (controller ,currentChannel,eventNote);
217246 displayCurrentNote (currentChannel, eventNote);
218247 }
219248
@@ -225,13 +254,6 @@ void playSong(libusb_device_handle *steamcontroller_handle, const char* songfile
225254
226255
227256
228- struct ParamsStruct {
229- const char * midiSong;
230- unsigned int intervalUSec;
231- int libusbDebugLevel;
232- bool repeatSong;
233- };
234-
235257
236258bool parseArguments (int argc, char ** argv, ParamsStruct* params){
237259 int c;
@@ -267,13 +289,21 @@ bool parseArguments(int argc, char** argv, ParamsStruct* params){
267289 }
268290}
269291
270- int main (int argc, char ** argv)
271- {
272- libusb_device_handle *dev_handle; // a device handle
273- int interface_num = 0 ;
274292
275- int r; // for return values
293+ void abortPlaying (int ){
294+ for (int i = 0 ; i < CHANNEL_COUNT ; i++){
295+ SteamController_PlayNote (&steamController1,i,NOTE_STOP);
296+ }
297+
298+ SteamController_Close (&steamController1);
276299
300+ cout << endl<< " Aborted " << endl;
301+
302+ exit (1 );
303+ }
304+
305+ int main (int argc, char ** argv)
306+ {
277307 cout <<" Steam Controller Singer by Pila" <<endl;
278308
279309 ParamsStruct params;
@@ -291,7 +321,7 @@ int main(int argc, char** argv)
291321
292322
293323 // Initializing LIBUSB
294- r = libusb_init (NULL );
324+ int r = libusb_init (NULL );
295325 if (r < 0 ) {
296326 cout<<" LIBUSB Init Error " <<r<<endl;
297327 std::cin.ignore ();
@@ -301,25 +331,21 @@ int main(int argc, char** argv)
301331 libusb_set_debug (NULL , params.libusbDebugLevel );
302332
303333 // Gaining access to Steam Controller
304- dev_handle = SteamController_OpenAndClaim (&interface_num);
305- if (dev_handle == NULL )
334+ if (!SteamController_OpenAndClaim (&steamController1)){
306335 return 1 ;
336+ }
307337
338+ // Set mecanism to stop playing when closing process
339+ signal (SIGINT, abortPlaying);
308340
309341 // Playing song
310342 do {
311- playSong (dev_handle ,params. midiSong ,params. intervalUSec );
343+ playSong (&steamController1 ,params);
312344 }while (params.repeatSong );
313345
314346
315347 // Releasing access to Steam Controller
316- r = libusb_release_interface (dev_handle,interface_num);
317- if (r < 0 ) {
318- cout<<" Interface release Error " <<r<<endl;
319- std::cin.ignore ();
320- return 1 ;
321- }
322- libusb_close (dev_handle);
348+ SteamController_Close (&steamController1);
323349
324350 libusb_exit (NULL );
325351
0 commit comments