Fix some range errors in discrete control testing. Clean up a lot of formatting and
comments. Allow application to be started on virtual port for testing. Don't complain when invalid CC# is seen, just ignore and return silently. fg
This commit is contained in:
parent
3a7d73ef71
commit
6eeef8f0e2
4 changed files with 174 additions and 164 deletions
172
mustang.cpp
172
mustang.cpp
|
|
@ -113,10 +113,10 @@ Mustang::handleInput( void ) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
{
|
{
|
||||||
// Patch change acknowledge sequence done
|
// Patch change acknowledge sequence done
|
||||||
pthread_mutex_lock( &cc_ack_eom.lock );
|
pthread_mutex_lock( &pc_ack_sync.lock );
|
||||||
cc_ack_eom.value = true;
|
pc_ack_sync.value = true;
|
||||||
pthread_cond_signal( &cc_ack_eom.cond );
|
pthread_cond_signal( &pc_ack_sync.cond );
|
||||||
pthread_mutex_unlock( &cc_ack_eom.lock );
|
pthread_mutex_unlock( &pc_ack_sync.lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x04:
|
case 0x04:
|
||||||
|
|
@ -132,8 +132,6 @@ Mustang::handleInput( void ) {
|
||||||
// parm dump or when manual patch change occurs.
|
// parm dump or when manual patch change occurs.
|
||||||
curr_preset_idx = idx;
|
curr_preset_idx = idx;
|
||||||
|
|
||||||
// preset_names_sync.value = true;
|
|
||||||
// pthread_cond_signal( &preset_names_sync.cond );
|
|
||||||
pthread_mutex_unlock( &preset_names_sync.lock );
|
pthread_mutex_unlock( &preset_names_sync.lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -147,8 +145,6 @@ Mustang::handleInput( void ) {
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
updateAmpObj( read_buf );
|
updateAmpObj( read_buf );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -161,8 +157,6 @@ Mustang::handleInput( void ) {
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
updateStompObj( read_buf );
|
updateStompObj( read_buf );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -175,8 +169,6 @@ Mustang::handleInput( void ) {
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
updateModObj( read_buf );
|
updateModObj( read_buf );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -189,8 +181,6 @@ Mustang::handleInput( void ) {
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
updateDelayObj( read_buf );
|
updateDelayObj( read_buf );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -203,8 +193,6 @@ Mustang::handleInput( void ) {
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
updateReverbObj( read_buf );
|
updateReverbObj( read_buf );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -216,8 +204,6 @@ Mustang::handleInput( void ) {
|
||||||
|
|
||||||
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
memcpy( dsp_parms[idx], (const char *)read_buf, 64 );
|
||||||
|
|
||||||
// dsp_sync[idx].value = true;
|
|
||||||
// pthread_cond_signal( &dsp_sync[idx].cond );
|
|
||||||
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
pthread_mutex_unlock( &dsp_sync[idx].lock );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -537,44 +523,44 @@ Mustang::updateAmpObj( const unsigned char *data ) {
|
||||||
|
|
||||||
const unsigned char *model = data + MODEL;
|
const unsigned char *model = data + MODEL;
|
||||||
|
|
||||||
if ( is_type(f57_deluxe_id,model) ||
|
if ( match16(f57_deluxe_id,model) ||
|
||||||
is_type(f57_champ_id,model) ||
|
match16(f57_champ_id,model) ||
|
||||||
is_type(f65_deluxe_id,model) ||
|
match16(f65_deluxe_id,model) ||
|
||||||
is_type(f65_princeton_id,model) ||
|
match16(f65_princeton_id,model) ||
|
||||||
is_type(f65_twin_id,model) ||
|
match16(f65_twin_id,model) ||
|
||||||
is_type(s60s_thrift_id,model) ) {
|
match16(s60s_thrift_id,model) ) {
|
||||||
new_amp = new AmpCC( this, model, 0 );
|
new_amp = new AmpCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(f59_bassman_id,model) ||
|
else if ( match16(f59_bassman_id,model) ||
|
||||||
is_type(brit_70s_id,model) ) {
|
match16(brit_70s_id,model) ) {
|
||||||
new_amp = new AmpCC1( this, model, 0 );
|
new_amp = new AmpCC1( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(f_supersonic_id,model) ) {
|
else if ( match16(f_supersonic_id,model) ) {
|
||||||
new_amp = new AmpCC2( this, model, 0 );
|
new_amp = new AmpCC2( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(brit_60s_id,model) ) {
|
else if ( match16(brit_60s_id,model) ) {
|
||||||
new_amp = new AmpCC3( this, model, 0);
|
new_amp = new AmpCC3( this, model, 0);
|
||||||
}
|
}
|
||||||
else if ( is_type(brit_80s_id,model) ||
|
else if ( match16(brit_80s_id,model) ||
|
||||||
is_type(us_90s_id,model) ||
|
match16(us_90s_id,model) ||
|
||||||
is_type(metal_2k_id,model) ||
|
match16(metal_2k_id,model) ||
|
||||||
is_type(brit_watt_id,model) ) {
|
match16(brit_watt_id,model) ) {
|
||||||
new_amp = new AmpCC4( this, model, 0 );
|
new_amp = new AmpCC4( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(studio_preamp_id,model) ) {
|
else if ( match16(studio_preamp_id,model) ) {
|
||||||
new_amp = new AmpCC5( this, model, 0 );
|
new_amp = new AmpCC5( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(brit_color_id,model) ) {
|
else if ( match16(brit_color_id,model) ) {
|
||||||
new_amp = new AmpCC6( this, model, 0 );
|
new_amp = new AmpCC6( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(f57_twin_id,model) ) {
|
else if ( match16(f57_twin_id,model) ) {
|
||||||
new_amp = new AmpCC7( this, model, 0 );
|
new_amp = new AmpCC7( this, model, 0 );
|
||||||
}
|
}
|
||||||
else if ( is_type(null_amp_id,model) ) {
|
else if ( match16(null_amp_id,model) ) {
|
||||||
new_amp = new NullAmpCC( this, model, 0 );
|
new_amp = new NullAmpCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Amp id {%x,%x} not supported yet\n", model[0], model[1] );
|
fprintf( stderr, "W - Amp id {%x,%x} not expected\n", model[0], model[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( new_amp!=NULL ) {
|
if ( new_amp!=NULL ) {
|
||||||
|
|
@ -648,12 +634,10 @@ Mustang::setAmp( int ord ) {
|
||||||
buffer = brit_color;
|
buffer = brit_color;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "W - Amp select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Amp select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -673,7 +657,8 @@ Mustang::ampControl( int cc, int value ) {
|
||||||
int rc = curr_amp->dispatch( cc, value, cmd );
|
int rc = curr_amp->dispatch( cc, value, cmd );
|
||||||
pthread_mutex_unlock( &dsp_sync[AMP_STATE].lock );
|
pthread_mutex_unlock( &dsp_sync[AMP_STATE].lock );
|
||||||
|
|
||||||
if ( rc<0 ) return rc;
|
// If value out-of-range, just return gracefully
|
||||||
|
if ( rc<0 ) return 0;
|
||||||
rc = direct_control( cmd );
|
rc = direct_control( cmd );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -687,45 +672,45 @@ Mustang::updateStompObj( const unsigned char *data ) {
|
||||||
const unsigned char *model = data + MODEL;
|
const unsigned char *model = data + MODEL;
|
||||||
const unsigned char slot = data[FXSLOT];
|
const unsigned char slot = data[FXSLOT];
|
||||||
|
|
||||||
if ( is_type(overdrive_id,model) ) {
|
if ( match16(overdrive_id,model) ) {
|
||||||
new_stomp = new OverdriveCC( this, model, slot );
|
new_stomp = new OverdriveCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(wah_id,model) ||
|
else if ( match16(wah_id,model) ||
|
||||||
is_type(touch_wah_id,model) ) {
|
match16(touch_wah_id,model) ) {
|
||||||
new_stomp = new WahCC( this, model, slot );
|
new_stomp = new WahCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(fuzz_id,model) ) {
|
else if ( match16(fuzz_id,model) ) {
|
||||||
new_stomp = new FuzzCC( this, model, slot );
|
new_stomp = new FuzzCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(fuzz_twah_id,model) ) {
|
else if ( match16(fuzz_twah_id,model) ) {
|
||||||
new_stomp = new FuzzTouchWahCC( this, model, slot );
|
new_stomp = new FuzzTouchWahCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(simple_comp_id,model) ) {
|
else if ( match16(simple_comp_id,model) ) {
|
||||||
new_stomp = new SimpleCompCC( this, model, slot );
|
new_stomp = new SimpleCompCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(comp_id,model) ) {
|
else if ( match16(comp_id,model) ) {
|
||||||
new_stomp = new CompCC( this, model, slot );
|
new_stomp = new CompCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(range_boost_id,model) ) {
|
else if ( match16(range_boost_id,model) ) {
|
||||||
new_stomp = new RangerCC( this, model, slot );
|
new_stomp = new RangerCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(green_box_id,model) ) {
|
else if ( match16(green_box_id,model) ) {
|
||||||
new_stomp = new GreenBoxCC( this, model, slot );
|
new_stomp = new GreenBoxCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(orange_box_id,model) ) {
|
else if ( match16(orange_box_id,model) ) {
|
||||||
new_stomp = new OrangeBoxCC( this, model, slot );
|
new_stomp = new OrangeBoxCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(black_box_id,model) ) {
|
else if ( match16(black_box_id,model) ) {
|
||||||
new_stomp = new BlackBoxCC( this, model, slot );
|
new_stomp = new BlackBoxCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(big_fuzz_id,model) ) {
|
else if ( match16(big_fuzz_id,model) ) {
|
||||||
new_stomp = new BigFuzzCC( this, model, slot );
|
new_stomp = new BigFuzzCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(null_stomp_id,model) ) {
|
else if ( match16(null_stomp_id,model) ) {
|
||||||
new_stomp = new NullStompCC( this, model, 0 );
|
new_stomp = new NullStompCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Stomp id {%x,%x} not supported\n", model[0], model[1] );
|
fprintf( stderr, "W - Stomp id {%x,%x} not expected\n", model[0], model[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( new_stomp!=NULL ) {
|
if ( new_stomp!=NULL ) {
|
||||||
|
|
@ -759,7 +744,6 @@ Mustang::setStomp( int ord ) {
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if ( isV2 ) {
|
if ( isV2 ) {
|
||||||
fprintf( stderr, "W - Stomp select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -791,12 +775,10 @@ Mustang::setStomp( int ord ) {
|
||||||
buffer = big_fuzz;
|
buffer = big_fuzz;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "W - Stomp select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Stomp select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -820,7 +802,7 @@ Mustang::stompControl( int cc, int value ) {
|
||||||
int rc = curr_stomp->dispatch( cc, value, cmd );
|
int rc = curr_stomp->dispatch( cc, value, cmd );
|
||||||
pthread_mutex_unlock( &dsp_sync[STOMP_STATE].lock );
|
pthread_mutex_unlock( &dsp_sync[STOMP_STATE].lock );
|
||||||
|
|
||||||
if ( rc<0 ) return rc;
|
if ( rc<0 ) return 0;
|
||||||
rc = direct_control( cmd );
|
rc = direct_control( cmd );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -834,45 +816,45 @@ Mustang::updateModObj( const unsigned char *data ) {
|
||||||
const unsigned char *model = data + MODEL;
|
const unsigned char *model = data + MODEL;
|
||||||
const unsigned char slot = data[FXSLOT];
|
const unsigned char slot = data[FXSLOT];
|
||||||
|
|
||||||
if ( is_type(sine_chorus_id,model) ||
|
if ( match16(sine_chorus_id,model) ||
|
||||||
is_type(tri_chorus_id,model) ) {
|
match16(tri_chorus_id,model) ) {
|
||||||
new_mod = new ChorusCC( this, model, slot );
|
new_mod = new ChorusCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(sine_flange_id,model) ||
|
else if ( match16(sine_flange_id,model) ||
|
||||||
is_type(tri_flange_id,model) ) {
|
match16(tri_flange_id,model) ) {
|
||||||
new_mod = new FlangerCC( this, model, slot );
|
new_mod = new FlangerCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(vibratone_id,model) ) {
|
else if ( match16(vibratone_id,model) ) {
|
||||||
new_mod = new VibratoneCC( this, model, slot );
|
new_mod = new VibratoneCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(vint_trem_id,model) ||
|
else if ( match16(vint_trem_id,model) ||
|
||||||
is_type(sine_trem_id,model) ) {
|
match16(sine_trem_id,model) ) {
|
||||||
new_mod = new TremCC( this, model, slot );
|
new_mod = new TremCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(ring_mod_id,model) ) {
|
else if ( match16(ring_mod_id,model) ) {
|
||||||
new_mod = new RingModCC( this, model, slot );
|
new_mod = new RingModCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(step_filt_id,model) ) {
|
else if ( match16(step_filt_id,model) ) {
|
||||||
new_mod = new StepFilterCC( this, model, slot );
|
new_mod = new StepFilterCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(phaser_id,model) ) {
|
else if ( match16(phaser_id,model) ) {
|
||||||
new_mod = new PhaserCC( this, model, slot );
|
new_mod = new PhaserCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(pitch_shift_id,model) ) {
|
else if ( match16(pitch_shift_id,model) ) {
|
||||||
new_mod = new PitchShifterCC( this, model, slot );
|
new_mod = new PitchShifterCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(m_wah_id,model) ||
|
else if ( match16(m_wah_id,model) ||
|
||||||
is_type(m_touch_wah_id,model) ) {
|
match16(m_touch_wah_id,model) ) {
|
||||||
new_mod = new ModWahCC( this, model, slot );
|
new_mod = new ModWahCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(dia_pitch_id,model) ) {
|
else if ( match16(dia_pitch_id,model) ) {
|
||||||
new_mod = new DiatonicShiftCC( this, model, slot );
|
new_mod = new DiatonicShiftCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(null_mod_id,model) ) {
|
else if ( match16(null_mod_id,model) ) {
|
||||||
new_mod = new NullModCC( this, model, 0 );
|
new_mod = new NullModCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Mod id {%x,%x} not supported\n", model[0], model[1] );
|
fprintf( stderr, "W - Mod id {%x,%x} not expected\n", model[0], model[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( new_mod!=NULL ) {
|
if ( new_mod!=NULL ) {
|
||||||
|
|
@ -937,12 +919,10 @@ Mustang::setMod( int ord ) {
|
||||||
buffer = diatonic_pitch_shift;
|
buffer = diatonic_pitch_shift;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "W - Mod select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Mod select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -966,7 +946,7 @@ Mustang::modControl( int cc, int value ) {
|
||||||
int rc = curr_mod->dispatch( cc, value, cmd );
|
int rc = curr_mod->dispatch( cc, value, cmd );
|
||||||
pthread_mutex_unlock( &dsp_sync[MOD_STATE].lock );
|
pthread_mutex_unlock( &dsp_sync[MOD_STATE].lock );
|
||||||
|
|
||||||
if ( rc<0 ) return rc;
|
if ( rc<0 ) return 0;
|
||||||
rc = direct_control( cmd );
|
rc = direct_control( cmd );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -980,36 +960,36 @@ Mustang::updateDelayObj( const unsigned char *data ) {
|
||||||
const unsigned char *model = data + MODEL;
|
const unsigned char *model = data + MODEL;
|
||||||
const unsigned char slot = data[FXSLOT];
|
const unsigned char slot = data[FXSLOT];
|
||||||
|
|
||||||
if ( is_type(mono_dly_id,model) ) {
|
if ( match16(mono_dly_id,model) ) {
|
||||||
new_delay = new MonoDelayCC( this, model, slot );
|
new_delay = new MonoDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(mono_filter_id,model) ||
|
else if ( match16(mono_filter_id,model) ||
|
||||||
is_type(st_filter_id,model) ) {
|
match16(st_filter_id,model) ) {
|
||||||
new_delay = new EchoFilterCC( this, model, slot );
|
new_delay = new EchoFilterCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(mtap_dly_id,model) ) {
|
else if ( match16(mtap_dly_id,model) ) {
|
||||||
new_delay = new MultitapDelayCC( this, model, slot );
|
new_delay = new MultitapDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(pong_dly_id,model) ) {
|
else if ( match16(pong_dly_id,model) ) {
|
||||||
new_delay = new PingPongDelayCC( this, model, slot );
|
new_delay = new PingPongDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(duck_dly_id,model) ) {
|
else if ( match16(duck_dly_id,model) ) {
|
||||||
new_delay = new DuckingDelayCC( this, model, slot );
|
new_delay = new DuckingDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(reverse_dly_id,model) ) {
|
else if ( match16(reverse_dly_id,model) ) {
|
||||||
new_delay = new ReverseDelayCC( this, model, slot );
|
new_delay = new ReverseDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(tape_dly_id,model) ) {
|
else if ( match16(tape_dly_id,model) ) {
|
||||||
new_delay = new TapeDelayCC( this, model, slot );
|
new_delay = new TapeDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(st_tape_dly_id,model) ) {
|
else if ( match16(st_tape_dly_id,model) ) {
|
||||||
new_delay = new StereoTapeDelayCC( this, model, slot );
|
new_delay = new StereoTapeDelayCC( this, model, slot );
|
||||||
}
|
}
|
||||||
else if ( is_type(null_dly_id,model) ) {
|
else if ( match16(null_dly_id,model) ) {
|
||||||
new_delay = new NullDelayCC( this, model, 0 );
|
new_delay = new NullDelayCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "W - Delay id {%x,%x} not supported\n", model[0], model[1] );
|
fprintf( stderr, "W - Delay id {%x,%x} not expected\n", model[0], model[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( new_delay!=NULL ) {
|
if ( new_delay!=NULL ) {
|
||||||
|
|
@ -1056,7 +1036,6 @@ Mustang::setDelay( int ord ) {
|
||||||
buffer = stereo_tape_delay;
|
buffer = stereo_tape_delay;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "W - Delay select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1079,7 +1058,7 @@ Mustang::delayControl( int cc, int value ) {
|
||||||
int rc = curr_delay->dispatch( cc, value, cmd );
|
int rc = curr_delay->dispatch( cc, value, cmd );
|
||||||
pthread_mutex_unlock( &dsp_sync[DELAY_STATE].lock );
|
pthread_mutex_unlock( &dsp_sync[DELAY_STATE].lock );
|
||||||
|
|
||||||
if ( rc<0 ) return rc;
|
if ( rc<0 ) return 0;
|
||||||
rc = direct_control( cmd );
|
rc = direct_control( cmd );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1093,7 +1072,7 @@ Mustang::updateReverbObj( const unsigned char *data ) {
|
||||||
|
|
||||||
delete curr_reverb;
|
delete curr_reverb;
|
||||||
|
|
||||||
if ( is_type(null_reverb_id,model) ) {
|
if ( match16(null_reverb_id,model) ) {
|
||||||
curr_reverb = new NullReverbCC( this, model, 0 );
|
curr_reverb = new NullReverbCC( this, model, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -1142,7 +1121,6 @@ Mustang::setReverb( int ord ) {
|
||||||
buffer = spring_65;
|
buffer = spring_65;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "W - Reverb select %d not supported\n", ord );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1165,7 +1143,7 @@ Mustang::reverbControl( int cc, int value ) {
|
||||||
int rc = curr_reverb->dispatch( cc, value, cmd );
|
int rc = curr_reverb->dispatch( cc, value, cmd );
|
||||||
pthread_mutex_unlock( &dsp_sync[REVERB_STATE].lock );
|
pthread_mutex_unlock( &dsp_sync[REVERB_STATE].lock );
|
||||||
|
|
||||||
if ( rc<0 ) return rc;
|
if ( rc<0 ) return 0;
|
||||||
rc = direct_control( cmd );
|
rc = direct_control( cmd );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1270,13 +1248,13 @@ Mustang::patchChange( int patch ) {
|
||||||
|
|
||||||
////// Critical Section
|
////// Critical Section
|
||||||
//
|
//
|
||||||
pthread_mutex_lock( &cc_ack_eom.lock );
|
pthread_mutex_lock( &pc_ack_sync.lock );
|
||||||
|
|
||||||
cc_ack_eom.value = false;
|
pc_ack_sync.value = false;
|
||||||
int rc = sendCmd( buffer );
|
int rc = sendCmd( buffer );
|
||||||
while ( rc==0 && ! cc_ack_eom.value ) pthread_cond_wait( &cc_ack_eom.cond, &cc_ack_eom.lock );
|
while ( rc==0 && ! pc_ack_sync.value ) pthread_cond_wait( &pc_ack_sync.cond, &pc_ack_sync.lock );
|
||||||
|
|
||||||
pthread_mutex_unlock( &cc_ack_eom.lock );
|
pthread_mutex_unlock( &pc_ack_sync.lock );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf( stderr, "DEBUG: Leaving patch change\n" );
|
fprintf( stderr, "DEBUG: Leaving patch change\n" );
|
||||||
|
|
|
||||||
53
mustang.h
53
mustang.h
|
|
@ -23,12 +23,15 @@ class StompCC;
|
||||||
|
|
||||||
class Mustang {
|
class Mustang {
|
||||||
|
|
||||||
|
// Pre-built 'execute' command
|
||||||
unsigned char execute[64];
|
unsigned char execute[64];
|
||||||
|
|
||||||
libusb_device_handle *usb_io;
|
libusb_device_handle *usb_io;
|
||||||
|
|
||||||
|
// USB listen thread
|
||||||
pthread_t worker;
|
pthread_t worker;
|
||||||
|
|
||||||
|
// Shutdown request flag
|
||||||
pthread_mutex_t shutdown_lock = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t shutdown_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
bool want_shutdown;
|
bool want_shutdown;
|
||||||
|
|
||||||
|
|
@ -44,6 +47,13 @@ class Mustang {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Identify patch-change ack / DSP parm update
|
||||||
|
static const unsigned char state_prefix[];
|
||||||
|
|
||||||
|
// Received {0x1c, 0x01, 0x00, ...}
|
||||||
|
// --> End of preset select acknowledge stream
|
||||||
|
Condition<bool> pc_ack_sync;
|
||||||
|
|
||||||
// Synchronize access to preset names
|
// Synchronize access to preset names
|
||||||
Condition<bool> preset_names_sync;
|
Condition<bool> preset_names_sync;
|
||||||
char preset_names[100][33];
|
char preset_names[100][33];
|
||||||
|
|
@ -51,39 +61,39 @@ class Mustang {
|
||||||
// Index to current preset
|
// Index to current preset
|
||||||
unsigned curr_preset_idx;
|
unsigned curr_preset_idx;
|
||||||
|
|
||||||
// Identify DSP-specific response family
|
// Manage access to each DSP data block and/or associated object.
|
||||||
static const unsigned char state_prefix[];
|
|
||||||
|
|
||||||
// Manage access to each DSP block and/of associated
|
|
||||||
// object.
|
|
||||||
Condition<bool> dsp_sync[6];
|
Condition<bool> dsp_sync[6];
|
||||||
unsigned char dsp_parms[6][64];
|
unsigned char dsp_parms[6][64];
|
||||||
|
|
||||||
// Received {0x1c, 0x01, 0x00, ...}
|
// Manage data and behavior for specific DSP models
|
||||||
// --> End of preset select acknowledge stream
|
AmpCC * curr_amp;
|
||||||
Condition<bool> cc_ack_eom;
|
StompCC * curr_stomp;
|
||||||
|
ModCC * curr_mod;
|
||||||
|
DelayCC * curr_delay;
|
||||||
|
ReverbCC * curr_reverb;
|
||||||
|
|
||||||
|
// Synchronize on end of parm dump
|
||||||
|
Condition<bool> parm_read_sync;
|
||||||
|
static const unsigned char parm_read_ack[];
|
||||||
|
|
||||||
|
// Synchronize on receipt of direct control acknowledge
|
||||||
|
Condition<bool> cc_ack_sync;
|
||||||
|
static const unsigned char cc_ack[];
|
||||||
|
|
||||||
// Received {0x00, 0x00, 0x19, ... }
|
// Received {0x00, 0x00, 0x19, ... }
|
||||||
// --> Acknowledge efx on/off toggle
|
// --> Acknowledge efx on/off toggle
|
||||||
Condition<bool> efx_toggle_sync;
|
Condition<bool> efx_toggle_sync;
|
||||||
static const unsigned char efx_toggle_ack[];
|
static const unsigned char efx_toggle_ack[];
|
||||||
|
|
||||||
// Synchronize on end of parm dump
|
|
||||||
Condition<bool> parm_read_sync;
|
|
||||||
static const unsigned char parm_read_ack[];
|
|
||||||
|
|
||||||
// Synchronize on receipt of model change acknowledge
|
// Synchronize on receipt of model change acknowledge
|
||||||
Condition<bool> model_change_sync;
|
Condition<bool> model_change_sync;
|
||||||
static const unsigned char model_change_ack[];
|
static const unsigned char model_change_ack[];
|
||||||
|
|
||||||
// Synchronize on receipt of direct control acknowledge
|
|
||||||
Condition<bool> cc_ack_sync;
|
|
||||||
static const unsigned char cc_ack[];
|
|
||||||
|
|
||||||
// Sync on tuner on/off ack
|
// Sync on tuner on/off ack
|
||||||
Condition<bool> tuner_ack_sync;
|
Condition<bool> tuner_ack_sync;
|
||||||
static const unsigned char tuner_ack[];
|
static const unsigned char tuner_ack[];
|
||||||
|
|
||||||
|
// Attached device probe structure
|
||||||
struct usb_id {
|
struct usb_id {
|
||||||
// product id
|
// product id
|
||||||
int pid;
|
int pid;
|
||||||
|
|
@ -93,17 +103,9 @@ class Mustang {
|
||||||
bool isV2;
|
bool isV2;
|
||||||
};
|
};
|
||||||
|
|
||||||
// For device probe
|
|
||||||
static const usb_id amp_ids[];
|
static const usb_id amp_ids[];
|
||||||
bool isV2;
|
bool isV2;
|
||||||
|
|
||||||
AmpCC * curr_amp;
|
|
||||||
|
|
||||||
StompCC * curr_stomp;
|
|
||||||
ModCC * curr_mod;
|
|
||||||
DelayCC * curr_delay;
|
|
||||||
ReverbCC * curr_reverb;
|
|
||||||
|
|
||||||
static void *threadStarter( void * );
|
static void *threadStarter( void * );
|
||||||
void handleInput( void );
|
void handleInput( void );
|
||||||
|
|
||||||
|
|
@ -121,7 +123,8 @@ class Mustang {
|
||||||
|
|
||||||
int checkOrDisableTuner( void );
|
int checkOrDisableTuner( void );
|
||||||
|
|
||||||
inline bool is_type(const unsigned char *a, const unsigned char *b) {
|
// Check for equality of 2-byte values
|
||||||
|
inline bool match16(const unsigned char *a, const unsigned char *b) {
|
||||||
return ( 0==memcmp(a,b,2) );
|
return ( 0==memcmp(a,b,2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -116,30 +115,54 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void errorcallback( RtError::Type type, const std::string & detail, void *userData ) {
|
|
||||||
// std::cout << "Error: Code = " << type << ", Msg: " << detail << "\n";
|
|
||||||
// }
|
|
||||||
|
|
||||||
void usage() {
|
void usage() {
|
||||||
fprintf( stderr, "Usage: mustang_midi <controller_port#> <midi_channel#>\n" );
|
const char msg[] =
|
||||||
fprintf( stderr, " port = 0..n, channel = 1..16\n" );
|
"Usage: mustang_midi <controller_port#> <midi_channel#>\n"
|
||||||
|
" mustang_midi <virtual_port> <midi_channel#>\n\n"
|
||||||
|
|
||||||
exit( 1 );
|
" port = 0..n, channel = 1..16\n";
|
||||||
|
|
||||||
|
fprintf( stderr, msg );
|
||||||
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, const char **argv ) {
|
int main( int argc, const char **argv ) {
|
||||||
if ( argc != 3 ) usage();
|
if ( argc != 3 ) usage();
|
||||||
|
|
||||||
|
RtMidiIn input_handler;
|
||||||
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
errno = 0;
|
|
||||||
int port = (int) strtol( argv[1], &endptr, 10 );
|
int port = (int) strtol( argv[1], &endptr, 10 );
|
||||||
if ( endptr == argv[0] ) usage();
|
if ( endptr == argv[0] ) {
|
||||||
if ( port < 0 ) usage();
|
try {
|
||||||
|
input_handler.openVirtualPort( argv[2] );
|
||||||
|
}
|
||||||
|
catch ( RtError &error ) {
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( port < 0 ) usage();
|
||||||
|
try {
|
||||||
|
input_handler.openPort( port );
|
||||||
|
}
|
||||||
|
catch ( RtError &error ) {
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
channel = (int) strtol( argv[2], &endptr, 10 ) - 1;
|
channel = (int) strtol( argv[2], &endptr, 10 ) - 1;
|
||||||
if ( endptr == argv[0] ) usage();
|
if ( endptr == argv[0] ) usage();
|
||||||
if ( channel < 0 || channel > 15 ) usage();
|
if ( channel < 0 || channel > 15 ) usage();
|
||||||
|
|
||||||
|
input_handler.setCallback( &message_action );
|
||||||
|
|
||||||
|
// Don't want sysex, timing, active sense
|
||||||
|
input_handler.ignoreTypes( true, true, true );
|
||||||
|
|
||||||
if ( 0 != mustang.initialize() ) {
|
if ( 0 != mustang.initialize() ) {
|
||||||
fprintf( stderr, "Cannot setup USB communication\n" );
|
fprintf( stderr, "Cannot setup USB communication\n" );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
|
|
@ -149,22 +172,6 @@ int main( int argc, const char **argv ) {
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
RtMidiIn *input_handler = new RtMidiIn();
|
|
||||||
|
|
||||||
// See if we have any ports
|
|
||||||
unsigned int num_ports = input_handler->getPortCount();
|
|
||||||
if ( num_ports == 0 ) {
|
|
||||||
std::cout << "Cannot find a MIDI port\n";
|
|
||||||
delete input_handler;
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
input_handler->openPort( port );
|
|
||||||
// input_handler->openVirtualPort( "TestPort" );
|
|
||||||
input_handler->setCallback( &message_action );
|
|
||||||
|
|
||||||
// Don't want sysex, timing, active sense
|
|
||||||
input_handler->ignoreTypes( true, true, true );
|
|
||||||
|
|
||||||
// Block and wait for signal
|
// Block and wait for signal
|
||||||
pause();
|
pause();
|
||||||
|
|
||||||
|
|
|
||||||
54
test.py
54
test.py
|
|
@ -1,10 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
# Use aconnectgui to wire Midi Through Port-0 out to
|
|
||||||
# mustang bridge virtual input port name
|
|
||||||
|
|
||||||
# OR
|
|
||||||
|
|
||||||
# hirsch@z87:~$ aconnect -o
|
# hirsch@z87:~$ aconnect -o
|
||||||
# client 14: 'Midi Through' [type=kernel]
|
# client 14: 'Midi Through' [type=kernel]
|
||||||
# 0 'Midi Through Port-0'
|
# 0 'Midi Through Port-0'
|
||||||
|
|
@ -12,8 +7,6 @@
|
||||||
# 0 'TestPort '
|
# 0 'TestPort '
|
||||||
#
|
#
|
||||||
# Given the above, open RtMidi as: 'RtMidi Input Client 128:0'
|
# Given the above, open RtMidi as: 'RtMidi Input Client 128:0'
|
||||||
#
|
|
||||||
# outport = mido.open_output('Midi Through 14:0')
|
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -130,6 +123,7 @@ def run_delay_test( struct, outport ):
|
||||||
|
|
||||||
for i in range( 0, len(struct) ):
|
for i in range( 0, len(struct) ):
|
||||||
control_rec = struct[i]
|
control_rec = struct[i]
|
||||||
|
# Skip if not a V2 amp
|
||||||
if control_rec[3] and type != 2:
|
if control_rec[3] and type != 2:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -255,11 +249,32 @@ def program_change_test( outport ):
|
||||||
outport.send( pc )
|
outport.send( pc )
|
||||||
sleep( 0.5 )
|
sleep( 0.5 )
|
||||||
|
|
||||||
|
def tuner_test( outport ):
|
||||||
|
raw_input( "Hit ENTER to select tuner...\n" )
|
||||||
|
cc.control = 20
|
||||||
|
cc.value = 127
|
||||||
|
outport.send( cc )
|
||||||
|
raw_input( "Hit ENTER to deselect tuner...\n" )
|
||||||
|
cc.value = 0
|
||||||
|
outport.send( cc )
|
||||||
|
|
||||||
|
def bypass_test( outport ):
|
||||||
|
raw_input( "Hit ENTER to select all effects...\n" )
|
||||||
|
cc.control = 22
|
||||||
|
cc.value = 127
|
||||||
|
outport.send( cc )
|
||||||
|
raw_input( "Hit ENTER to bypass all effects...\n" )
|
||||||
|
cc.value = 0
|
||||||
|
outport.send( cc )
|
||||||
|
|
||||||
|
|
||||||
|
###################### main ########################
|
||||||
|
|
||||||
args = sys.argv
|
args = sys.argv
|
||||||
|
|
||||||
if len(args) < 4:
|
if len(args) < 4:
|
||||||
print "Usage: test.py <virtual_port_name> <midi_channel> <v1|v2> [test_name]\n"
|
print "Usage: test.py <controller_port> <midi_channel> <v1|v2> [test_name]\n"
|
||||||
print " Pass test name in {pc, stomp, mod, reverb, delay, amp} for single test\n"
|
print " Pass test name in {pc, tuner, efxbypass, stomp, mod, reverb, delay, amp} for single test\n"
|
||||||
print " Default is to run all of them if no arg 4 passed\n"
|
print " Default is to run all of them if no arg 4 passed\n"
|
||||||
sys.exit( 1 )
|
sys.exit( 1 )
|
||||||
|
|
||||||
|
|
@ -286,8 +301,14 @@ outport = mido.open_output( args[1] )
|
||||||
if single == "all" or single == "pc":
|
if single == "all" or single == "pc":
|
||||||
program_change_test( outport )
|
program_change_test( outport )
|
||||||
|
|
||||||
|
if single == "all" or single == "tuner":
|
||||||
|
tuner_test( outport )
|
||||||
|
|
||||||
|
if single == "all" or single == "efxbypass":
|
||||||
|
bypass_test( outport )
|
||||||
|
|
||||||
if single == "all" or single == "stomp":
|
if single == "all" or single == "stomp":
|
||||||
# Model # Ctrl v2only
|
# Model Ctrl v2only
|
||||||
stomp_test = (
|
stomp_test = (
|
||||||
( "Ranger Boost", 8, "AAAA", True ),
|
( "Ranger Boost", 8, "AAAA", True ),
|
||||||
( "Green Box", 9, "AAAA", True ),
|
( "Green Box", 9, "AAAA", True ),
|
||||||
|
|
@ -303,11 +324,11 @@ if single == "all" or single == "stomp":
|
||||||
run_stomp_test( stomp_test, outport )
|
run_stomp_test( stomp_test, outport )
|
||||||
|
|
||||||
if single == "all" or single == "mod":
|
if single == "all" or single == "mod":
|
||||||
# Model # Ctrl v2only
|
# Model Ctrl v2only
|
||||||
mod_test = (
|
mod_test = (
|
||||||
( "Wah", 12, "AAAAD02", True ),
|
( "Wah", 12, "AAAAD01", True ),
|
||||||
( "Touch Wah", 13, "AAAAD02", True ),
|
( "Touch Wah", 13, "AAAAD01", True ),
|
||||||
( "Dia Shift", 14, "AD22D12D09A", True ),
|
( "Dia Shift", 14, "AD21D11D08A", True ),
|
||||||
|
|
||||||
( "Sine Chorus", 1, "AAAAA", False ),
|
( "Sine Chorus", 1, "AAAAA", False ),
|
||||||
( "Vibratone", 5, "AAAAA", False ),
|
( "Vibratone", 5, "AAAAA", False ),
|
||||||
|
|
@ -322,7 +343,7 @@ if single == "all" or single == "reverb":
|
||||||
run_reverb_test( outport )
|
run_reverb_test( outport )
|
||||||
|
|
||||||
if single == "all" or single == "delay":
|
if single == "all" or single == "delay":
|
||||||
# Model # Ctrl v2only
|
# Model Ctrl v2only
|
||||||
delay_test = (
|
delay_test = (
|
||||||
( "Mono Delay", 1, "AAAAA", False ),
|
( "Mono Delay", 1, "AAAAA", False ),
|
||||||
( "Multitap", 4, "AAAAD03", False ),
|
( "Multitap", 4, "AAAAD03", False ),
|
||||||
|
|
@ -331,7 +352,7 @@ if single == "all" or single == "delay":
|
||||||
run_delay_test( delay_test, outport )
|
run_delay_test( delay_test, outport )
|
||||||
|
|
||||||
if single == "all" or single == "amp":
|
if single == "all" or single == "amp":
|
||||||
# Model, #, Bias/Sag? Has 78+79?
|
# Model, Ctrl v2only
|
||||||
amp_test = (
|
amp_test = (
|
||||||
( "Studio Preamp", 13, "AAAAA--D04D12", True ),
|
( "Studio Preamp", 13, "AAAAA--D04D12", True ),
|
||||||
|
|
||||||
|
|
@ -343,3 +364,4 @@ if single == "all" or single == "amp":
|
||||||
)
|
)
|
||||||
run_amp_test( amp_test, outport )
|
run_amp_test( amp_test, outport )
|
||||||
|
|
||||||
|
print "All tests complete\n"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue