2 Copyright (C) 2004 Paul Davis <paul@linuxaudiosystems.com>
3 Torben Hohn <torbenh@informatik.uni-bremen.de>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <sys/types.h>
25 #include <semaphore.h>
26 #include <vestige/aeffectx.h>
29 #include "jack/midiport.h"
35 extern long jack_host_callback (struct AEffect
*, long, long, long, void*, float);
39 extern void gui_init (int* argc
, char** argv
[]);
40 extern int manage_vst_plugin (JackVST
*);
43 extern int ladish_save_now
;
44 extern char* ladish_state_filename
;
46 /* Prototype for plugin "canDo" helper function*/
47 int canDo(struct AEffect
* plugin
, char* feature
);
49 /* Structures & Prototypes for midi output and associated queue */
50 typedef struct _MidiMessage MidiMessage
;
54 int len
; /* Length of MIDI message, in bytes. */
55 unsigned char data
[3];
57 #define RINGBUFFER_SIZE 1024*sizeof(MidiMessage)
58 void process_midi_output(JackVST
* jvst
, jack_nframes_t nframes
);
59 void queue_midi_message(JackVST
* jvst
, int status
, int d1
, int d2
, jack_nframes_t delta
);
62 // Until i get Jack to call me when he wants to create a thread,
63 // i need to go through this.
65 volatile int with_winaudio
= 1;
67 static HANDLE audioThreadHandle
= 0;
68 static jack_nframes_t winaudio_nframes
;
69 static void *winaudio_data
;
70 sem_t winaudio_activate
, winaudio_done
;
72 static pthread_t audio_thread
= 0;
74 int winaudio_process_callback( jack_nframes_t nframes
, void *data
)
76 winaudio_nframes
= nframes
;
79 sem_post( &winaudio_activate
);
80 sem_wait( &winaudio_done
);
86 WinAudioThreadMain(LPVOID parameter
)
89 struct sched_param param
;
90 param
.sched_priority
= 10;
91 pthread_setschedparam(pthread_self(), SCHED_FIFO
, ¶m
);
93 sem_post( &winaudio_done
);
95 while( with_winaudio
) {
96 sem_wait( &winaudio_activate
);
97 process_callback( winaudio_nframes
, winaudio_data
);
98 sem_post( &winaudio_done
);
103 void process_midi_output(JackVST
* jvst
, jack_nframes_t nframes
)
105 /* This jack ringbuffer consume code was largely taken from jack-keyboard */
106 /* written by Edward Tomasz Napierala <trasz@FreeBSD.org> */
108 unsigned char *buffer
;
110 jack_nframes_t last_frame_time
;
111 jack_ringbuffer_t
* ringbuffer
;
114 last_frame_time
= jack_last_frame_time(jvst
->client
);
116 port_buffer
= jack_port_get_buffer(jvst
->midi_outport
, nframes
);
117 if (port_buffer
== NULL
) {
118 fst_error("jack_port_get_buffer failed, cannot send anything.");
122 ringbuffer
= jvst
->ringbuffer
;
123 while (jack_ringbuffer_read_space(ringbuffer
)) {
124 read
= jack_ringbuffer_peek(ringbuffer
, (char*)&ev
, sizeof(ev
));
125 if (read
!= sizeof(ev
)) {
126 fst_error("Short read from the ringbuffer, possible note loss.");
127 jack_ringbuffer_read_advance(ringbuffer
, read
);
131 t
= ev
.time
+ nframes
- last_frame_time
;
133 /* If computed time is too much into the future, we'll send it later. */
134 if (t
>= (int)nframes
) break;
136 /* If computed time is < 0, we missed a cycle because of xrun. */
139 jack_ringbuffer_read_advance(ringbuffer
, sizeof(ev
));
141 buffer
= jack_midi_event_reserve(port_buffer
, t
, ev
.len
);
142 if (buffer
== NULL
) {
143 fst_error("queue: jack_midi_event_reserve failed, NOTE LOST.");
147 memcpy(buffer
, ev
.data
, ev
.len
);
151 void queue_midi_message(JackVST
* jvst
, int status
, int d1
, int d2
, jack_nframes_t delta
)
153 jack_ringbuffer_t
* ringbuffer
;
155 int statusHi
= (status
>> 4) & 0xF;
156 int statusLo
= status
& 0xF;
159 /*fst_error("queue_new_message = 0x%hhX, %d, %d\n", status, d1, d2);*/
160 /* fst_error("statusHi = %d, statusLo = %d\n", statusHi, statusLo);*/
163 if (statusHi
== 0xC || statusHi
== 0xD) {
166 } else if (statusHi
== 0xF) {
167 if (statusLo
== 0 || statusLo
== 2) {
171 } else if (statusLo
== 1 || statusLo
== 3) {
181 if( pthread_self() == audio_thread
) {
182 unsigned char *buffer
;
184 port_buffer
= jack_port_get_buffer(jvst
->midi_outport
, jack_get_buffer_size( jvst
->client
) );
185 if (port_buffer
== NULL
) {
186 fst_error("jack_port_get_buffer failed, cannot send anything.");
190 buffer
= jack_midi_event_reserve(port_buffer
, delta
, ev
.len
);
191 if (buffer
== NULL
) {
192 fst_error("jack_midi_event_reserve failed, NOTE LOST.");
195 memcpy(buffer
, ev
.data
, ev
.len
);
200 ev
.time
= jack_frame_time(jvst
->client
) + delta
;
202 ringbuffer
= jvst
->ringbuffer
;
203 if (jack_ringbuffer_write_space(ringbuffer
) < sizeof(ev
)) {
204 fst_error("Not enough space in the ringbuffer, NOTE LOST.");
208 written
= jack_ringbuffer_write(ringbuffer
, (char*)&ev
, sizeof(ev
));
209 if (written
!= sizeof(ev
)) {
210 fst_error("jack_ringbuffer_write failed, NOTE LOST.");
214 int process_callback( jack_nframes_t nframes
, void* data
)
218 JackVST
* jvst
= (JackVST
*) data
;
219 struct AEffect
* plugin
= jvst
->fst
->plugin
;
221 audio_thread
= pthread_self();
223 if( !jvst
->resume_called
) {
224 jvst
->resume_called
= TRUE
;
225 plugin
->dispatcher (plugin
, effMainsChanged
, 0, 1, NULL
, 0.0f
);
227 for (i
= 0; i
< plugin
->numInputs
; ++i
) {
228 jvst
->ins
[i
] = (float *) jack_port_get_buffer (jvst
->inports
[i
], nframes
);
231 for (i
= 0; i
< plugin
->numOutputs
; ++i
) {
232 jvst
->outs
[i
] = (float *) jack_port_get_buffer (jvst
->outports
[i
], nframes
);
235 if (jvst
->bypassed
) {
237 if (plugin
->numInputs
) {
238 for (o
= 0, i
= 0; o
< plugin
->numOutputs
; ++o
) {
239 memcpy (jvst
->outs
[o
], jvst
->ins
[i
], sizeof (float) * nframes
);
241 if (i
< plugin
->numOutputs
- 1) {
246 for (o
= 0, i
= 0; o
< plugin
->numOutputs
; ++o
) {
248 memset (jvst
->outs
[o
], 0, sizeof (float) * nframes
);
253 } else if (jvst
->muted
) {
255 for (o
= 0, i
= 0; o
< plugin
->numOutputs
; ++o
) {
257 memset (jvst
->outs
[o
], 0, sizeof (float) * nframes
);
263 if (jvst
->midi_outport
) {
264 void *port_buffer
= jack_port_get_buffer(jvst
->midi_outport
, nframes
);
265 if (port_buffer
== NULL
) {
266 fst_error("jack_port_get_buffer failed, cannot send anything.");
269 jack_midi_clear_buffer(port_buffer
);
272 if (jvst
->midi_inport
) {
273 void *port_buffer
= jack_port_get_buffer( jvst
->midi_inport
, nframes
);
274 jack_nframes_t num_jackevents
= jack_midi_get_event_count( port_buffer
);
275 jack_midi_event_t jackevent
;
276 int j
,stuffed_events
= 0;
278 if( num_jackevents
>= MIDI_EVENT_MAX
)
279 num_jackevents
= MIDI_EVENT_MAX
;
281 for( i
=0; i
<num_jackevents
; i
++ ) {
282 if( jack_midi_event_get( &jackevent
, port_buffer
, i
) != 0 )
285 if( (jackevent
.buffer
[0] & 0xf0) == 0xb0 && jvst
->midi_learn
) {
286 jvst
->midi_learn_CC
= jackevent
.buffer
[1];
287 } else if( (jackevent
.buffer
[0] & 0xf0) == 0xb0 && jvst
->midi_map
[jackevent
.buffer
[1]] != -1 ) {
289 int parameter
= jvst
->midi_map
[jackevent
.buffer
[1]];
290 float value
= 1.0/127.0 * (float) jackevent
.buffer
[2];
291 plugin
->setParameter( plugin
, parameter
, value
);
293 } else if( jvst
->want_midi_in
) {
294 jvst
->event_array
[stuffed_events
].type
= kVstMidiType
;
295 jvst
->event_array
[stuffed_events
].byteSize
= 24;
296 jvst
->event_array
[stuffed_events
].deltaFrames
= jackevent
.time
;
298 for( j
=0; (j
<4); j
++ ) {
299 jvst
->event_array
[stuffed_events
].midiData
[j
] =
300 (j
<jackevent
.size
) ? jackevent
.buffer
[j
] : 0;
306 if( stuffed_events
> 0 ) {
307 jvst
->events
->numEvents
= stuffed_events
;
308 plugin
->dispatcher (plugin
, effProcessEvents
, 0, 0, jvst
->events
, 0.0f
);
312 current_program
= plugin
->dispatcher( plugin
, effGetProgram
, 0, 0, NULL
, 0.0f
);
313 if( current_program
>= 0 )
314 jvst
->current_program
= current_program
;
316 if (plugin
->flags
& effFlagsCanReplacing
) {
318 for (i
= 0; i
< plugin
->numOutputs
; ++i
) {
319 memset (jvst
->outs
[i
], 0, sizeof (float) * nframes
);
321 plugin
->processReplacing (plugin
, jvst
->ins
, jvst
->outs
, nframes
);
325 for (i
= 0; i
< plugin
->numOutputs
; ++i
) {
326 memset (jvst
->outs
[i
], 0, sizeof (float) * nframes
);
328 plugin
->process (plugin
, jvst
->ins
, jvst
->outs
, nframes
);
330 if (jvst
->midi_outport
) {
331 process_midi_output(jvst
, nframes
);
337 printf("got ladish save here\n");
338 fst_save_state (jvst
->fst
, ladish_state_filename
);
354 void create_argc_argv_from_cmdline( char *cmdline
, char *argv0
, int *argc
, char ***argv
) {
357 enum ParseMode parseMode
= MODE_WHITESPACE
;
358 enum ParseMode parseMode_before_ESC
= MODE_NORMAL
;
364 while( parseMode
!= MODE_EOL
) {
365 switch( parseMode
) {
369 parseMode
= MODE_DOUBLEQUOTE
;
372 parseMode
= MODE_QUOTE
;
375 parseMode_before_ESC
= parseMode
;
376 parseMode
= MODE_ESCAPED
;
378 case ' ': // First Space after an arg;
379 parseMode
= MODE_WHITESPACE
;
382 case 0: // EOL after arg.
383 parseMode
= MODE_EOL
;
393 parseMode
= MODE_NORMAL
;
396 parseMode_before_ESC
= parseMode
;
397 parseMode
= MODE_ESCAPED
;
400 fst_error( "parse Error on cmdline" );
401 parseMode
= MODE_EOL
;
408 case MODE_DOUBLEQUOTE
:
411 parseMode
= MODE_NORMAL
;
414 parseMode_before_ESC
= parseMode
;
415 parseMode
= MODE_ESCAPED
;
418 fst_error( "parse Error on cmdline" );
419 parseMode
= MODE_EOL
;
429 // emit escaped char;
430 parseMode
= parseMode_before_ESC
;
433 // emit escaped char;
434 parseMode
= parseMode_before_ESC
;
437 // emit escaped char;
438 parseMode
= parseMode_before_ESC
;
441 fst_error( "EOL after escape: ignored" );
442 parseMode
= MODE_EOL
;
445 fst_error( "Unknown Escapecharacter: ignored" );
446 parseMode
= parseMode_before_ESC
;
451 case MODE_WHITESPACE
:
454 parseMode
= MODE_DOUBLEQUOTE
;
458 parseMode
= MODE_QUOTE
;
462 parseMode_before_ESC
= MODE_NORMAL
;
463 parseMode
= MODE_ESCAPED
;
467 parseMode
= MODE_WHITESPACE
;
470 parseMode
= MODE_EOL
;
474 parseMode
= MODE_NORMAL
;
484 myargv
= malloc( myargc
* sizeof( char * ) );
486 fst_error( "cant alloc memory" );
490 // alloc strlen(cmdline) + 1 for each argv.
491 // this avoids another parsing pass.
492 for( i
=0; i
<myargc
; i
++ ) {
493 myargv
[i
] = malloc( strlen(cmdline
) + 1 );
495 fst_error( "cant alloc memory" );
501 // Now rerun theparser and actually emit chars.
503 parseMode
= MODE_WHITESPACE
;
504 parseMode_before_ESC
= MODE_NORMAL
;
506 char *emit_pos
= myargv
[0];
508 while( parseMode
!= MODE_EOL
) {
509 switch( parseMode
) {
513 parseMode
= MODE_DOUBLEQUOTE
;
516 parseMode
= MODE_QUOTE
;
519 parseMode_before_ESC
= parseMode
;
520 parseMode
= MODE_ESCAPED
;
522 case ' ': // First Space after an arg;
523 parseMode
= MODE_WHITESPACE
;
527 case 0: // EOL after arg.
528 parseMode
= MODE_EOL
;
533 *(emit_pos
++) = *pos
;
540 parseMode
= MODE_NORMAL
;
543 parseMode_before_ESC
= parseMode
;
544 parseMode
= MODE_ESCAPED
;
547 fst_error( "parse Error on cmdline" );
548 parseMode
= MODE_EOL
;
553 *(emit_pos
++) = *pos
;
557 case MODE_DOUBLEQUOTE
:
560 parseMode
= MODE_NORMAL
;
563 parseMode_before_ESC
= parseMode
;
564 parseMode
= MODE_ESCAPED
;
567 fst_error( "parse Error on cmdline" );
568 parseMode
= MODE_EOL
;
573 *(emit_pos
++) = *pos
;
580 // emit escaped char;
581 parseMode
= parseMode_before_ESC
;
582 *(emit_pos
++) = *pos
;
585 // emit escaped char;
586 parseMode
= parseMode_before_ESC
;
587 *(emit_pos
++) = *pos
;
590 // emit escaped char;
591 parseMode
= parseMode_before_ESC
;
592 *(emit_pos
++) = *pos
;
595 fst_error( "EOL after escape: ignored" );
596 parseMode
= MODE_EOL
;
600 fst_error( "Unknown Escapecharacter: ignored" );
601 parseMode
= parseMode_before_ESC
;
605 case MODE_WHITESPACE
:
608 parseMode
= MODE_DOUBLEQUOTE
;
611 emit_pos
= myargv
[current_arg
];
614 parseMode
= MODE_QUOTE
;
617 emit_pos
= myargv
[current_arg
];
620 parseMode_before_ESC
= MODE_NORMAL
;
621 parseMode
= MODE_ESCAPED
;
624 emit_pos
= myargv
[current_arg
];
627 parseMode
= MODE_WHITESPACE
;
630 parseMode
= MODE_EOL
;
633 parseMode
= MODE_NORMAL
;
636 emit_pos
= myargv
[current_arg
];
638 *(emit_pos
++) = *pos
;
646 strncpy( myargv
[0], argv0
, strlen(cmdline
) );
652 /* Plugin "canDo" helper function to neaten up plugin feature detection calls */
653 int canDo(struct AEffect
* plugin
, char* feature
)
655 return (plugin
->dispatcher(plugin
, effCanDo
, 0, 0, (void*)feature
, 0.0f
) > 0);
659 static void sig_ladish(int sig
)
661 printf("got SIGUSR1, saving state now...\n");
666 WinMain(HINSTANCE hInst
, HINSTANCE hPrevInst
, LPSTR cmdline
, int cmdshow
)
668 //main( int argc, char **argv )
671 struct AEffect
* plugin
;
673 char* client_name
= 0;
676 int resume_not_rt
= 1;
678 char * state_file
= 0;
682 float sample_rate
= 0;
690 memset(&sa
, 0, sizeof(sa
));
691 sa
.sa_handler
= sig_ladish
;
692 sigaction(SIGUSR1
, &sa
, NULL
);
695 create_argc_argv_from_cmdline( cmdline
, "./fst", &argc
, &argv
);
698 fprintf (stderr
, "usage: %s <ladish-state-filename> <plugin>\n", argv
[0]);
702 printf( "yo... lets see...\n" );
705 gui_init (&argc
, &argv
);
707 ladish_state_filename
= argv
[1];
709 if (open(ladish_state_filename
, O_RDONLY
) > 0) {
711 state_file
= ladish_state_filename
;
716 if (fst_init (hInst
)) {
720 jvst
= (JackVST
*) calloc (1, sizeof (JackVST
));
721 for (i
=0; i
<128; i
++ )
722 jvst
->midi_map
[i
] = -1;
724 client_name
= g_path_get_basename(strdup (plug
));
725 if ((period
= strrchr (client_name
, '.')) != NULL
) {
729 if ((jvst
->handle
= fst_load (plug
)) == NULL
) {
730 fst_error ("can't load plugin %s", plug
);
733 if ((jvst
->client
= jack_client_open (client_name
, JackNullOption
, NULL
)) == 0) {
734 fst_error ("can't connect to JACK");
738 printf( "instantiate... \n" );
740 if ((jvst
->fst
= fst_instantiate (jvst
->handle
, jack_host_callback
, jvst
)) == NULL
) {
741 fst_error ("can't instantiate plugin %s", plug
);
745 plugin
= jvst
->fst
->plugin
;
747 /* set rate and blocksize */
748 sample_rate
= (float)jack_get_sample_rate(jvst
->client
);
749 block_size
= jack_get_buffer_size(jvst
->client
);
751 printf("Sample Rate = %.2f\n", sample_rate
);
752 printf("Block Size = %ld\n", block_size
);
754 plugin
->dispatcher (plugin
, effSetSampleRate
, 0, 0, NULL
,
755 (float) jack_get_sample_rate (jvst
->client
));
756 plugin
->dispatcher (plugin
, effSetBlockSize
, 0,
757 jack_get_buffer_size (jvst
->client
), NULL
, 0.0f
);
760 /* set program to zero */
761 /* i comment this out because it breaks dfx Geometer
762 * looks like we cant set programs for it
765 * this might have been because we were not a real wine thread, but i doubt
768 * plugin->dispatcher (plugin, effSetProgram, 0, 0, NULL, 0.0f);
772 jvst
->midi_inport
= jack_port_register(jvst
->client
,
774 JACK_DEFAULT_MIDI_TYPE
,
778 vst_version
= plugin
->dispatcher (plugin
, effGetVstVersion
, 0, 0, NULL
, 0.0f
);
779 if (vst_version
>= 2) {
780 int isSynth
= (plugin
->flags
& effFlagsIsSynth
) > 0;
781 int canReceiveVstEvents
= canDo(plugin
, "receiveVstEvents");
782 int canReceiveVstMidiEvent
= canDo(plugin
, "receiveVstMidiEvent");
783 int canSendVstEvents
= canDo(plugin
, "sendVstEvents");
784 int canSendVstMidiEvent
= canDo(plugin
, "sendVstMidiEvent");
786 printf("Plugin isSynth = %d\n", isSynth
);
787 printf("Plugin canDo receiveVstEvents = %d\n", canReceiveVstEvents
);
788 printf("Plugin canDo receiveVstMidiEvent = %d\n", canReceiveVstMidiEvent
);
789 printf("Plugin canDo sendVstEvents = %d\n", canSendVstEvents
);
790 printf("Plugin canDo SendVstMidiEvent = %d\n", canSendVstMidiEvent
);
792 /* should we send the plugin VST events (i.e. MIDI) */
793 if (isSynth
|| canReceiveVstEvents
|| canReceiveVstMidiEvent
) {
795 jvst
->want_midi_in
= 1;
797 /* The VstEvents structure already contains an array of 2 */
798 /* pointers to VstEvent so I guess that this malloc actually */
799 /* gives enough space for MIDI_EVENT_MAX + 2 events.... */
800 jvst
->events
= (VstEvents
*)malloc(sizeof(VstEvents
) +
801 (MIDI_EVENT_MAX
* sizeof(VstMidiEvent
*)));
803 jvst
->events
->numEvents
= 0;
804 jvst
->events
->reserved
= 0;
806 /* Initialise dynamic array of MIDI_EVENT_MAX VstMidiEvents */
807 /* and point the VstEvents events array of pointers to it */
808 jvst
->event_array
= (VstMidiEvent
*)calloc(MIDI_EVENT_MAX
,
809 sizeof (VstMidiEvent
));
810 for (i
= 0; i
< MIDI_EVENT_MAX
; i
++) {
811 jvst
->events
->events
[i
] = (VstEvent
*)&(jvst
->event_array
[i
]);
815 /* Can the plugin send VST events (i.e. MIDI) */
816 if (canSendVstEvents
|| canSendVstMidiEvent
) {
817 jvst
->ringbuffer
= jack_ringbuffer_create(RINGBUFFER_SIZE
);
818 if (jvst
->ringbuffer
== NULL
) {
819 fst_error("Cannot create JACK ringbuffer.");
823 jack_ringbuffer_mlock(jvst
->ringbuffer
);
825 jvst
->midi_outport
= jack_port_register(jvst
->client
,
827 JACK_DEFAULT_MIDI_TYPE
,
833 printf("PortLayout: in: %d out: %d\n", plugin
->numInputs
, plugin
->numOutputs
);
835 jvst
->inports
= (jack_port_t
**)malloc(sizeof(jack_port_t
*) * plugin
->numInputs
);
836 jvst
->ins
= (float**)malloc(sizeof(float*) * plugin
->numInputs
);
838 for (i
= 0; i
< plugin
->numInputs
; ++i
) {
840 snprintf (buf
, sizeof(buf
), "in%d", i
+1);
841 jvst
->inports
[i
] = jack_port_register (jvst
->client
, buf
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
844 jvst
->outports
= (jack_port_t
**) malloc (sizeof(jack_port_t
*) * plugin
->numOutputs
);
845 jvst
->outs
= (float **) malloc (sizeof (float *) * plugin
->numOutputs
);
847 for (i
= 0; i
< plugin
->numOutputs
; ++i
) {
849 snprintf (buf
, sizeof(buf
), "out%d", i
+1);
850 jvst
->outports
[i
] = jack_port_register (jvst
->client
, buf
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
853 if( with_winaudio
) {
856 sem_init( &winaudio_activate
, 0, 0 );
857 sem_init( &winaudio_done
, 0, 0 );
859 audioThreadHandle
= CreateThread(0, 0, WinAudioThreadMain
, 0, 0, &threadId
);
860 if (!audioThreadHandle
) {
861 fst_error( "Failed to create audio thread!" );
864 // ok... this waits for the windows thread to get up in the first place.
865 sem_wait( &winaudio_done
);
866 printf( "created audio thread\n" );
867 jack_set_process_callback (jvst
->client
, (JackProcessCallback
) winaudio_process_callback
, jvst
);
870 jack_set_process_callback (jvst
->client
, (JackProcessCallback
) process_callback
, jvst
);
872 printf( "Calling Jack activate\n" );
873 jack_activate (jvst
->client
);
876 printf( "open Editor\n" );
878 if (fst_run_editor (jvst
->fst
)) {
879 fst_error ("cannot create editor");
883 printf( "no Editor\n" );
886 /* load state if requested */
889 if (!fst_load_state (jvst
->fst
, state_file
)) {
890 printf ("ERROR: Could not load state file %s\n", state_file
);
891 jack_deactivate( jvst
->client
);
892 if( with_winaudio
) {
893 printf( "Waiting for WinAudioThread to exit\n" );
895 CloseHandle( audioThreadHandle
);
902 printf( "Entering main loop\n" );
904 printf( "ok.... RockNRoll\n" );
905 manage_vst_plugin (jvst
);
911 jack_deactivate( jvst
->client
);
912 if( with_winaudio
) {
913 printf( "Waiting for WinAudioThread to exit\n" );
915 CloseHandle( audioThreadHandle
);