@@ -628,6 +628,134 @@ static int test_bind_channel(void) {
return 0 ;
}
/* test unbind */
static int test_bind_unbind ( void ) {
printf ( " Test: bind to channel 5, unbind, then toggle default (channel 0) \n " ) ;
pid_t pid = start_looper ( ) ;
if ( pid < 0 ) return 1 ;
jack_client_t * client ;
jack_status_t status ;
client = jack_client_open ( " test_unbind " , JackNoStartServer , & status ) ;
if ( ! client ) {
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " SKIP: no JACK \n " ) ;
return 1 ;
}
jack_port_t * audio_out = jack_port_register ( client , " out " ,
JACK_DEFAULT_AUDIO_TYPE ,
JackPortIsOutput , 0 ) ;
jack_port_t * audio_in = jack_port_register ( client , " in " ,
JACK_DEFAULT_AUDIO_TYPE ,
JackPortIsInput , 0 ) ;
if ( ! audio_out | | ! audio_in ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
return 1 ;
}
usleep ( 200000 ) ;
char my_out [ 64 ] , my_in [ 64 ] ;
snprintf ( my_out , sizeof ( my_out ) , " test_unbind:out " ) ;
snprintf ( my_in , sizeof ( my_in ) , " test_unbind:in " ) ;
if ( jack_connect ( client , my_out , " looper:input " ) | |
jack_connect ( client , " looper:output " , my_in ) ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
return 1 ;
}
/* Bind to channel 5 */
if ( send_jack_note_on ( " looper:control " , 64 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: send control key failed \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
if ( send_jack_note_on ( " looper:control " , 5 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: bind to 5 failed \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
/* Unbind (reset to 0) */
if ( send_jack_note_on ( " looper:control " , 64 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: control key for unbind \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
if ( send_jack_note_on ( " looper:control " , 63 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: send unbind note 63 failed \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
/* Now toggle with control+62 – should affect channel 0 */
if ( send_jack_note_on ( " looper:control " , 64 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: control key for toggle \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
if ( send_jack_note_on ( " looper:control " , 62 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: toggle note 62 \n " ) ;
return 1 ;
}
/* Wait for beep and loop */
int sr = jack_get_sample_rate ( client ) ;
continuous_sine = 0 ;
beep_remaining = ( int ) ( 0.1f * sr ) ;
bursts = 0 ;
prev_above = 0 ;
passthrough_output_port = audio_out ;
passthrough_input_port = audio_in ;
passthrough_phase = 0.0f ;
passthrough_freq = 440.0f ;
passthrough_sample_rate = sr ;
passthrough_total_samples = 0 ;
passthrough_sum_sq = 0.0 ;
passthrough_done = 0 ;
jack_set_process_callback ( client , passthrough_process , NULL ) ;
if ( jack_activate ( client ) ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
return 1 ;
}
usleep ( 200000 ) ; /* allow beep */
/* second control+62 -> loop */
if ( send_jack_note_on ( " looper:control " , 64 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: control key for loop \n " ) ;
return 1 ;
}
usleep ( 200000 ) ;
if ( send_jack_note_on ( " looper:control " , 62 , 127 ) ! = 0 ) {
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ; waitpid ( pid , NULL , 0 ) ;
fprintf ( stderr , " FAIL: toggle for loop \n " ) ;
return 1 ;
}
usleep ( 2000000 ) ;
jack_deactivate ( client ) ;
jack_client_close ( client ) ;
kill ( pid , SIGTERM ) ;
waitpid ( pid , NULL , 0 ) ;
int got_bursts = bursts ;
printf ( " detected bursts: %d \n " , got_bursts ) ;
if ( got_bursts < 3 ) {
fprintf ( stderr , " FAIL: expected >=3 bursts, got %d \n " , got_bursts ) ;
return 1 ;
}
printf ( " PASS (unbind works, toggle channel 0) \n " ) ;
return 0 ;
}
/* test remove channel */
static int test_remove_channel ( void ) {
printf ( " Test: dynamic channel removal via MIDI command \n " ) ;
@@ -738,7 +866,13 @@ int main(void) {
failures + + ;
}
/* 8. Test channel removal */
/* 8. Test unbind */
if ( test_bind_unbind ( ) ! = 0 ) {
fprintf ( stderr , " FAILED \n " ) ;
failures + + ;
}
/* 9. Test channel removal */
if ( test_remove_channel ( ) ! = 0 ) {
fprintf ( stderr , " FAILED \n " ) ;
failures + + ;