Changeset 1336
- Timestamp:
- 09/23/08 03:42:04 (15 years ago)
- Files:
-
- trunk/libffado/admin/pyuic4.py (copied) (copied from branches/libffado-2.0/admin/pyuic4.py)
- trunk/libffado/config.h.in (modified) (2 diffs)
- trunk/libffado/configuration (copied) (copied from branches/libffado-2.0/configuration)
- trunk/libffado/external/libconfig (copied) (copied from branches/libffado-2.0/external/libconfig)
- trunk/libffado/external/SConscript (modified) (1 diff)
- trunk/libffado/README (modified) (3 diffs)
- trunk/libffado/SConstruct (modified) (11 diffs)
- trunk/libffado/src/bebob/bebob_avdevice.cpp (modified) (7 diffs)
- trunk/libffado/src/bebob/bebob_avdevice.h (modified) (2 diffs)
- trunk/libffado/src/bebob/bebob_dl_mgr.cpp (modified) (7 diffs)
- trunk/libffado/src/bebob/ffado_driver_bebob.txt (deleted)
- trunk/libffado/src/bebob/focusrite/focusrite_generic.cpp (modified) (4 diffs)
- trunk/libffado/src/bebob/focusrite/focusrite_generic.h (modified) (3 diffs)
- trunk/libffado/src/bebob/focusrite/focusrite_saffire.cpp (modified) (6 diffs)
- trunk/libffado/src/bebob/focusrite/focusrite_saffire.h (modified) (4 diffs)
- trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp (modified) (17 diffs)
- trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.h (modified) (1 diff)
- trunk/libffado/src/devicemanager.cpp (modified) (19 diffs)
- trunk/libffado/src/devicemanager.h (modified) (6 diffs)
- trunk/libffado/src/dice/dice_avdevice.cpp (modified) (1 diff)
- trunk/libffado/src/dice/dice_avdevice.h (modified) (1 diff)
- trunk/libffado/src/fbtypes.h (modified) (1 diff)
- trunk/libffado/src/ffado.cpp (modified) (1 diff)
- trunk/libffado/src/ffadodevice.h (modified) (2 diffs)
- trunk/libffado/src/fireworks/efc/efc_cmd.h (modified) (1 diff)
- trunk/libffado/src/fireworks/efc/efc_cmds_hardware.h (modified) (1 diff)
- trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.cpp (modified) (1 diff)
- trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.h (modified) (2 diffs)
- trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.cpp (modified) (1 diff)
- trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.h (modified) (2 diffs)
- trunk/libffado/src/fireworks/ffado_driver_fireworks.txt (deleted)
- trunk/libffado/src/fireworks/fireworks_control.cpp (modified) (24 diffs)
- trunk/libffado/src/fireworks/fireworks_control.h (modified) (4 diffs)
- trunk/libffado/src/fireworks/fireworks_device.cpp (modified) (15 diffs)
- trunk/libffado/src/fireworks/fireworks_device.h (modified) (6 diffs)
- trunk/libffado/src/fireworks/fireworks_firmware.cpp (modified) (4 diffs)
- trunk/libffado/src/fireworks/fireworks_session_block.cpp (copied) (copied from branches/libffado-2.0/src/fireworks/fireworks_session_block.cpp)
- trunk/libffado/src/fireworks/fireworks_session_block.h (copied) (copied from branches/libffado-2.0/src/fireworks/fireworks_session_block.h)
- trunk/libffado/src/genericavc/avc_avdevice.cpp (modified) (6 diffs)
- trunk/libffado/src/genericavc/avc_avdevice.h (modified) (5 diffs)
- trunk/libffado/src/genericavc/avc_vendormodel.cpp (deleted)
- trunk/libffado/src/genericavc/avc_vendormodel.h (deleted)
- trunk/libffado/src/genericavc/ffado_driver_genericavc.txt (deleted)
- trunk/libffado/src/libavc/general/avc_plug.cpp (modified) (1 diff)
- trunk/libffado/src/libavc/general/avc_plug.h (modified) (1 diff)
- trunk/libffado/src/libavc/general/avc_unit.cpp (modified) (1 diff)
- trunk/libffado/src/libcontrol/ClockSelect.cpp (modified) (4 diffs)
- trunk/libffado/src/libcontrol/ClockSelect.h (modified) (2 diffs)
- trunk/libffado/src/libcontrol/Element.cpp (modified) (4 diffs)
- trunk/libffado/src/libcontrol/Element.h (modified) (3 diffs)
- trunk/libffado/src/libieee1394/configrom.cpp (modified) (1 diff)
- trunk/libffado/src/libieee1394/configrom.h (modified) (1 diff)
- trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (modified) (4 diffs)
- trunk/libffado/src/libieee1394/ieee1394service.cpp (modified) (11 diffs)
- trunk/libffado/src/libieee1394/ieee1394service.h (modified) (4 diffs)
- trunk/libffado/src/libieee1394/IsoHandler.cpp (modified) (27 diffs)
- trunk/libffado/src/libieee1394/IsoHandler.h (modified) (4 diffs)
- trunk/libffado/src/libieee1394/IsoHandlerManager.cpp (modified) (21 diffs)
- trunk/libffado/src/libieee1394/IsoHandlerManager.h (modified) (5 diffs)
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (15 diffs)
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (modified) (2 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp (modified) (15 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.h (modified) (4 diffs)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (28 diffs)
- trunk/libffado/src/libstreaming/StreamProcessorManager.h (modified) (5 diffs)
- trunk/libffado/src/libutil/Configuration.cpp (copied) (copied from branches/libffado-2.0/src/libutil/Configuration.cpp)
- trunk/libffado/src/libutil/Configuration.h (copied) (copied from branches/libffado-2.0/src/libutil/Configuration.h)
- trunk/libffado/src/libutil/PosixMutex.cpp (modified) (12 diffs)
- trunk/libffado/src/libutil/PosixMutex.h (modified) (3 diffs)
- trunk/libffado/src/libutil/PosixThread.cpp (modified) (7 diffs)
- trunk/libffado/src/libutil/PosixThread.h (modified) (1 diff)
- trunk/libffado/src/libutil/Thread.h (modified) (3 diffs)
- trunk/libffado/src/libutil/TimestampedBuffer.cpp (modified) (3 diffs)
- trunk/libffado/src/libutil/TimestampedBuffer.h (modified) (1 diff)
- trunk/libffado/src/libutil/Watchdog.cpp (modified) (2 diffs)
- trunk/libffado/src/metrichalo/mh_avdevice.cpp (modified) (1 diff)
- trunk/libffado/src/metrichalo/mh_avdevice.h (modified) (1 diff)
- trunk/libffado/src/motu/motu_avdevice.cpp (modified) (11 diffs)
- trunk/libffado/src/motu/motu_avdevice.h (modified) (4 diffs)
- trunk/libffado/src/motu/motu_controls.cpp (modified) (1 diff)
- trunk/libffado/src/motu/motu_controls.h (modified) (3 diffs)
- trunk/libffado/src/rme/rme_avdevice.cpp (modified) (1 diff)
- trunk/libffado/src/rme/rme_avdevice.h (modified) (1 diff)
- trunk/libffado/src/SConscript (modified) (4 diffs)
- trunk/libffado/support/alsa/alsa_plugin.cpp (modified) (2 diffs)
- trunk/libffado/support/dbus/control-interface.xml (modified) (1 diff)
- trunk/libffado/support/dbus/controlserver.cpp (modified) (5 diffs)
- trunk/libffado/support/dbus/controlserver.h (modified) (3 diffs)
- trunk/libffado/support/dbus/ffado-dbus-server.cpp (modified) (1 diff)
- trunk/libffado/support/firmware/bridgeco-downloader.cpp (modified) (4 diffs)
- trunk/libffado/support/firmware/fireworks-downloader.cpp (modified) (8 diffs)
- trunk/libffado/support/mixer-qt4 (copied) (copied from branches/libffado-2.0/support/mixer-qt4)
- trunk/libffado/support/mixer-qt4/SConscript (copied) (copied from branches/libffado-2.0/support/mixer-qt4/SConscript)
- trunk/libffado/support/mixer/ffadomixer.in (modified) (12 diffs)
- trunk/libffado/support/mixer/ffadomixer_config.py.in (modified) (1 diff)
- trunk/libffado/support/mixer/mixer_af2.py (deleted)
- trunk/libffado/support/mixer/mixer_af2.ui (deleted)
- trunk/libffado/support/mixer/mixer_audiofire.py (copied) (copied from branches/libffado-2.0/support/mixer/mixer_audiofire.py)
- trunk/libffado/support/mixer/mixer_audiofire_settings.ui (copied) (copied from branches/libffado-2.0/support/mixer/mixer_audiofire_settings.ui)
- trunk/libffado/support/mixer/mixer_audiofire_strip.ui (copied) (copied from branches/libffado-2.0/support/mixer/mixer_audiofire_strip.ui)
- trunk/libffado/support/mixer/mixer_global.py (modified) (2 diffs)
- trunk/libffado/support/mixer/mixer_global.ui (modified) (4 diffs)
- trunk/libffado/support/mixer/mixer_motu.py (modified) (9 diffs)
- trunk/libffado/support/mixer/mixer_motu.ui (modified) (10 diffs)
- trunk/libffado/support/mixer/mixer_saffire.py (modified) (4 diffs)
- trunk/libffado/support/mixer/mixer_saffire.ui (deleted)
- trunk/libffado/support/mixer/mixer_saffire_base.py (modified) (2 diffs)
- trunk/libffado/support/mixer/mixer_saffire_mono.ui (copied) (copied from branches/libffado-2.0/support/mixer/mixer_saffire_mono.ui)
- trunk/libffado/support/mixer/mixer_saffire_stereo.ui (copied) (copied from branches/libffado-2.0/support/mixer/mixer_saffire_stereo.ui)
- trunk/libffado/support/mixer/SConscript (modified) (2 diffs)
- trunk/libffado/support/SConscript (modified) (1 diff)
- trunk/libffado/tests/dbus_test.py (copied) (copied from branches/libffado-2.0/tests/dbus_test.py)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/config.h.in
r1254 r1336 6 6 #define LIBDIR "$LIBDIR" 7 7 #define SHAREDIR "$SHAREDIR" 8 9 /* configuration file locations */ 10 #define USER_CONFIG_FILE "$USER_CONFIG_FILE" 11 #define SYSTEM_CONFIG_FILE "$SYSTEM_CONFIG_FILE" 8 12 9 13 /* Define indicating availability of lrint() */ … … 129 133 // packets early if we want to. (not completely according to spec) 130 134 // (for spec compliance you need to specify a value of 0) 131 #define AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY 0135 #define AMDTP_MAX_CYCLES_TO_TRANSMIT_EARLY 1 132 136 133 137 // ensure that the AMDTP SP clips all float values to [-1.0..1.0] trunk/libffado/external/SConscript
r1185 r1336 26 26 env = env.Clone() 27 27 28 env.SConscript( dirs= "dbus", exports="env" )28 env.SConscript( dirs=["dbus", "libconfig"], exports="env" ) 29 29 trunk/libffado/README
r1239 r1336 42 42 * Focusrite Saffire PRO10 43 43 * Focusrite Saffire PRO26 44 * ECHO AudioFire2 45 * ECHO AudioFire4 44 * ECHO AudioFire2, AudioFire4, AudioFire8, AudioFire12 46 45 * Mackie Onyx Mixer FireWire expansion 47 46 … … 71 70 * Presonus FireBox 72 71 * Presonus FirePod / FP10 73 * Focusrite Saffire LE 74 * ECHO AudioFire8 75 * ECHO AudioFire12 72 * Alesis io14 73 * TC Konnekt 8, Konnekt 24D, Konnekt Live 76 74 77 75 Usupported devices: 78 76 * Presonus FireStation 79 77 * Presonus FireStudio (all variants) 80 * TC Konnekt (all variants)81 * Alesis devices78 * Other TC Konnekt devices 79 * Other Alesis devices 82 80 * Metric Halo devices 83 81 * RME Firewire devices … … 105 103 106 104 jackd (>= 0.109.12), http://jackaudio.org 105 [NOTE: at the time of writing, this is the development (SVN) version.] 107 106 108 107 Optionally, but recommended is that you install qjackctl: trunk/libffado/SConstruct
r1258 r1336 102 102 buildenv[var]='' 103 103 104 env = Environment( tools=['default','scanreplace','pyuic',' dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )104 env = Environment( tools=['default','scanreplace','pyuic','pyuic4','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts ) 105 105 106 106 if os.environ.has_key('CC'): … … 108 108 if os.environ.has_key('CXX'): 109 109 env['CXX'] = os.environ['CXX'] 110 111 # grab OS CFLAGS / CCFLAGS 112 env['OS_CFLAGS']=[] 113 if os.environ.has_key('CFLAGS'): 114 env['OS_CFLAGS'] = os.environ['CFLAGS'] 115 env['OS_CCFLAGS']=[] 116 if os.environ.has_key('CCFLAGS'): 117 env['OS_CCFLAGS'] = os.environ['CCFLAGS'] 110 118 111 119 Help( """ … … 185 193 tests.update( env['PKGCONFIG_TESTS'] ) 186 194 tests.update( env['PYUIC_TESTS'] ) 195 tests.update( env['PYUIC4_TESTS'] ) 187 196 188 197 conf = Configure( env, … … 283 292 284 293 # PyQT checks 294 build_mixer = False 285 295 if conf.CheckForApp( "which pyuic" ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'qt' ): 286 296 env['PYUIC'] = True 297 build_mixer = True 298 299 if conf.CheckForApp( "xdg-desktop-menu --help" ): 300 env['XDG_TOOLS'] = True 301 else: 302 print """ 303 I couldn't find the program 'xdg-desktop-menu'. Together with xdg-icon-resource 304 this is needed to add the fancy entry to your menu. But the mixer will be installed, you can start it by executing "ffadomixer". 305 """ 306 elif conf.CheckForApp( "which pyuic4" ) and conf.CheckForPyModule( 'dbus' ) and conf.CheckForPyModule( 'PyQt4' ): 307 env['PYUIC4'] = True 308 build_mixer = True 287 309 288 310 if conf.CheckForApp( "xdg-desktop-menu --help" ): … … 294 316 """ 295 317 296 else:318 if not build_mixer: 297 319 print """ 298 I couldn't find all the prerequisites ('pyuic' and the python-modules 'dbus' and320 I couldn't find all the prerequisites ('pyuic' / 'pyuic4' and the python-modules 'dbus' and 299 321 'qt', the packages could be named like dbus-python and PyQt) to build the mixer. 300 322 Therefor the mixer won't get installed. … … 398 420 config_os = 3 399 421 config = config_guess.split ("-") 422 423 needs_fPIC = False 400 424 401 425 # Autodetect … … 481 505 482 506 # build for 64-bit userland? 483 if env['DIST_TARGET'] == "powerpc64" or env['DIST_TARGET'] == "x86_64":484 print "Doing a 64-bit build"507 if env['DIST_TARGET'] == "powerpc64": 508 print "Doing a 64-bit PowerPC build" 485 509 env.AppendUnique( CCFLAGS=["-m64"] ) 486 510 env.AppendUnique( CFLAGS=["-m64"] ) 511 elif env['DIST_TARGET'] == "x86_64": 512 print "Doing a 64-bit x86 build" 513 env.AppendUnique( CCFLAGS=["-m64"] ) 514 env.AppendUnique( CFLAGS=["-m64"] ) 515 needs_fPIC = True 487 516 else: 488 517 print "Doing a 32-bit build" 489 518 env.AppendUnique( CCFLAGS=["-m32"] ) 490 519 env.AppendUnique( CFLAGS=["-m32"] ) 520 521 if needs_fPIC or '-fPIC' in env['OS_CFLAGS']: 522 env.AppendUnique( CFLAGS=["-fPIC"] ) 523 if needs_fPIC or '-fPIC' in env['OS_CCFLAGS']: 524 env.AppendUnique( CCFLAGS=["-fPIC"] ) 491 525 492 526 # end of processor-specific section … … 502 536 env['REVISION'] = env['REVISION'].split(':')[-1] 503 537 504 if env['REVISION'] == 'exported': 538 # try to circumvent localized versions 539 if len(env['REVISION']) >= 5 and env['REVISION'][0:6] == 'export': 505 540 env['REVISION'] = '' 506 541 … … 513 548 env['CONFIGDIR'] = "~/.ffado" 514 549 env['CACHEDIR'] = "~/.ffado" 550 551 env['USER_CONFIG_FILE'] = env['CONFIGDIR'] + "/configuration" 552 env['SYSTEM_CONFIG_FILE'] = env['sharedir'] + "/configuration" 515 553 516 554 env['REGISTRATION_URL'] = "http://ffado.org/deviceregistration/register.php?action=register" … … 540 578 pkgconfig = env.ScanReplace( "libffado.pc.in" ) 541 579 env.Install( env['libdir'] + '/pkgconfig', pkgconfig ) 580 581 env.Install( env['SYSTEM_CONFIG_FILE'], 'configuration' ) 542 582 543 583 subdirs=['external','src','libffado','tests','support','doc'] … … 600 640 env.Command( "TAGS", "", findcommand + " |xargs etags" ) 601 641 env.AlwaysBuild( "tags", "TAGS" ) 602 env.NoCache( "tags", "TAGS" ) 603 642 if 'NoCache' in dir(env): 643 env.NoCache( "tags", "TAGS" ) 644 trunk/libffado/src/bebob/bebob_avdevice.cpp
r1324 r1336 24 24 #include "config.h" 25 25 26 #include "devicemanager.h" 26 27 #include "bebob/bebob_avdevice.h" 27 28 #include "bebob/bebob_avdevice_subunit.h" … … 39 40 #include "libieee1394/ieee1394service.h" 40 41 41 #include "genericavc/avc_vendormodel.h"42 43 42 #include "libavc/general/avc_plug_info.h" 44 43 #include "libavc/general/avc_extended_plug_info.h" … … 82 81 83 82 bool 84 AvDevice::probe( ConfigRom& configRom, bool generic )83 AvDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 85 84 { 86 85 if(generic) { … … 118 117 unsigned int modelId = configRom.getModelId(); 119 118 120 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_bebob.txt" ); 121 if ( vendorModel.parse() ) { 122 return vendorModel.isPresent( vendorId, modelId ); 123 } 124 return false; 119 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 120 return c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB; 125 121 } 126 122 } … … 174 170 } 175 171 172 #define BEBOB_CHECK_AND_ADD_SR(v, x) \ 173 { if(supportsSamplingFrequency(x)) \ 174 v.push_back(x); } 176 175 bool 177 176 AvDevice::discover() … … 180 179 unsigned int modelId = getConfigRom().getModelId(); 181 180 182 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_bebob.txt" ); 183 if ( vendorModel.parse() ) { 184 m_model = vendorModel.find( vendorId, modelId ); 185 } 186 187 if (GenericAVC::VendorModel::isValid(m_model)) { 181 Util::Configuration &c = getDeviceManager().getConfiguration(); 182 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 183 184 if (c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB) { 188 185 debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 189 m_model.vendor_name.c_str(),190 m_model.model_name.c_str());186 vme.vendor_name.c_str(), 187 vme.model_name.c_str()); 191 188 } else { 192 debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n", 189 debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n", 193 190 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 194 191 } … … 452 449 return true; 453 450 } 454 455 451 456 452 uint8_t trunk/libffado/src/bebob/bebob_avdevice.h
r1324 r1336 64 64 virtual ~AvDevice(); 65 65 66 static bool probe( ConfigRom& configRom, bool generic = false );66 static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 67 67 virtual bool loadFromCache(); 68 68 virtual bool saveCache(); … … 113 113 virtual uint16_t getConfigurationIdSyncMode(); 114 114 115 std::vector<int> m_supported_frequencies; 115 116 protected: 116 117 Mixer* m_Mixer; trunk/libffado/src/bebob/bebob_dl_mgr.cpp
r1234 r1336 160 160 } 161 161 sleep( 1 ); 162 printf("."); 163 fflush(stdout); 162 164 } 163 165 … … 387 389 // bootloader erases the flash, have to wait until is ready 388 390 // to answer our next request 389 printf( "wait until flash ereasing has terminated\n" ); 390 sleep( 30 ); 391 printf( "wait until flash erasing has terminated\n" ); 392 int cnt = 30; 393 while(cnt--) { 394 sleep( 1 ); 395 printf("."); 396 fflush(stdout); 397 } 398 printf("\n"); 391 399 392 400 if ( !readResponse( ccDStart ) ) { … … 462 470 downloadedBytes += blockSize; 463 471 if ( ( i % 100 ) == 0 ) { 464 printf( "%10d/%d bytes downloaded\ n",472 printf( "%10d/%d bytes downloaded\r", 465 473 downloadedBytes, totalBytes ); 474 fflush(stdout); 466 475 } 467 476 … … 487 496 488 497 printf( "wait for transaction completion\n" ); 489 sleep( 10 ); 498 cnt = 10; 499 while(cnt--) { 500 sleep( 1 ); 501 printf("."); 502 fflush(stdout); 503 } 504 printf("\n"); 490 505 491 506 if ( !readResponse( ccEnd ) ) { … … 545 560 BeBoB::BootloaderManager::waitForBusReset() 546 561 { 547 pthread_cond_wait( &m_cond, &m_mutex ); 562 struct timespec timeout; 563 int retcode; 564 clock_gettime(CLOCK_REALTIME, &timeout); 565 do { 566 printf("."); 567 fflush(stdout); 568 timeout.tv_sec = timeout.tv_sec + 1; 569 retcode = pthread_cond_timedwait( &m_cond, &m_mutex, &timeout ); 570 } while (retcode == ETIMEDOUT); 548 571 } 549 572 … … 642 665 // there is no way to find out when it has finished 643 666 sleep( 10 ); 667 int cnt = 10; 668 while(cnt--) { 669 sleep( 1 ); 670 printf("."); 671 fflush(stdout); 672 } 673 printf("\n"); 644 674 645 675 return true; … … 697 727 698 728 sleep( 5 ); 729 int cnt = 5; 730 while(cnt--) { 731 sleep( 1 ); 732 printf("."); 733 fflush(stdout); 734 } 735 printf("\n"); 699 736 700 737 return true; trunk/libffado/src/bebob/focusrite/focusrite_generic.cpp
r1184 r1336 56 56 FocusriteDevice::setSpecificValue(uint32_t id, uint32_t v) 57 57 { 58 bool use_avc=false; 58 debugOutput(DEBUG_LEVEL_VERBOSE, "Writing parameter address space id 0x%08lX (%u), data: 0x%08lX\n", 59 id, id, v); 60 bool use_avc = false; 59 61 if(!getOption("useAvcForParameters", use_avc)) { 60 62 debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); … … 70 72 FocusriteDevice::getSpecificValue(uint32_t id, uint32_t *v) 71 73 { 72 bool use_avc=false; 74 bool retval; 75 bool use_avc = false; 73 76 if(!getOption("useAvcForParameters", use_avc)) { 74 77 debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); 75 78 } 76 79 if (use_avc) { 77 return getSpecificValueAvc(id, v); 78 } else { 79 return getSpecificValueARM(id, v); 80 } 80 retval = getSpecificValueAvc(id, v); 81 } else { 82 retval = getSpecificValueARM(id, v); 83 } 84 debugOutput(DEBUG_LEVEL_VERBOSE,"Read parameter address space id 0x%08lX (%u): %08lX\n", id, id, *v); 85 return retval; 81 86 } 82 87 … … 308 313 } 309 314 315 MeteringControl::MeteringControl(FocusriteDevice& parent, int id) 316 : Control::Discrete(&parent) 317 , m_Parent(parent) 318 , m_cmd_id ( id ) 319 {} 320 MeteringControl::MeteringControl(FocusriteDevice& parent, int id, 321 std::string name, std::string label, std::string descr) 322 : Control::Discrete(&parent) 323 , m_Parent(parent) 324 , m_cmd_id ( id ) 325 { 326 setName(name); 327 setLabel(label); 328 setDescription(descr); 329 } 330 331 int 332 MeteringControl::getValue() 333 { 334 uint32_t val=0; 335 336 if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) { 337 debugError( "getSpecificValue failed\n" ); 338 return 0; 339 } else { 340 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n", 341 m_cmd_id, val); 342 return val; 343 } 344 } 345 310 346 // reg control 311 347 RegisterControl::RegisterControl(FocusriteDevice& parent) … … 412 448 } 413 449 450 // hardware dial control 451 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id) 452 : Control::Discrete(&parent) 453 , m_Parent(parent) 454 , m_cmd_id ( id ) 455 {} 456 DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, 457 std::string name, std::string label, std::string descr) 458 : Control::Discrete(&parent) 459 , m_Parent(parent) 460 , m_cmd_id ( id ) 461 { 462 setName(name); 463 setLabel(label); 464 setDescription(descr); 465 } 466 467 int 468 DialPositionControl::getValue() 469 { 470 uint32_t val=0; 471 472 if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) { 473 debugError( "getSpecificValue failed\n" ); 474 return 0; 475 } else { 476 val = val >> 5; 477 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n", 478 m_cmd_id, val); 479 return val; 480 } 481 } 414 482 415 483 // Saffire pro matrix mixer element trunk/libffado/src/bebob/focusrite/focusrite_generic.h
r1158 r1336 46 46 BinaryControl(FocusriteDevice& parent, int id, int bit, 47 47 std::string name, std::string label, std::string descr); 48 48 49 49 virtual bool setValue(int v); 50 50 virtual int getValue(); … … 81 81 virtual int getMaximum() {return 0x07FFF;}; 82 82 83 private: 84 FocusriteDevice& m_Parent; 85 unsigned int m_cmd_id; 86 }; 87 88 class MeteringControl 89 : public Control::Discrete 90 { 91 public: 92 MeteringControl(FocusriteDevice& parent, int id); 93 MeteringControl(FocusriteDevice& parent, int id, 94 std::string name, std::string label, std::string descr); 95 96 virtual bool setValue(int v) {return false;}; 97 virtual int getValue(); 98 virtual bool setValue(int idx, int v) 99 {return setValue(v);}; 100 virtual int getValue(int idx) 101 {return getValue();}; 102 103 virtual int getMinimum() {return 0;}; 104 virtual int getMaximum() {return 0x07FFF;}; 83 105 private: 84 106 FocusriteDevice& m_Parent; … … 122 144 unsigned int m_cmd_id; 123 145 unsigned int m_bit_shift; 146 }; 147 148 class DialPositionControl 149 : public Control::Discrete 150 { 151 public: 152 DialPositionControl(FocusriteDevice& parent, int id); 153 DialPositionControl(FocusriteDevice& parent, int id, 154 std::string name, std::string label, std::string descr); 155 156 virtual bool setValue(int v) {return false;}; 157 virtual int getValue(); 158 virtual bool setValue(int idx, int v) 159 {return setValue(v);}; 160 virtual int getValue(int idx) 161 {return getValue();}; 162 163 virtual int getMinimum() {return 0;}; 164 virtual int getMaximum() {return 0x07FFF;}; 165 private: 166 FocusriteDevice& m_Parent; 167 unsigned int m_cmd_id; 124 168 }; 125 169 trunk/libffado/src/bebob/focusrite/focusrite_saffire.cpp
r1181 r1336 146 146 result &= m_MixerContainer->addElement( 147 147 new BinaryControl(*this, 148 FR_SAFFIRE_CMD_ID_ SPDIF_SWITCH, 0,148 FR_SAFFIRE_CMD_ID_INPUT_SOURCE, 0, 149 149 "SpdifSwitch", "S/PDIF Switch", "S/PDIF Switch")); 150 result &= m_MixerContainer->addElement( 151 new BinaryControl(*this, 152 FR_SAFFIRE_CMD_ID_MONO_MODE, 0, 153 "MonoMode", "Mono Mode", "Toggle Mono Mode")); 154 result &= m_MixerContainer->addElement( 155 new BinaryControl(*this, 156 FR_SAFFIRE_CMD_ID_DEVICE_MODE, 0, 157 "DeviceMode", "Device Mode", "Toggle Device Mode")); 158 result &= m_MixerContainer->addElement( 159 new BinaryControl(*this, 160 FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK, 0, 161 "ExternalLock", "External Lock", "Has external lock?")); 162 result &= m_MixerContainer->addElement( 163 new BinaryControl(*this, 164 FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS, 0, 165 "AudioOnStatus", "Audio On Status", "Audio On Status")); 166 result &= m_MixerContainer->addElement( 167 new BinaryControl(*this, 168 FR_SAFFIRE_CMD_ID_SAVE_SETTINGS, 0, 169 "SaveSettings", "Save Settings", "Save Settings")); 150 170 151 171 // output mute controls … … 230 250 FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC, 231 251 "Out78Level", "Out7/8 Level", "Output 7/8 Level")); 252 253 result &= m_MixerContainer->addElement( 254 new DialPositionControl(*this, 255 FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 256 "MonitorDial", "Monitor Dial", "Monitor Dial Value")); 257 258 // metering 259 result &= m_MixerContainer->addElement( 260 new MeteringControl(*this, 261 FR_SAFFIRE_CMD_ID_METERING_IN1, 262 "MeteringIn1", "Metering Input 1", "Metering on Input 1")); 263 result &= m_MixerContainer->addElement( 264 new MeteringControl(*this, 265 FR_SAFFIRE_CMD_ID_METERING_IN2, 266 "MeteringIn2", "Metering Input 2", "Metering on Input 2")); 267 result &= m_MixerContainer->addElement( 268 new MeteringControl(*this, 269 FR_SAFFIRE_CMD_ID_METERING_IN3, 270 "MeteringIn3", "Metering Input 3", "Metering on Input 3")); 271 result &= m_MixerContainer->addElement( 272 new MeteringControl(*this, 273 FR_SAFFIRE_CMD_ID_METERING_IN4, 274 "MeteringIn4", "Metering Input 4", "Metering on Input 4")); 275 276 result &= m_MixerContainer->addElement( 277 new MeteringControl(*this, 278 FR_SAFFIRE_CMD_ID_METERING_PC1, 279 "MeteringPc1", "Metering PC 1", "Metering on PC Channel 1")); 280 result &= m_MixerContainer->addElement( 281 new MeteringControl(*this, 282 FR_SAFFIRE_CMD_ID_METERING_PC2, 283 "MeteringPc2", "Metering PC 2", "Metering on PC Channel 2")); 284 result &= m_MixerContainer->addElement( 285 new MeteringControl(*this, 286 FR_SAFFIRE_CMD_ID_METERING_PC3, 287 "MeteringPc3", "Metering PC 3", "Metering on PC Channel 3")); 288 result &= m_MixerContainer->addElement( 289 new MeteringControl(*this, 290 FR_SAFFIRE_CMD_ID_METERING_PC4, 291 "MeteringPc4", "Metering PC 4", "Metering on PC Channel 4")); 292 result &= m_MixerContainer->addElement( 293 new MeteringControl(*this, 294 FR_SAFFIRE_CMD_ID_METERING_PC5, 295 "MeteringPc5", "Metering PC 5", "Metering on PC Channel 5")); 296 result &= m_MixerContainer->addElement( 297 new MeteringControl(*this, 298 FR_SAFFIRE_CMD_ID_METERING_PC6, 299 "MeteringPc6", "Metering PC 6", "Metering on PC Channel 6")); 300 result &= m_MixerContainer->addElement( 301 new MeteringControl(*this, 302 FR_SAFFIRE_CMD_ID_METERING_PC7, 303 "MeteringPc7", "Metering PC 7", "Metering on PC Channel 7")); 304 result &= m_MixerContainer->addElement( 305 new MeteringControl(*this, 306 FR_SAFFIRE_CMD_ID_METERING_PC8, 307 "MeteringPc8", "Metering PC 8", "Metering on PC Channel 8")); 308 result &= m_MixerContainer->addElement( 309 new MeteringControl(*this, 310 FR_SAFFIRE_CMD_ID_METERING_PC9, 311 "MeteringPc9", "Metering PC 9", "Metering on PC Channel 9")); 312 result &= m_MixerContainer->addElement( 313 new MeteringControl(*this, 314 FR_SAFFIRE_CMD_ID_METERING_PC10, 315 "MeteringPc10", "Metering PC 10", "Metering on PC Channel 10")); 316 232 317 } 233 318 … … 248 333 FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_96K, 0, 249 334 "Swap41_96", "Swap41_96", "Swap41_96")); 250 251 335 } else { 252 336 result &= m_MixerContainer->addElement( 253 new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_InputMix, "InputMix")); 254 255 result &= m_MixerContainer->addElement( 256 new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_PCMix, "PCMix")); 337 new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireStereoMatrixMix, "MatrixMixerStereo")); 338 result &= m_MixerContainer->addElement( 339 new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireMonoMatrixMix, "MatrixMixerMono")); 257 340 } 258 341 … … 342 425 void SaffireMatrixMixer::init() 343 426 { 344 if (m_type==eMMT_PCMix) { 427 if (m_type==eMMT_SaffireStereoMatrixMix) { 428 m_RowInfo.clear(); 429 addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 345 430 addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2"); 346 431 addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4"); 347 432 addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6"); 348 433 addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8"); 349 addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 350 434 addSignalInfo(m_RowInfo, "IN12", "Input 1/2", "Hardware Inputs 1/2"); 435 addSignalInfo(m_RowInfo, "IN34", "Input 3/4", "Hardware Inputs 3/4 (dry / S/PDIF)"); 436 addSignalInfo(m_RowInfo, "FX", "Effect return", "Effect return"); 437 438 m_ColInfo.clear(); 439 addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 351 440 addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2"); 352 441 addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4"); 353 addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6"); 354 addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8"); 355 addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 442 addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)"); 443 addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)"); 356 444 357 445 // init the cell matrix 358 #define FOCUSRITE_SAFFIRE_PCMIX_NB_COLS 5 359 #define FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS 5 360 361 std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_PCMIX_NB_COLS ); 362 std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS, tmp_cols); 446 #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS 5 447 #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS 8 448 #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET 0 449 450 std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS ); 451 std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS, tmp_cols); 363 452 m_CellInfo = tmp_all; 364 453 … … 369 458 c.address=0; 370 459 371 for (int i=0;i<FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS;i++) { 372 for (int j=0;j<FOCUSRITE_SAFFIRE_PCMIX_NB_COLS;j++) { 373 m_CellInfo.at(i).at(j) = c; 460 // all cells are valid 461 for (int i=0; i < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS; i++) { 462 for (int j=0; j < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS; j++) { 463 c.row = i; 464 c.col = j; 465 c.valid = true; 466 c.address = FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS + c.col; 467 m_CellInfo.at(i).at(j) = c; 374 468 } 375 469 } 376 377 // now set the cells that are valid 378 setCellInfo(0,0,FR_SAFFIRE_CMD_ID_PC12_TO_OUT12, true); 379 setCellInfo(0,1,FR_SAFFIRE_CMD_ID_PC12_TO_OUT34, true); 380 setCellInfo(0,2,FR_SAFFIRE_CMD_ID_PC12_TO_OUT56, true); 381 setCellInfo(0,3,FR_SAFFIRE_CMD_ID_PC12_TO_OUT79, true); 382 setCellInfo(0,4,FR_SAFFIRE_CMD_ID_PC12_TO_OUT910, true); 383 setCellInfo(1,0,FR_SAFFIRE_CMD_ID_PC34_TO_OUT12, true); 384 setCellInfo(1,1,FR_SAFFIRE_CMD_ID_PC34_TO_OUT34, true); 385 setCellInfo(1,2,FR_SAFFIRE_CMD_ID_PC34_TO_OUT56, true); 386 setCellInfo(1,3,FR_SAFFIRE_CMD_ID_PC34_TO_OUT79, true); 387 setCellInfo(1,4,FR_SAFFIRE_CMD_ID_PC34_TO_OUT910, true); 388 setCellInfo(2,0,FR_SAFFIRE_CMD_ID_PC56_TO_OUT12, true); 389 setCellInfo(2,1,FR_SAFFIRE_CMD_ID_PC56_TO_OUT34, true); 390 setCellInfo(2,2,FR_SAFFIRE_CMD_ID_PC56_TO_OUT56, true); 391 setCellInfo(2,3,FR_SAFFIRE_CMD_ID_PC56_TO_OUT79, true); 392 setCellInfo(2,4,FR_SAFFIRE_CMD_ID_PC56_TO_OUT910, true); 393 setCellInfo(3,0,FR_SAFFIRE_CMD_ID_PC78_TO_OUT12, true); 394 setCellInfo(3,1,FR_SAFFIRE_CMD_ID_PC78_TO_OUT34, true); 395 setCellInfo(3,2,FR_SAFFIRE_CMD_ID_PC78_TO_OUT56, true); 396 setCellInfo(3,3,FR_SAFFIRE_CMD_ID_PC78_TO_OUT79, true); 397 setCellInfo(3,4,FR_SAFFIRE_CMD_ID_PC78_TO_OUT910, true); 398 setCellInfo(4,0,FR_SAFFIRE_CMD_ID_PC910_TO_OUT12, true); 399 setCellInfo(4,1,FR_SAFFIRE_CMD_ID_PC910_TO_OUT34, true); 400 setCellInfo(4,2,FR_SAFFIRE_CMD_ID_PC910_TO_OUT56, true); 401 setCellInfo(4,3,FR_SAFFIRE_CMD_ID_PC910_TO_OUT79, true); 402 setCellInfo(4,4,FR_SAFFIRE_CMD_ID_PC910_TO_OUT910, true); 403 404 } else if (m_type==eMMT_InputMix) { 405 addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1"); 406 addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2"); 407 addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input"); 408 addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input"); 409 addSignalInfo(m_RowInfo, "REV1", "REVERB 1", "Reverb CH1 return"); 410 addSignalInfo(m_RowInfo, "REV1", "REVERB 2", "Reverb CH2 return"); 411 412 addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1"); 413 addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2"); 414 addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3"); 415 addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4"); 416 addSignalInfo(m_ColInfo, "OUT5", "OUT 5", "Output 5"); 417 addSignalInfo(m_ColInfo, "OUT6", "OUT 6", "Output 6"); 418 addSignalInfo(m_ColInfo, "OUT7", "OUT 7", "Output 7"); 419 addSignalInfo(m_ColInfo, "OUT8", "OUT 8", "Output 8"); 420 addSignalInfo(m_ColInfo, "OUT9", "OUT 9", "Output 9"); 421 addSignalInfo(m_ColInfo, "OUT10", "OUT 10", "Output 10"); 470 } else if (m_type==eMMT_SaffireMonoMatrixMix) { 471 m_RowInfo.clear(); 472 addSignalInfo(m_RowInfo, "IN1", "Input 1", "Hardware Inputs 1"); 473 addSignalInfo(m_RowInfo, "IN3", "Input 3", "Hardware Inputs 3"); 474 addSignalInfo(m_RowInfo, "FX1", "Effect return 1", "Effect return 1"); 475 addSignalInfo(m_RowInfo, "IN2", "Input 2", "Hardware Inputs 2"); 476 addSignalInfo(m_RowInfo, "IN4", "Input 4", "Hardware Inputs 4"); 477 addSignalInfo(m_RowInfo, "FX2", "Effect return 2", "Effect return 2"); 478 addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10"); 479 addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2"); 480 addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4"); 481 addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6"); 482 addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8"); 483 484 m_ColInfo.clear(); 485 addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10"); 486 addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2"); 487 addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4"); 488 addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)"); 489 addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)"); 422 490 423 491 // init the cell matrix 424 #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS 10 425 #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS 6 426 427 std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS ); 428 std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS,tmp_cols); 492 #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS 5 493 #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS 11 494 #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET 0 495 496 std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS ); 497 std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS, tmp_cols); 429 498 m_CellInfo = tmp_all; 430 499 … … 435 504 c.address=0; 436 505 437 for (int i=0;i<FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS;i++) { 438 for (int j=0;j<FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS;j++) { 439 m_CellInfo.at(i).at(j) = c; 506 // all cells are valid 507 for (int i=0; i < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS; i++) { 508 for (int j=0; j < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS; j++) { 509 c.row = i; 510 c.col = j; 511 c.valid = true; 512 c.address = FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS + c.col; 513 m_CellInfo.at(i).at(j) = c; 440 514 } 441 515 } 442 443 // now set the cells that are valid444 setCellInfo(0,0,FR_SAFFIRE_CMD_ID_IN1_TO_OUT1, true);445 setCellInfo(0,2,FR_SAFFIRE_CMD_ID_IN1_TO_OUT3, true);446 setCellInfo(0,4,FR_SAFFIRE_CMD_ID_IN1_TO_OUT5, true);447 setCellInfo(0,6,FR_SAFFIRE_CMD_ID_IN1_TO_OUT7, true);448 setCellInfo(0,8,FR_SAFFIRE_CMD_ID_IN1_TO_OUT9, true);449 setCellInfo(1,1,FR_SAFFIRE_CMD_ID_IN2_TO_OUT2, true);450 setCellInfo(1,3,FR_SAFFIRE_CMD_ID_IN2_TO_OUT4, true);451 setCellInfo(1,5,FR_SAFFIRE_CMD_ID_IN2_TO_OUT6, true);452 setCellInfo(1,7,FR_SAFFIRE_CMD_ID_IN2_TO_OUT8, true);453 setCellInfo(1,9,FR_SAFFIRE_CMD_ID_IN2_TO_OUT10, true);454 setCellInfo(2,0,FR_SAFFIRE_CMD_ID_IN3_TO_OUT1, true);455 setCellInfo(2,2,FR_SAFFIRE_CMD_ID_IN3_TO_OUT3, true);456 setCellInfo(2,4,FR_SAFFIRE_CMD_ID_IN3_TO_OUT5, true);457 setCellInfo(2,6,FR_SAFFIRE_CMD_ID_IN3_TO_OUT7, true);458 setCellInfo(2,8,FR_SAFFIRE_CMD_ID_IN3_TO_OUT9, true);459 setCellInfo(3,1,FR_SAFFIRE_CMD_ID_IN4_TO_OUT2, true);460 setCellInfo(3,3,FR_SAFFIRE_CMD_ID_IN4_TO_OUT4, true);461 setCellInfo(3,5,FR_SAFFIRE_CMD_ID_IN4_TO_OUT6, true);462 setCellInfo(3,7,FR_SAFFIRE_CMD_ID_IN4_TO_OUT8, true);463 setCellInfo(3,9,FR_SAFFIRE_CMD_ID_IN4_TO_OUT10, true);464 465 setCellInfo(4,0,FR_SAFFIRE_CMD_ID_REV1_TO_OUT1, true);466 setCellInfo(5,1,FR_SAFFIRE_CMD_ID_REV2_TO_OUT2, true);467 setCellInfo(4,2,FR_SAFFIRE_CMD_ID_REV1_TO_OUT3, true);468 setCellInfo(5,3,FR_SAFFIRE_CMD_ID_REV2_TO_OUT4, true);469 setCellInfo(4,4,FR_SAFFIRE_CMD_ID_REV1_TO_OUT5, true);470 setCellInfo(5,5,FR_SAFFIRE_CMD_ID_REV2_TO_OUT6, true);471 setCellInfo(4,6,FR_SAFFIRE_CMD_ID_REV1_TO_OUT7, true);472 setCellInfo(5,7,FR_SAFFIRE_CMD_ID_REV2_TO_OUT8, true);473 setCellInfo(4,8,FR_SAFFIRE_CMD_ID_REV1_TO_OUT9, true);474 setCellInfo(5,9,FR_SAFFIRE_CMD_ID_REV2_TO_OUT10, true);475 476 516 } else if (m_type == eMMT_LEMix48) { 477 517 addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1"); trunk/libffado/src/bebob/focusrite/focusrite_saffire.h
r1181 r1336 33 33 // -- Original Saffire -- 34 34 35 // The ID's for the hardware input matrix mixer 36 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT1 1 37 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT3 2 38 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT5 3 39 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT7 4 40 #define FR_SAFFIRE_CMD_ID_IN1_TO_OUT9 0 41 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT2 16 42 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT4 17 43 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT6 18 44 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT8 19 45 #define FR_SAFFIRE_CMD_ID_IN2_TO_OUT10 15 46 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT1 6 47 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT3 7 48 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT5 8 49 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT7 9 50 #define FR_SAFFIRE_CMD_ID_IN3_TO_OUT9 5 51 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT2 21 52 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT4 22 53 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT6 23 54 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT8 24 55 #define FR_SAFFIRE_CMD_ID_IN4_TO_OUT10 20 56 57 // reverb return id's (part of hardware input mixer) 58 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT1 11 59 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT2 26 60 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT3 12 61 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT4 27 62 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT5 13 63 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT6 28 64 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT7 14 65 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT8 29 66 #define FR_SAFFIRE_CMD_ID_REV1_TO_OUT9 10 67 #define FR_SAFFIRE_CMD_ID_REV2_TO_OUT10 25 68 69 // The ID's for the playback matrix mixer 70 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT12 36 71 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT34 37 72 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT56 38 73 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT79 39 74 #define FR_SAFFIRE_CMD_ID_PC12_TO_OUT910 35 75 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT12 41 76 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT34 42 77 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT56 43 78 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT79 44 79 #define FR_SAFFIRE_CMD_ID_PC34_TO_OUT910 40 80 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT12 46 81 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT34 47 82 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT56 48 83 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT79 49 84 #define FR_SAFFIRE_CMD_ID_PC56_TO_OUT910 45 85 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT12 51 86 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT34 52 87 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT56 53 88 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT79 54 89 #define FR_SAFFIRE_CMD_ID_PC78_TO_OUT910 50 90 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT12 31 91 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT34 32 92 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT56 33 93 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT79 34 94 #define FR_SAFFIRE_CMD_ID_PC910_TO_OUT910 30 35 // no need for control id's, we can directly compute the addresses of the matrix mixer 36 /* 37 38 MIXER LAYOUT (): 39 40 OFFSET: 30 41 42 |-- Out9/10--| |-- Out1/2 --| |-- Out3/4 --| |-- Out5/6 --| |-- Out7/8 --| 43 P5 0: 0/ 0 1: 110/ 110 2: 0/ 0 3: 0/ 0 4: 0/ 0 44 P1 5: 0/ 0 6:32767/32767 7: 0/ 0 8: 0/ 0 9: 0/ 0 45 P2 10: 0/ 0 11: 0/ 0 12:32767/32767 13: 0/ 0 14: 0/ 0 46 P3 15: 0/ 0 16: 0/ 0 17: 0/ 0 18:32767/32767 19: 0/ 0 47 P4 20: 0/ 0 21: 0/ 0 22: 0/ 0 23: 0/ 0 24:32767/32767 48 R1 25: 0/ 0 26: 0/ 0 27: 0/ 0 28: 0/ 0 29: 0/ 0 49 R2 30: 0/ 0 31: 0/ 0 32: 0/ 0 33: 0/ 0 34: 0/ 0 50 Fx 35: 0/ 0 36: 0/ 0 37: 0/ 0 38: 0/ 0 39: 0/ 0 51 52 P5: DAW ch 9/10 53 P1: DAW ch 1/2 54 P2: DAW ch 3/4 55 P3: DAW ch 5/6 56 P4: DAW ch 7/8 57 R1: HW INPUT ch 1/2 / Reverb ch 1 58 R2: HW INPUT ch 3/4 / Reverb ch 2 59 Fx: reverb/fx return? / input mix 60 61 */ 95 62 96 63 // the control ID's … … 108 75 109 76 // other stuff 110 #define FR_SAFFIRE_CMD_ID_MONITOR_DIAL 61 111 #define FR_SAFFIRE_CMD_ID_SPDIF_SWITCH 62 77 #define FR_SAFFIRE_CMD_ID_MONITOR_DIAL 61 78 79 #define FR_SAFFIRE_CMD_ID_INPUT_SOURCE 62 80 #define FR_SAFFIRE_CMD_ID_INPUT_SOURCE_SPDIF 1 81 #define FR_SAFFIRE_CMD_ID_INPUT_SOURCE_ANALOG 0 82 83 #define FR_SAFFIRE_CMD_ID_MONO_MODE 63 84 #define FR_SAFFIRE_CMD_ID_MONO_MODE_STEREO 0 85 #define FR_SAFFIRE_CMD_ID_MONO_MODE_MONO 1 112 86 113 87 #define FR_SAFFIRE_CMD_ID_METERING_IN1 64 … … 116 90 #define FR_SAFFIRE_CMD_ID_METERING_IN4 67 117 91 118 #define FR_SAFFIRE_CMD_ID_SPDIF_DETECT 79 92 #define FR_SAFFIRE_CMD_ID_METERING_PC1 68 93 #define FR_SAFFIRE_CMD_ID_METERING_PC2 69 94 #define FR_SAFFIRE_CMD_ID_METERING_PC3 70 95 #define FR_SAFFIRE_CMD_ID_METERING_PC4 71 96 #define FR_SAFFIRE_CMD_ID_METERING_PC5 72 97 #define FR_SAFFIRE_CMD_ID_METERING_PC6 73 98 #define FR_SAFFIRE_CMD_ID_METERING_PC7 74 99 #define FR_SAFFIRE_CMD_ID_METERING_PC8 75 100 #define FR_SAFFIRE_CMD_ID_METERING_PC9 76 101 #define FR_SAFFIRE_CMD_ID_METERING_PC10 77 102 103 #define FR_SAFFIRE_CMD_ID_DEVICE_MODE 78 104 #define FR_SAFFIRE_CMD_ID_DEVICE_MODE_NORMAL 0 105 #define FR_SAFFIRE_CMD_ID_DEVICE_MODE_SCARD 1 106 107 #define FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK 79 108 #define FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS 80 109 #define FR_SAFFIRE_CMD_ID_SAVE_SETTINGS 82 110 111 #define FR_SAFFIRELE_CMD_ID_DSP_REVISION 1022 112 #define FR_SAFFIRELE_CMD_ID_DSP_VERSION 1023 119 113 120 114 // -- Saffire LE -- … … 257 251 public: 258 252 enum eMatrixMixerType { 259 eMMT_ InputMix,260 eMMT_ PCMix,253 eMMT_SaffireStereoMatrixMix, 254 eMMT_SaffireMonoMatrixMix, 261 255 eMMT_LEMix48, 262 256 eMMT_LEMix96, trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp
r1253 r1336 26 26 27 27 #include "devicemanager.h" 28 #include "libutil/ Time.h"28 #include "libutil/SystemTimeSource.h" 29 29 30 30 #include "libutil/ByteSwap.h" … … 367 367 void 368 368 SaffireProDevice::updateClockSources() { 369 m_active_clocksource = &m_internal_clocksource; 370 369 371 m_internal_clocksource.type = FFADODevice::eCT_Internal; 372 m_internal_clocksource.active = false; 370 373 m_internal_clocksource.valid = true; 371 374 m_internal_clocksource.locked = true; … … 375 378 376 379 m_spdif_clocksource.type = FFADODevice::eCT_SPDIF; 380 m_spdif_clocksource.active = false; 377 381 m_spdif_clocksource.valid = true; 378 382 m_spdif_clocksource.locked = false; … … 382 386 383 387 m_wordclock_clocksource.type = FFADODevice::eCT_WordClock; 388 m_wordclock_clocksource.active = false; 384 389 m_wordclock_clocksource.valid = true; 385 390 m_wordclock_clocksource.locked = false; … … 390 395 if(isPro26()) { 391 396 m_adat1_clocksource.type = FFADODevice::eCT_ADAT; 397 m_adat1_clocksource.active = false; 392 398 m_adat1_clocksource.valid = true; 393 399 m_adat1_clocksource.locked = false; … … 397 403 398 404 m_adat2_clocksource.type = FFADODevice::eCT_ADAT; 405 m_adat2_clocksource.active = false; 399 406 m_adat2_clocksource.valid = true; 400 407 m_adat2_clocksource.locked = false; … … 403 410 m_adat2_clocksource.description = "ADAT 2"; 404 411 } 405 } 406 407 FFADODevice::ClockSource 408 SaffireProDevice::getActiveClockSource() 409 { 412 413 // figure out the active source 410 414 uint32_t sync; 411 415 if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG, &sync ) ){ 412 416 debugError( "getSpecificValue failed\n" ); 413 return ClockSource(); 414 } 415 416 updateClockSources(); // make sure the current state is reflected in the clocksources 417 418 switch(sync) { 419 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 420 return m_internal_clocksource; 421 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 422 return m_spdif_clocksource; 423 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 424 return m_adat1_clocksource; 425 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 426 return m_adat2_clocksource; 427 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 428 return m_wordclock_clocksource; 417 m_internal_clocksource.active=true; 418 return; 419 } 420 debugOutput(DEBUG_LEVEL_VERBOSE, "SYNC_CONFIG field value: %08lX\n", sync ); 421 422 switch(sync & 0xFF) { 429 423 default: 430 424 debugWarning( "Unexpected SYNC_CONFIG field value: %08lX\n", sync ); 431 return ClockSource(); 432 } 425 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 426 m_internal_clocksource.active=true; 427 m_active_clocksource = &m_internal_clocksource; 428 break; 429 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 430 m_spdif_clocksource.active=true; 431 m_active_clocksource = &m_spdif_clocksource; 432 break; 433 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 434 m_wordclock_clocksource.active=true; 435 m_active_clocksource = &m_wordclock_clocksource; 436 break; 437 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 438 m_adat1_clocksource.active=true; 439 m_active_clocksource = &m_adat1_clocksource; 440 break; 441 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 442 m_adat2_clocksource.active=true; 443 m_active_clocksource = &m_adat2_clocksource; 444 break; 445 } 446 switch((sync >> 8) & 0xFF) { 447 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_INTERNAL: 448 // always locked 449 break; 450 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_SPDIF: 451 m_spdif_clocksource.locked=true; 452 break; 453 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT1: 454 m_wordclock_clocksource.locked=true; 455 break; 456 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_ADAT2: 457 m_adat1_clocksource.locked=true; 458 break; 459 case FR_SAFFIREPRO_CMD_SYNC_CONFIG_WORDCLOCK: 460 m_adat2_clocksource.locked=true; 461 break; 462 default: 463 debugWarning( "Unexpected SYNC_CONFIG_STATE field value: %08lX\n", sync ); 464 } 465 } 466 467 FFADODevice::ClockSource 468 SaffireProDevice::getActiveClockSource() 469 { 470 updateClockSources(); 471 return *m_active_clocksource; 433 472 } 434 473 … … 436 475 SaffireProDevice::setActiveClockSource(ClockSource s) 437 476 { 477 // prevent busresets from being handled immediately 478 getDeviceManager().lockBusResetHandler(); 479 unsigned int gen_before = get1394Service().getGeneration(); 480 481 debugOutput(DEBUG_LEVEL_VERBOSE, "set active source to %d...\n", s.id); 438 482 if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_SYNC_CONFIG, s.id ) ){ 439 debugError( "detSpecificValue failed\n" ); 440 return false; 441 } 483 debugError( "setSpecificValue failed\n" ); 484 getDeviceManager().unlockBusResetHandler(); 485 return false; 486 } 487 488 // the device can do a bus reset at this moment 489 Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 490 if(!get1394Service().waitForBusResetStormToEnd(10, 2000)) { 491 debugWarning("Device doesn't stop bus-resetting\n"); 492 } 493 unsigned int gen_after = get1394Service().getGeneration(); 494 debugOutput(DEBUG_LEVEL_VERBOSE, " gen: %d=>%d\n", gen_before, gen_after); 495 496 getDeviceManager().unlockBusResetHandler(); 442 497 return true; 443 498 } … … 446 501 SaffireProDevice::getSupportedClockSources() 447 502 { 503 debugOutput(DEBUG_LEVEL_VERBOSE, "listing...\n"); 448 504 FFADODevice::ClockSourceVector r; 449 505 r.push_back(m_internal_clocksource); … … 571 627 const int max_tries = 2; 572 628 int ntries = max_tries+1; 573 574 // FIXME: not very clean 575 getDeviceManager().ignoreBusResets(true); 576 629 630 // the device behaves like a pig when changing samplerate, 631 // generating a bunch of bus-resets. 632 // we don't want the busreset handler to run while we are 633 // changing the samplerate. however it has to run after the 634 // device finished, since the bus resets might have influenced 635 // other attached devices. 636 getDeviceManager().lockBusResetHandler(); 577 637 unsigned int gen_before = get1394Service().getGeneration(); 578 638 579 639 while(--ntries) { 580 640 if (rebootOnSamplerateChange) { … … 587 647 588 648 // the device needs quite some time to reboot 589 SleepRelativeUsec(2 * 1000 * 1000);649 Util::SystemTimeSource::SleepUsecRelative(2 * 1000 * 1000); 590 650 591 651 int timeout = 5; // multiples of 1s … … 595 655 { 596 656 // wait for a while 597 SleepRelativeUsec(1000 * 1000);657 Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 598 658 } 599 659 if (!timeout) { … … 602 662 603 663 // the device needs quite some time to reboot 604 SleepRelativeUsec(2 * 1000 * 1000);664 Util::SystemTimeSource::SleepUsecRelative(2 * 1000 * 1000); 605 665 606 666 // wait for the device to finish the reboot … … 610 670 { 611 671 // wait for a while 612 SleepRelativeUsec(1000 * 1000);672 Util::SystemTimeSource::SleepUsecRelative(1000 * 1000); 613 673 } 614 674 if (!timeout) { 615 675 debugError( "Device did not reset itself after forced reboot...\n"); 676 getDeviceManager().unlockBusResetHandler(); 616 677 return false; 617 678 } … … 620 681 // so we know the device is rebooting 621 682 // now wait until it stops generating busresets 622 timeout = 10; 623 unsigned int gen_current; 624 do { 625 gen_current=get1394Service().getGeneration(); 626 debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting... (gen: %u)\n", gen_current); 627 628 // wait for a while 629 SleepRelativeUsec(4 * 1000 * 1000); 630 } while (gen_current != get1394Service().getGeneration() 631 && --timeout); 632 633 if (!timeout) { 634 debugError( "Device did not recover from reboot...\n"); 683 if(!get1394Service().waitForBusResetStormToEnd(20, 4000)) { 684 debugError("The device keeps behaving like a pig...\n"); 685 getDeviceManager().unlockBusResetHandler(); 635 686 return false; 636 687 } 637 638 688 debugOutput(DEBUG_LEVEL_VERBOSE, "Device available (gen: %u => %u)...\n", 639 689 gen_before, get1394Service().getGeneration()); 640 690 641 691 // wait some more 642 SleepRelativeUsec(1 * 1000 * 1000);692 Util::SystemTimeSource::SleepUsecRelative(1 * 1000 * 1000); 643 693 644 694 // we have to rediscover the device … … 651 701 } 652 702 653 int verify =getSamplingFrequency();703 int verify = getSamplingFrequency(); 654 704 debugOutput( DEBUG_LEVEL_VERBOSE, 655 705 "setSampleRate (try %d): requested samplerate %d, device now has %d\n", … … 662 712 } 663 713 664 // FIXME: not very clean665 getDeviceManager(). ignoreBusResets(false);714 // make the busreset handlers run 715 getDeviceManager().unlockBusResetHandler(); 666 716 667 717 if (ntries==0) { trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.h
r1253 r1336 421 421 ClockSource m_adat1_clocksource; 422 422 ClockSource m_adat2_clocksource; 423 ClockSource *m_active_clocksource; 423 424 424 425 Control::Container *m_MixerContainer; trunk/libffado/src/devicemanager.cpp
r1254 r1336 32 32 #include "libieee1394/configrom.h" 33 33 #include "libieee1394/ieee1394service.h" 34 #include "libieee1394/IsoHandlerManager.h" 34 35 35 36 #include "libstreaming/generic/StreamProcessor.h" … … 85 86 DeviceManager::DeviceManager() 86 87 : Control::Container(NULL, "devicemanager") // this is the control root node 87 , m_ avDevicesLock( new Util::PosixMutex() )88 , m_BusResetLock( new Util::PosixMutex( ) )89 , m_processorManager( new Streaming::StreamProcessorManager( ) )88 , m_DeviceListLock( new Util::PosixMutex("DEVLST") ) 89 , m_BusResetLock( new Util::PosixMutex("DEVBR") ) 90 , m_processorManager( new Streaming::StreamProcessorManager( *this ) ) 90 91 , m_deviceStringParser( new DeviceStringParser() ) 92 , m_configuration ( new Util::Configuration() ) 91 93 , m_used_cache_last_time( false ) 92 , m_ignore_busreset( false )93 94 , m_thread_realtime( false ) 94 95 , m_thread_priority( 0 ) … … 100 101 DeviceManager::~DeviceManager() 101 102 { 102 m_avDevicesLock->Lock(); // make sure nobody is using this 103 // save configuration 104 if(!m_configuration->save()) { 105 debugWarning("could not save configuration\n"); 106 } 107 108 m_BusResetLock->Lock(); // make sure we are not handling a busreset. 109 m_DeviceListLock->Lock(); // make sure nobody is using this 103 110 for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 104 111 it != m_avDevices.end(); … … 110 117 delete *it; 111 118 } 112 m_avDevicesLock->Unlock(); 113 delete m_avDevicesLock; 119 m_DeviceListLock->Unlock(); 114 120 115 121 // the SP's are automatically unregistered from the SPM 116 122 delete m_processorManager; 117 123 124 // the device list is empty, so wake up any waiting 125 // reset handlers 126 m_BusResetLock->Unlock(); 127 128 // remove the bus-reset handlers 118 129 for ( FunctorVectorIterator it = m_busreset_functors.begin(); 119 130 it != m_busreset_functors.end(); … … 122 133 delete *it; 123 134 } 124 delete m_BusResetLock;125 135 126 136 for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin(); … … 131 141 } 132 142 143 delete m_DeviceListLock; 144 delete m_BusResetLock; 133 145 delete m_deviceStringParser; 134 146 } … … 159 171 assert(m_1394Services.size() == 0); 160 172 assert(m_busreset_functors.size() == 0); 173 174 m_configuration->openFile( "temporary", Util::Configuration::eFM_Temporary ); 175 m_configuration->openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadWrite ); 176 m_configuration->openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 161 177 162 178 int nb_detected_ports = Ieee1394Service::detectNbPorts(); … … 185 201 } 186 202 // add the bus reset handler 187 Util::Functor* tmp_busreset_functor = new Util::MemberFunctor 0< DeviceManager*,188 void (DeviceManager::*)( )>189 ( this, &DeviceManager::busresetHandler, false );203 Util::Functor* tmp_busreset_functor = new Util::MemberFunctor1< DeviceManager*, 204 void (DeviceManager::*)(Ieee1394Service &), Ieee1394Service & > 205 ( this, &DeviceManager::busresetHandler, *tmp1394Service, false ); 190 206 if ( !tmp_busreset_functor ) { 191 207 debugFatal( "Could not create busreset handler for port %d\n", port ); … … 221 237 222 238 void 223 DeviceManager::busresetHandler( )239 DeviceManager::busresetHandler(Ieee1394Service &service) 224 240 { 225 241 // serialize bus reset handling since it can be that a new one occurs while we're 226 242 // doing stuff. 243 debugOutput( DEBUG_LEVEL_NORMAL, "Bus reset detected on service %p...\n", &service ); 227 244 Util::MutexLockHelper lock(*m_BusResetLock); 228 debugOutput( DEBUG_LEVEL_VERBOSE, "Bus reset...\n" ); 229 if(m_ignore_busreset) { 230 debugOutput( DEBUG_LEVEL_VERBOSE, " ignoring...\n" ); 231 return; 232 } 233 234 // FIXME: what port was the bus reset on? 235 // FIXME: what if the devices are gone? 245 debugOutput( DEBUG_LEVEL_NORMAL, " handling busreset...\n" ); 246 247 // FIXME: what if the devices are gone? (device should detect this!) 236 248 // propagate the bus reset to all avDevices 237 m_ avDevicesLock->Lock(); // make sure nobody is using this249 m_DeviceListLock->Lock(); // make sure nobody is using this 238 250 for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 239 251 it != m_avDevices.end(); 240 252 ++it ) 241 253 { 242 (*it)->handleBusReset(); 243 } 244 m_avDevicesLock->Unlock(); 254 if(&service == &((*it)->get1394Service())) { 255 debugOutput(DEBUG_LEVEL_NORMAL, 256 "issue busreset on device GUID %s\n", 257 (*it)->getConfigRom().getGuidString().c_str()); 258 (*it)->handleBusReset(); 259 } else { 260 debugOutput(DEBUG_LEVEL_NORMAL, 261 "skipping device GUID %s since not on service %p\n", 262 (*it)->getConfigRom().getGuidString().c_str(), &service); 263 } 264 } 265 m_DeviceListLock->Unlock(); 266 267 // now that the devices have been updates, we can request to update the iso streams 268 if(!service.getIsoHandlerManager().handleBusReset()) { 269 debugError("IsoHandlerManager failed to handle busreset\n"); 270 } 245 271 246 272 // notify the streamprocessormanager of the busreset 247 if(m_processorManager) {248 m_processorManager->handleBusReset();249 } else {250 debugWarning("No valid SPM\n");251 }273 // if(m_processorManager) { 274 // m_processorManager->handleBusReset(service); 275 // } else { 276 // debugWarning("No valid SPM\n"); 277 // } 252 278 253 279 // rediscover to find new devices … … 261 287 262 288 // display the new state 263 showDeviceInfo(); 289 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) { 290 showDeviceInfo(); 291 } 264 292 } 265 293 … … 317 345 DeviceManager::discover( bool useCache, bool rediscover ) 318 346 { 347 debugOutput( DEBUG_LEVEL_NORMAL, "Starting discovery...\n" ); 319 348 useCache = useCache && ENABLE_DISCOVERY_CACHE; 320 349 m_used_cache_last_time = useCache; … … 370 399 // notify that we are going to manipulate the list 371 400 signalNotifiers(m_preUpdateNotifiers); 372 m_ avDevicesLock->Lock(); // make sure nobody starts using the list401 m_DeviceListLock->Lock(); // make sure nobody starts using the list 373 402 if(rediscover) { 374 403 … … 635 664 } 636 665 637 m_ avDevicesLock->Unlock();666 m_DeviceListLock->Unlock(); 638 667 // notify any clients 639 668 signalNotifiers(m_postUpdateNotifiers); … … 825 854 #ifdef ENABLE_BEBOB 826 855 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" ); 827 if ( BeBoB::AvDevice::probe( *configRom, generic ) ) {856 if ( BeBoB::AvDevice::probe( getConfiguration(), *configRom, generic ) ) { 828 857 return BeBoB::AvDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 829 858 } … … 832 861 #ifdef ENABLE_FIREWORKS 833 862 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" ); 834 if ( FireWorks::Device::probe( *configRom, generic ) ) {863 if ( FireWorks::Device::probe( getConfiguration(), *configRom, generic ) ) { 835 864 return FireWorks::Device::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 836 865 } … … 840 869 #ifdef ENABLE_GENERICAVC 841 870 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" ); 842 if ( GenericAVC::AvDevice::probe( *configRom, generic ) ) {871 if ( GenericAVC::AvDevice::probe( getConfiguration(), *configRom, generic ) ) { 843 872 return GenericAVC::AvDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 844 873 } … … 847 876 #ifdef ENABLE_MOTU 848 877 debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" ); 849 if ( Motu::MotuDevice::probe( *configRom, generic ) ) {878 if ( Motu::MotuDevice::probe( getConfiguration(), *configRom, generic ) ) { 850 879 return Motu::MotuDevice::createDevice( *this, std::auto_ptr<ConfigRom>( configRom ) ); 851 880 } … … 1018 1047 } 1019 1048 1020 1021 1049 void 1022 1050 DeviceManager::setVerboseLevel(int l) … … 1026 1054 m_processorManager->setVerboseLevel(l); 1027 1055 m_deviceStringParser->setVerboseLevel(l); 1056 m_configuration->setVerboseLevel(l); 1028 1057 for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 1029 1058 it != m_avDevices.end(); trunk/libffado/src/devicemanager.h
r1239 r1336 38 38 #include "libutil/Functors.h" 39 39 #include "libutil/Mutex.h" 40 #include "libutil/Configuration.h" 40 41 41 42 #include <vector> … … 105 106 Streaming::StreamProcessor *getSyncSource(); 106 107 107 void ignoreBusResets(bool b) {m_ignore_busreset = b;}; 108 /** 109 * prevents the busreset handler from running. use with care! 110 */ 111 void lockBusResetHandler() {m_BusResetLock->Lock();}; 112 /** 113 * releases the busreset handlers 114 */ 115 void unlockBusResetHandler() {m_BusResetLock->Unlock();}; 108 116 bool registerBusresetNotification(Util::Functor *f) 109 117 {return registerNotification(m_busResetNotifiers, f);}; … … 120 128 bool unregisterPostUpdateNotification(Util::Functor *f) 121 129 {return unregisterNotification(m_postUpdateNotifiers, f);}; 130 131 132 Util::Configuration& getConfiguration() {return *m_configuration;}; 122 133 123 134 void showDeviceInfo(); … … 137 148 FFADODevice* getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) ); 138 149 139 void busresetHandler( );150 void busresetHandler(Ieee1394Service &); 140 151 141 152 protected: … … 147 158 148 159 // the lock protecting the device list 149 Util::Mutex* m_ avDevicesLock;160 Util::Mutex* m_DeviceListLock; 150 161 // the lock to serialize bus reset handling 151 162 Util::Mutex* m_BusResetLock; … … 157 168 Streaming::StreamProcessorManager* m_processorManager; 158 169 DeviceStringParser* m_deviceStringParser; 170 Util::Configuration* m_configuration; 159 171 bool m_used_cache_last_time; 160 bool m_ignore_busreset;161 172 162 173 typedef std::vector< Util::Functor* > notif_vec_t; trunk/libffado/src/dice/dice_avdevice.cpp
r1333 r1336 190 190 191 191 return samplingFrequency; 192 } 193 194 #define DICE_CHECK_AND_ADD_SR(v, x, reg) \ 195 { if(maskedCheckNotZeroGlobalReg( DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, reg)) \ 196 v.push_back(x); } 197 std::vector<int> 198 DiceAvDevice::getSupportedSamplingFrequencies() 199 { 200 std::vector<int> frequencies; 201 DICE_CHECK_AND_ADD_SR(frequencies, 32000, DICE_CLOCKCAP_RATE_32K); 202 DICE_CHECK_AND_ADD_SR(frequencies, 44100, DICE_CLOCKCAP_RATE_44K1); 203 DICE_CHECK_AND_ADD_SR(frequencies, 48000, DICE_CLOCKCAP_RATE_48K); 204 DICE_CHECK_AND_ADD_SR(frequencies, 88200, DICE_CLOCKCAP_RATE_88K2); 205 DICE_CHECK_AND_ADD_SR(frequencies, 96000, DICE_CLOCKCAP_RATE_96K); 206 DICE_CHECK_AND_ADD_SR(frequencies, 176400, DICE_CLOCKCAP_RATE_176K4); 207 DICE_CHECK_AND_ADD_SR(frequencies, 192000, DICE_CLOCKCAP_RATE_192K); 208 return frequencies; 192 209 } 193 210 trunk/libffado/src/dice/dice_avdevice.h
r1239 r1336 70 70 virtual bool setSamplingFrequency( int samplingFrequency ); 71 71 virtual int getSamplingFrequency( ); 72 virtual std::vector<int> getSupportedSamplingFrequencies(); 72 73 73 74 virtual ClockSourceVector getSupportedClockSources(); trunk/libffado/src/fbtypes.h
r864 r1336 27 27 #include <libraw1394/raw1394.h> 28 28 29 #define INVALID_NODE_ID 0xFF 30 29 31 typedef quadlet_t fb_quadlet_t; 30 32 typedef byte_t fb_byte_t; trunk/libffado/src/ffado.cpp
r1254 r1336 98 98 99 99 printMessage("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 100 101 #if DEBUG_USE_MESSAGE_BUFFER 102 // ok 103 #else 104 printMessage("FFADO built without realtime-safe message buffer support. This can cause xruns and is not recommended.\n"); 105 #endif 100 106 101 107 if(!dev) { trunk/libffado/src/ffadodevice.h
r1129 r1336 42 42 namespace Streaming { 43 43 class StreamProcessor; 44 class StreamProcessorManager;45 44 } 46 45 … … 139 138 */ 140 139 virtual int getSamplingFrequency( ) = 0; 140 141 /** 142 * @brief get the supported sampling frequencies 143 * @return a vector containing the supported sampling frequencies 144 */ 145 virtual std::vector<int> getSupportedSamplingFrequencies( ) = 0; 141 146 142 147 /** trunk/libffado/src/fireworks/efc/efc_cmd.h
r1234 r1336 104 104 105 105 // specifiers for the flags field 106 #define EFC_CMD_HW_DYNADDR_SUPPORTED 1107 #define EFC_CMD_HW_MIRRORING_SUPPORTED 2108 #define EFC_CMD_HW_SPDIF_COAX_SUPPORTED 3109 #define EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED 4110 #define EFC_CMD_HW_HAS_DSP 5111 #define EFC_CMD_HW_HAS_FPGA 6112 #define EFC_CMD_HW_HAS_PHANTOM 7106 #define EFC_CMD_HW_DYNADDR_SUPPORTED 0 107 #define EFC_CMD_HW_MIRRORING_SUPPORTED 1 108 #define EFC_CMD_HW_SPDIF_COAX_SUPPORTED 2 109 #define EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED 3 110 #define EFC_CMD_HW_HAS_DSP 4 111 #define EFC_CMD_HW_HAS_FPGA 5 112 #define EFC_CMD_HW_HAS_PHANTOM 6 113 113 114 114 #define EFC_CMD_HW_CHECK_FLAG(__val__,__flag__) \ trunk/libffado/src/fireworks/efc/efc_cmds_hardware.h
r864 r1336 53 53 virtual void showEfcCmd(); 54 54 55 bool hasSoftwarePhantom() 55 bool hasSoftwarePhantom() const 56 56 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_PHANTOM);}; 57 bool hasDSP() 57 bool hasDSP() const 58 58 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_DSP);}; 59 bool hasFPGA() 59 bool hasFPGA() const 60 60 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_HAS_FPGA);}; 61 bool hasSpdifCoax() 61 bool hasSpdifCoax() const 62 62 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_SPDIF_COAX_SUPPORTED);}; 63 bool hasSpdifAESEBUXLR() 63 bool hasSpdifAESEBUXLR() const 64 64 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_SPDIF_AESEBUXLR_SUPPORTED);}; 65 bool hasMirroring() 65 bool hasMirroring() const 66 66 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_MIRRORING_SUPPORTED);}; 67 bool hasDynAddr() 67 bool hasDynAddr() const 68 68 {return EFC_CMD_HW_CHECK_FLAG(m_flags, EFC_CMD_HW_DYNADDR_SUPPORTED);}; 69 69 trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.cpp
r1136 r1336 166 166 } 167 167 168 // -- get flags 169 EfcGetFlagsCmd::EfcGetFlagsCmd() 170 : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_GET_FLAGS) 171 , m_flags ( 0 ) 172 { 173 } 174 175 bool 176 EfcGetFlagsCmd::serialize( Util::Cmd::IOSSerialize& se ) 177 { 178 bool result=true; 179 180 // the length should be specified before 181 // the header is serialized 182 m_length=EFC_HEADER_LENGTH_QUADLETS; 183 184 result &= EfcCmd::serialize ( se ); 185 186 return result; 187 } 188 189 bool 190 EfcGetFlagsCmd::deserialize( Util::Cmd::IISDeserialize& de ) 191 { 192 bool result=true; 193 194 result &= EfcCmd::deserialize ( de ); 195 196 EFC_DESERIALIZE_AND_SWAP(de, &m_flags, result); 197 198 return result; 199 } 200 201 void 202 EfcGetFlagsCmd::showEfcCmd() 203 { 204 EfcCmd::showEfcCmd(); 205 debugOutput(DEBUG_LEVEL_NORMAL, "EFC Get Flags:\n"); 206 debugOutput(DEBUG_LEVEL_NORMAL, " Flags : %08X\n", m_flags); 207 } 208 209 // ---- 210 EfcChangeFlagsCmd::EfcChangeFlagsCmd() 211 : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_CHANGE_FLAGS) 212 , m_setmask ( 0 ) 213 , m_clearmask ( 0 ) 214 { 215 } 216 217 bool 218 EfcChangeFlagsCmd::serialize( Util::Cmd::IOSSerialize& se ) 219 { 220 bool result=true; 221 222 // the length should be specified before 223 // the header is serialized 224 m_length=EFC_HEADER_LENGTH_QUADLETS+2; 225 226 result &= EfcCmd::serialize ( se ); 227 228 result &= se.write(CondSwapToBus32(m_setmask), "SetMask" ); 229 result &= se.write(CondSwapToBus32(m_clearmask), "ClearMask" ); 230 231 return result; 232 } 233 234 bool 235 EfcChangeFlagsCmd::deserialize( Util::Cmd::IISDeserialize& de ) 236 { 237 bool result=true; 238 result &= EfcCmd::deserialize ( de ); 239 return result; 240 } 241 242 void 243 EfcChangeFlagsCmd::showEfcCmd() 244 { 245 EfcCmd::showEfcCmd(); 246 debugOutput(DEBUG_LEVEL_NORMAL, "EFC Change flags:\n"); 247 debugOutput(DEBUG_LEVEL_NORMAL, " Set mask : %08X\n", m_setmask); 248 debugOutput(DEBUG_LEVEL_NORMAL, " Clear mask : %08X\n", m_clearmask); 249 } 250 251 252 // ---- 253 EfcIdentifyCmd::EfcIdentifyCmd() 254 : EfcCmd(EFC_CAT_HARDWARE_CONTROL, EFC_CMD_HWCTRL_IDENTIFY) 255 { 256 } 257 258 bool 259 EfcIdentifyCmd::serialize( Util::Cmd::IOSSerialize& se ) 260 { 261 bool result=true; 262 263 // the length should be specified before 264 // the header is serialized 265 m_length=EFC_HEADER_LENGTH_QUADLETS; 266 267 result &= EfcCmd::serialize ( se ); 268 269 return result; 270 } 271 272 bool 273 EfcIdentifyCmd::deserialize( Util::Cmd::IISDeserialize& de ) 274 { 275 bool result=true; 276 277 result &= EfcCmd::deserialize ( de ); 278 279 return result; 280 } 281 282 void 283 EfcIdentifyCmd::showEfcCmd() 284 { 285 EfcCmd::showEfcCmd(); 286 debugOutput(DEBUG_LEVEL_NORMAL, "EFC Identify\n"); 287 } 288 168 289 } // namespace FireWorks trunk/libffado/src/fireworks/efc/efc_cmds_hardware_ctrl.h
r864 r1336 28 28 29 29 namespace FireWorks { 30 31 #define FIREWORKS_EFC_FLAG_MIXER_ENABLED 1 32 #define FIREWORKS_EFC_FLAG_SPDIF_PRO 2 33 #define FIREWORKS_EFC_FLAG_SPDIF_RAW 4 30 34 31 35 class EfcGetClockCmd : public EfcCmd … … 82 86 }; 83 87 88 89 class EfcGetFlagsCmd : public EfcCmd 90 { 91 public: 92 EfcGetFlagsCmd(); 93 virtual ~EfcGetFlagsCmd() {}; 94 95 virtual bool serialize( Util::Cmd::IOSSerialize& se ); 96 virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 97 98 virtual const char* getCmdName() const 99 { return "EfcGetFlagsCmd"; } 100 101 virtual void showEfcCmd(); 102 103 uint32_t m_flags; 104 }; 105 106 class EfcChangeFlagsCmd : public EfcCmd 107 { 108 public: 109 EfcChangeFlagsCmd(); 110 virtual ~EfcChangeFlagsCmd() {}; 111 112 virtual bool serialize( Util::Cmd::IOSSerialize& se ); 113 virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 114 115 virtual const char* getCmdName() const 116 { return "EfcChangeFlagsCmd"; } 117 118 virtual void showEfcCmd(); 119 120 uint32_t m_setmask; 121 uint32_t m_clearmask; 122 }; 123 124 class EfcIdentifyCmd : public EfcCmd 125 { 126 public: 127 EfcIdentifyCmd(); 128 virtual ~EfcIdentifyCmd() {}; 129 130 virtual bool serialize( Util::Cmd::IOSSerialize& se ); 131 virtual bool deserialize( Util::Cmd::IISDeserialize& de ); 132 133 virtual const char* getCmdName() const 134 { return "EfcIdentifyCmd"; } 135 136 virtual void showEfcCmd(); 137 138 }; 139 84 140 } // namespace FireWorks 85 141 trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.cpp
r1136 r1336 37 37 , m_reg ( r ) 38 38 { 39 m_category_id = EFC_CAT_IO_CONFIG; 39 40 m_type=eCT_Get; 40 41 setRegister(r); trunk/libffado/src/fireworks/efc/efc_cmds_ioconfig.h
r864 r1336 29 29 namespace FireWorks { 30 30 31 #define EFC_MAX_ISOC_MAP_ENTRIES 32 32 typedef struct tag_efc_isoc_map 33 { 34 uint32_t samplerate; 35 uint32_t flags; 36 37 uint32_t num_playmap_entries; 38 uint32_t num_phys_out; 39 int32_t playmap[ EFC_MAX_ISOC_MAP_ENTRIES ]; 40 41 uint32_t num_recmap_entries; 42 uint32_t num_phys_in; 43 int32_t recmap[ EFC_MAX_ISOC_MAP_ENTRIES ]; 44 } IsoChannelMap; 45 31 46 class EfcGenericIOConfigCmd : public EfcCmd 32 47 { … … 46 61 47 62 virtual const char* getCmdName() const 48 { return "EfcGenericIOConfigCmd"; } 63 { return "EfcGenericIOConfigCmd"; }; 49 64 50 uint32_t 65 uint32_t m_value; 51 66 52 67 private: trunk/libffado/src/fireworks/fireworks_control.cpp
r1158 r1336 28 28 #include "efc/efc_cmds_mixer.h" 29 29 #include "efc/efc_cmds_monitor.h" 30 #include "efc/efc_cmds_hardware_ctrl.h" 30 31 31 32 #include <string> … … 40 41 : Control::MatrixMixer(&p, "MonitorControl") 41 42 , m_control(c) 42 , m_Parent (p)43 , m_ParentDevice(p) 43 44 { 44 45 } … … 47 48 : Control::MatrixMixer(&p, n) 48 49 , m_control(c) 49 , m_Parent (p)50 , m_ParentDevice(p) 50 51 { 51 52 } … … 86 87 bool did_command=false; 87 88 88 if(row >= (int)m_Parent .getHwInfo().m_nb_phys_audio_in) {89 if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) { 89 90 debugError("specified row (%u) larger than number of rows (%d)\n", 90 row, m_Parent .getHwInfo().m_nb_phys_audio_in);91 row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in); 91 92 return 0.0; 92 93 } 93 if(col >= (int)m_Parent .getHwInfo().m_nb_phys_audio_out) {94 if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) { 94 95 debugError("specified col (%u) larger than number of cols (%d)\n", 95 col, m_Parent .getHwInfo().m_nb_phys_audio_out);96 col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out); 96 97 return 0.0; 97 98 } 98 99 100 // not a switch since we create variables 99 101 if(m_control==eMC_Gain) { 100 102 EfcSetMonitorGainCmd setCmd; 101 setCmd.m_input=row; 102 setCmd.m_output=col; 103 setCmd.m_value=(uint32_t)val; 104 if (!m_Parent.doEfcOverAVC(setCmd)) 105 { 106 debugFatal("Cmd failed\n"); 107 } 108 retval=setCmd.m_value; 109 did_command=true; 103 setCmd.m_input = row; 104 setCmd.m_output = col; 105 setCmd.m_value = (uint32_t)val; 106 if (!m_ParentDevice.doEfcOverAVC(setCmd)) 107 { 108 debugError("Cmd failed\n"); 109 } 110 // update the session block 111 m_ParentDevice.m_session.h.monitorgains[row][col] = setCmd.m_value; 112 retval = setCmd.m_value; 113 did_command = true; 110 114 } 111 115 if(m_control==eMC_Pan) { 112 116 EfcSetMonitorPanCmd setCmd; 113 setCmd.m_input=row; 114 setCmd.m_output=col; 115 setCmd.m_value=(uint32_t)val; 116 if (!m_Parent.doEfcOverAVC(setCmd)) 117 { 118 debugFatal("Cmd failed\n"); 119 } 120 retval=setCmd.m_value; 121 did_command=true; 117 setCmd.m_input = row; 118 setCmd.m_output = col; 119 setCmd.m_value = (uint32_t)val; 120 if (!m_ParentDevice.doEfcOverAVC(setCmd)) 121 { 122 debugError("Cmd failed\n"); 123 } 124 // update the session block 125 m_ParentDevice.m_session.s.monitorpans[row][col] = setCmd.m_value; 126 retval = setCmd.m_value; 127 did_command = true; 122 128 } 123 129 if(m_control==eMC_Mute) { 124 130 EfcSetMonitorMuteCmd setCmd; 125 setCmd.m_input=row; 126 setCmd.m_output=col; 127 setCmd.m_value=(uint32_t)val; 128 if (!m_Parent.doEfcOverAVC(setCmd)) 129 { 130 debugFatal("Cmd failed\n"); 131 } 132 retval=setCmd.m_value; 133 did_command=true; 131 setCmd.m_input = row; 132 setCmd.m_output = col; 133 setCmd.m_value = (uint32_t)val; 134 if (!m_ParentDevice.doEfcOverAVC(setCmd)) 135 { 136 debugError("Cmd failed\n"); 137 } 138 // update the session block 139 if(setCmd.m_value) { 140 m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_MUTE_BIT; 141 } else { 142 m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_MUTE_BIT; 143 } 144 retval = setCmd.m_value; 145 did_command = true; 134 146 } 135 147 if(m_control==eMC_Solo) { 136 148 EfcSetMonitorSoloCmd setCmd; 137 setCmd.m_input=row; 138 setCmd.m_output=col; 139 setCmd.m_value=(uint32_t)val; 140 if (!m_Parent.doEfcOverAVC(setCmd)) 141 { 142 debugFatal("Cmd failed\n"); 143 } 144 retval=setCmd.m_value; 145 did_command=true; 149 setCmd.m_input = row; 150 setCmd.m_output = col; 151 setCmd.m_value = (uint32_t)val; 152 if (!m_ParentDevice.doEfcOverAVC(setCmd)) 153 { 154 debugError("Cmd failed\n"); 155 } 156 // update the session block 157 if(setCmd.m_value) { 158 m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_SOLO_BIT; 159 } else { 160 m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_SOLO_BIT; 161 } 162 retval = setCmd.m_value; 163 did_command = true; 146 164 } 147 165 … … 160 178 bool did_command=false; 161 179 162 if(row >= (int)m_Parent .getHwInfo().m_nb_phys_audio_in) {180 if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) { 163 181 debugError("specified row (%u) larger than number of rows (%d)\n", 164 row, m_Parent .getHwInfo().m_nb_phys_audio_in);182 row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in); 165 183 return 0.0; 166 184 } 167 if(col >= (int)m_Parent .getHwInfo().m_nb_phys_audio_out) {185 if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) { 168 186 debugError("specified col (%u) larger than number of cols (%d)\n", 169 col, m_Parent .getHwInfo().m_nb_phys_audio_out);187 col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out); 170 188 return 0.0; 171 189 } … … 175 193 getCmd.m_input=row; 176 194 getCmd.m_output=col; 177 if (!m_Parent .doEfcOverAVC(getCmd))178 { 179 debug Fatal("Cmd failed\n");195 if (!m_ParentDevice.doEfcOverAVC(getCmd)) 196 { 197 debugError("Cmd failed\n"); 180 198 } 181 199 retval=getCmd.m_value; … … 186 204 getCmd.m_input=row; 187 205 getCmd.m_output=col; 188 if (!m_Parent .doEfcOverAVC(getCmd))189 { 190 debug Fatal("Cmd failed\n");206 if (!m_ParentDevice.doEfcOverAVC(getCmd)) 207 { 208 debugError("Cmd failed\n"); 191 209 } 192 210 retval=getCmd.m_value; … … 197 215 getCmd.m_input=row; 198 216 getCmd.m_output=col; 199 if (!m_Parent .doEfcOverAVC(getCmd))200 { 201 debug Fatal("Cmd failed\n");217 if (!m_ParentDevice.doEfcOverAVC(getCmd)) 218 { 219 debugError("Cmd failed\n"); 202 220 } 203 221 retval=getCmd.m_value; … … 208 226 getCmd.m_input=row; 209 227 getCmd.m_output=col; 210 if (!m_Parent .doEfcOverAVC(getCmd))211 { 212 debug Fatal("Cmd failed\n");228 if (!m_ParentDevice.doEfcOverAVC(getCmd)) 229 { 230 debugError("Cmd failed\n"); 213 231 } 214 232 retval=getCmd.m_value; … … 227 245 int MonitorControl::getRowCount( ) 228 246 { 229 return m_Parent .getHwInfo().m_nb_phys_audio_in;247 return m_ParentDevice.getHwInfo().m_nb_phys_audio_in; 230 248 } 231 249 232 250 int MonitorControl::getColCount( ) 233 251 { 234 return m_Parent .getHwInfo().m_nb_phys_audio_out;252 return m_ParentDevice.getHwInfo().m_nb_phys_audio_out; 235 253 } 236 254 … … 243 261 : Control::Continuous(&p, "SimpleControl") 244 262 , m_Slave(new EfcGenericMixerCmd(t, c, channel)) 245 , m_Parent (p)263 , m_ParentDevice(p) 246 264 { 247 265 } … … 254 272 : Control::Continuous(&p, n) 255 273 , m_Slave(new EfcGenericMixerCmd(t, c, channel)) 256 , m_Parent (p)274 , m_ParentDevice(p) 257 275 { 258 276 } … … 273 291 if(m_Slave) { 274 292 m_Slave->setType(eCT_Set); 275 m_Slave->m_value =(uint32_t)val;276 if (!m_Parent .doEfcOverAVC(*m_Slave))277 { 278 debug Fatal("Cmd failed\n");293 m_Slave->m_value = (uint32_t)val; 294 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 295 { 296 debugError("Cmd failed\n"); 279 297 return 0.0; 298 } 299 300 // update the session block 301 switch(m_Slave->getTarget()) { 302 case eMT_PlaybackMix: 303 switch(m_Slave->getCommand()) { 304 case eMC_Gain: 305 m_ParentDevice.m_session.h.playbackgains[m_Slave->m_channel] = m_Slave->m_value; 306 break; 307 default: // nothing 308 break; 309 } 310 break; 311 case eMT_PhysicalOutputMix: 312 switch(m_Slave->getCommand()) { 313 case eMC_Gain: 314 m_ParentDevice.m_session.h.outputgains[m_Slave->m_channel] = m_Slave->m_value; 315 break; 316 default: // nothing 317 break; 318 } 319 break; 320 default: // nothing 321 break; 280 322 } 281 323 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %lf = %lf\n", … … 292 334 if(m_Slave) { 293 335 m_Slave->setType(eCT_Get); 294 if (!m_Parent .doEfcOverAVC(*m_Slave))295 { 296 debug Fatal("Cmd failed\n");336 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 337 { 338 debugError("Cmd failed\n"); 297 339 return 0.0; 298 340 } … … 315 357 , m_bit(bit) 316 358 , m_Slave(new EfcGenericMixerCmd(t, c, channel)) 317 , m_Parent (p)359 , m_ParentDevice(p) 318 360 { 319 361 } … … 327 369 , m_bit(bit) 328 370 , m_Slave(new EfcGenericMixerCmd(t, c, channel)) 329 , m_Parent (p)371 , m_ParentDevice(p) 330 372 { 331 373 } … … 361 403 m_Slave->setType(eCT_Set); 362 404 m_Slave->m_value=reg; 363 if (!m_Parent .doEfcOverAVC(*m_Slave))364 { 365 debug Fatal("Cmd failed\n");405 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 406 { 407 debugError("Cmd failed\n"); 366 408 return 0; 367 409 } 410 411 // update the session block 412 switch(m_Slave->getTarget()) { 413 case eMT_PlaybackMix: 414 switch(m_Slave->getCommand()) { 415 case eMC_Mute: 416 m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].mute = m_Slave->m_value; 417 break; 418 case eMC_Solo: 419 m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].solo = m_Slave->m_value; 420 break; 421 default: // nothing 422 break; 423 } 424 break; 425 case eMT_PhysicalOutputMix: 426 switch(m_Slave->getCommand()) { 427 case eMC_Mute: 428 m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].mute = m_Slave->m_value; 429 break; 430 case eMC_Nominal: 431 m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].shift = m_Slave->m_value; 432 break; 433 default: // nothing 434 break; 435 } 436 break; 437 case eMT_PhysicalInputMix: 438 switch(m_Slave->getCommand()) { 439 //case eMC_Pad: 440 // m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].pad = m_Slave->m_value; 441 // break; 442 case eMC_Nominal: 443 m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift = m_Slave->m_value; 444 break; 445 default: // nothing 446 break; 447 } 448 break; 449 default: // nothing 450 break; 451 } 452 368 453 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %ld (reg: 0x%08X => 0x%08X)\n", 369 454 m_Slave->m_channel, val, old_reg, reg); … … 378 463 { 379 464 if(m_Slave) { 465 // workaround for the failing get nominal command for input channels 466 // get it from the session block 467 if ((m_Slave->getTarget() == eMT_PhysicalInputMix) 468 && (m_Slave->getCommand() == eMC_Nominal)) { 469 int val = m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift; 470 debugOutput(DEBUG_LEVEL_VERBOSE, "input pad workaround: %08X\n", val); 471 return val; 472 } 380 473 m_Slave->setType(eCT_Get); 381 if (!m_Parent .doEfcOverAVC(*m_Slave))382 { 383 debug Fatal("Cmd failed\n");474 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 475 { 476 debugError("Cmd failed\n"); 384 477 return 0; 385 478 } … … 394 487 } 395 488 489 // --- control element for flags 490 491 SpdifModeControl::SpdifModeControl(FireWorks::Device& parent) 492 : Control::Discrete(&parent, "SpdifModeControl") 493 , m_ParentDevice(parent) 494 { 495 } 496 497 SpdifModeControl::SpdifModeControl(FireWorks::Device& parent, 498 std::string n) 499 : Control::Discrete(&parent, n) 500 , m_ParentDevice(parent) 501 { 502 } 503 504 SpdifModeControl::~SpdifModeControl() 505 { 506 } 507 508 void SpdifModeControl::show() 509 { 510 debugOutput(DEBUG_LEVEL_NORMAL, "SpdifModeControl\n"); 511 } 512 513 bool SpdifModeControl::setValue( const int val ) 514 { 515 EfcChangeFlagsCmd setCmd; 516 if(val) { 517 setCmd.m_setmask = FIREWORKS_EFC_FLAG_SPDIF_PRO; 518 } else { 519 setCmd.m_clearmask = FIREWORKS_EFC_FLAG_SPDIF_PRO; 520 } 521 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue val: %d setmask: %08X, clear: %08X\n", 522 val, setCmd.m_setmask, setCmd.m_clearmask); 523 if (!m_ParentDevice.doEfcOverAVC(setCmd)) 524 { 525 debugError("Cmd failed\n"); 526 return false; 527 } 528 return true; 529 } 530 531 int SpdifModeControl::getValue( ) 532 { 533 EfcGetFlagsCmd getCmd; 534 if (!m_ParentDevice.doEfcOverAVC(getCmd)) 535 { 536 debugError("Cmd failed\n"); 537 return 0; 538 } 539 debugOutput(DEBUG_LEVEL_VERBOSE, "got flags: %08X\n", 540 getCmd.m_flags); 541 if(getCmd.m_flags & FIREWORKS_EFC_FLAG_SPDIF_PRO) return 1; 542 else return 0; 543 } 544 396 545 // --- io config controls 397 546 … … 400 549 : Control::Discrete(&parent, "IOConfigControl") 401 550 , m_Slave(new EfcGenericIOConfigCmd(r)) 402 , m_Parent (parent)551 , m_ParentDevice(parent) 403 552 { 404 553 } … … 409 558 : Control::Discrete(&parent, n) 410 559 , m_Slave(new EfcGenericIOConfigCmd(r)) 411 , m_Parent (parent)560 , m_ParentDevice(parent) 412 561 { 413 562 } … … 429 578 m_Slave->setType(eCT_Set); 430 579 m_Slave->m_value=val; 431 if (!m_Parent .doEfcOverAVC(*m_Slave))432 { 433 debug Fatal("Cmd failed\n");580 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 581 { 582 debugError("Cmd failed\n"); 434 583 return 0; 435 584 } … … 446 595 if(m_Slave) { 447 596 m_Slave->setType(eCT_Get); 448 if (!m_Parent .doEfcOverAVC(*m_Slave))449 { 450 debug Fatal("Cmd failed\n");597 if (!m_ParentDevice.doEfcOverAVC(*m_Slave)) 598 { 599 debugError("Cmd failed\n"); 451 600 return 0; 452 601 } … … 460 609 } 461 610 462 611 // control to get hardware information 612 HwInfoControl::HwInfoControl(FireWorks::Device& p, 613 enum eHwInfoField f) 614 : Control::Discrete(&p, "HwInfoControl") 615 , m_ParentDevice(p) 616 , m_Field(f) 617 { 618 } 619 620 HwInfoControl::HwInfoControl(FireWorks::Device& p, 621 enum eHwInfoField f, 622 std::string n) 623 : Control::Discrete(&p, n) 624 , m_ParentDevice(p) 625 , m_Field(f) 626 { 627 } 628 629 HwInfoControl::~HwInfoControl() 630 { 631 } 632 633 int HwInfoControl::getValue() 634 { 635 switch (m_Field) { 636 case eHIF_PhysicalAudioOutCount: 637 return m_ParentDevice.getHwInfo().m_nb_phys_audio_out; 638 case eHIF_PhysicalAudioInCount: 639 return m_ParentDevice.getHwInfo().m_nb_phys_audio_in; 640 case eHIF_1394PlaybackCount: 641 return m_ParentDevice.getHwInfo().m_nb_1394_playback_channels; 642 case eHIF_1394RecordCount: 643 return m_ParentDevice.getHwInfo().m_nb_1394_record_channels; 644 case eHIF_GroupOutCount: 645 return m_ParentDevice.getHwInfo().m_nb_out_groups; 646 case eHIF_GroupInCount: 647 return m_ParentDevice.getHwInfo().m_nb_in_groups; 648 case eHIF_PhantomPower: 649 return m_ParentDevice.getHwInfo().hasSoftwarePhantom(); 650 default: 651 debugError("Bogus field\n"); 652 return 0; 653 } 654 } 655 656 void HwInfoControl::show() 657 { 658 debugOutput(DEBUG_LEVEL_NORMAL, "HwInfoControl\n"); 659 } 660 661 662 // control to save settings 663 MultiControl::MultiControl(FireWorks::Device& p, enum eType t) 664 : Control::Discrete(&p, "MultiControl") 665 , m_ParentDevice(p) 666 , m_Type(t) 667 { 668 } 669 670 MultiControl::MultiControl(FireWorks::Device& p, 671 enum eType t, std::string n) 672 : Control::Discrete(&p, n) 673 , m_ParentDevice(p) 674 , m_Type(t) 675 { 676 } 677 678 MultiControl::~MultiControl() 679 { 680 } 681 682 bool MultiControl::setValue(const int v) 683 { 684 switch(m_Type) { 685 case eT_SaveSession: 686 debugOutput(DEBUG_LEVEL_VERBOSE, "saving session\n"); 687 return m_ParentDevice.saveSession(); 688 case eT_Identify: 689 debugOutput(DEBUG_LEVEL_VERBOSE, "indentify device\n"); 690 { 691 EfcIdentifyCmd cmd; 692 if (!m_ParentDevice.doEfcOverAVC(cmd)) 693 { 694 debugError("Cmd failed\n"); 695 return false; 696 } 697 } 698 return true; 699 default: 700 debugError("Bad type\n"); 701 return false; 702 } 703 } 704 705 void MultiControl::show() 706 { 707 debugOutput(DEBUG_LEVEL_NORMAL, "MultiControl\n"); 708 switch(m_Type) { 709 case eT_SaveSession: 710 debugOutput(DEBUG_LEVEL_NORMAL, "Type: SaveSession\n"); 711 break; 712 case eT_Identify: 713 debugOutput(DEBUG_LEVEL_NORMAL, "Type: Identify\n"); 714 break; 715 default: 716 debugError("Bad type\n"); 717 } 718 } 463 719 464 720 } // FireWorks trunk/libffado/src/fireworks/fireworks_control.h
r1324 r1336 71 71 protected: 72 72 enum eMonitorControl m_control; 73 FireWorks::Device& m_Parent ;73 FireWorks::Device& m_ParentDevice; 74 74 }; 75 75 … … 101 101 protected: 102 102 EfcGenericMixerCmd* m_Slave; 103 FireWorks::Device& m_Parent ;103 FireWorks::Device& m_ParentDevice; 104 104 }; 105 105 … … 132 132 int m_bit; 133 133 EfcGenericMixerCmd* m_Slave; 134 FireWorks::Device& m_Parent; 135 }; 134 FireWorks::Device& m_ParentDevice; 135 }; 136 137 class SpdifModeControl : public Control::Discrete 138 { 139 140 public: 141 SpdifModeControl(FireWorks::Device& parent); 142 SpdifModeControl(FireWorks::Device& parent, 143 std::string n); 144 virtual ~SpdifModeControl(); 145 146 virtual void show(); 147 148 virtual bool setValue( const int ); 149 virtual int getValue( ); 150 virtual bool setValue(int idx, int v) 151 {return setValue(v);}; 152 virtual int getValue(int idx) 153 {return getValue();}; 154 155 virtual int getMinimum() {return 0;}; 156 virtual int getMaximum() {return 0;}; 157 158 protected: 159 FireWorks::Device& m_ParentDevice; 160 }; 161 136 162 137 163 // for on-off type of controls … … 163 189 int m_bit; 164 190 EfcGenericIOConfigCmd* m_Slave; 165 FireWorks::Device& m_Parent; 191 FireWorks::Device& m_ParentDevice; 192 }; 193 194 195 class HwInfoControl : public Control::Discrete 196 { 197 public: 198 199 enum eHwInfoField { 200 eHIF_PhysicalAudioOutCount, 201 eHIF_PhysicalAudioInCount, 202 eHIF_1394PlaybackCount, 203 eHIF_1394RecordCount, 204 eHIF_GroupOutCount, 205 eHIF_GroupInCount, 206 eHIF_PhantomPower, 207 }; 208 public: 209 HwInfoControl(FireWorks::Device& parent, 210 enum eHwInfoField); 211 HwInfoControl(FireWorks::Device& parent, 212 enum eHwInfoField, std::string n); 213 virtual ~HwInfoControl(); 214 215 virtual void show(); 216 217 virtual bool setValue( const int ) {return false;}; 218 virtual int getValue( ); 219 virtual bool setValue(int idx, int v) 220 {return setValue(v);}; 221 virtual int getValue(int idx) 222 {return getValue();}; 223 224 virtual int getMinimum() {return 0;}; 225 virtual int getMaximum() {return 0;}; 226 227 protected: 228 FireWorks::Device& m_ParentDevice; 229 enum eHwInfoField m_Field; 230 }; 231 232 class MultiControl : public Control::Discrete 233 { 234 public: 235 236 enum eType { 237 eT_SaveSession, 238 eT_Identify, 239 }; 240 public: 241 MultiControl(FireWorks::Device& parent, enum eType); 242 MultiControl(FireWorks::Device& parent, enum eType, 243 std::string n); 244 virtual ~MultiControl(); 245 246 virtual void show(); 247 248 virtual bool setValue( const int ); 249 virtual int getValue( ) {return 0;}; 250 virtual bool setValue(int idx, int v) 251 {return setValue(v);}; 252 virtual int getValue(int idx) 253 {return getValue();}; 254 255 virtual int getMinimum() {return 0;}; 256 virtual int getMaximum() {return 0;}; 257 258 protected: 259 FireWorks::Device& m_ParentDevice; 260 enum eType m_Type; 166 261 }; 167 262 trunk/libffado/src/fireworks/fireworks_device.cpp
r1254 r1336 22 22 */ 23 23 24 #include "config.h"25 24 // #include "config.h" 25 #include "devicemanager.h" 26 26 #include "fireworks_device.h" 27 27 #include "efc/efc_avc_cmd.h" … … 40 40 #include "libutil/PosixMutex.h" 41 41 42 #include "IntelFlashMap.h" 43 44 #define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 2000 45 42 46 #include <sstream> 43 47 using namespace std; … … 48 52 Device::Device(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )) 49 53 : GenericAVC::AvDevice( d, configRom) 50 , m_poll_lock( new Util::PosixMutex( ) )54 , m_poll_lock( new Util::PosixMutex("DEVPOLL") ) 51 55 , m_efc_discovery_done ( false ) 52 56 , m_MixerContainer ( NULL ) 57 , m_HwInfoContainer ( NULL ) 53 58 { 54 59 debugOutput( DEBUG_LEVEL_VERBOSE, "Created FireWorks::Device (NodeID %d)\n", … … 75 80 76 81 bool 77 Device::probe( ConfigRom& configRom, bool generic )82 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 78 83 { 79 84 if(generic) { … … 106 111 unsigned int vendorId = configRom.getNodeVendorId(); 107 112 unsigned int modelId = configRom.getModelId(); 108 109 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 110 if ( vendorModel.parse() ) { 111 return vendorModel.isPresent( vendorId, modelId ); 112 } 113 return false; 113 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 114 return c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks; 114 115 } 115 116 } … … 121 122 unsigned int modelId = getConfigRom().getModelId(); 122 123 123 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); 124 if ( vendorModel.parse() ) { 125 m_model = vendorModel.find( vendorId, modelId ); 126 } 127 128 if (!GenericAVC::VendorModel::isValid(m_model)) { 124 Util::Configuration &c = getDeviceManager().getConfiguration(); 125 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 126 127 if (c.isValid(vme) && vme.driver == Util::Configuration::eD_FireWorks) { 128 debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 129 vme.vendor_name.c_str(), 130 vme.model_name.c_str()); 131 } else { 129 132 debugWarning("Using generic ECHO Audio FireWorks support for unsupported device '%s %s'\n", 130 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 131 } else { 132 debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 133 m_model.vendor_name.c_str(), m_model.model_name.c_str()); 133 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 134 134 } 135 135 … … 141 141 142 142 // discover AVC-wise 143 if ( !GenericAVC::AvDevice::discover () ) {143 if ( !GenericAVC::AvDevice::discoverGeneric() ) { 144 144 debugError( "Could not discover GenericAVC::AvDevice\n" ); 145 145 return false; … … 259 259 result &= m_MixerContainer->addElement( 260 260 new BinaryControl(*this, eMT_PlaybackMix, eMC_Mute, ch, 0, node_name.str()+"Mute")); 261 result &= m_MixerContainer->addElement( 262 new BinaryControl(*this, eMT_PlaybackMix, eMC_Solo, ch, 0, node_name.str()+"Solo")); 261 263 result &= m_MixerContainer->addElement( 262 264 new SimpleControl(*this, eMT_PlaybackMix, eMC_Gain, ch, node_name.str()+"Gain")); … … 276 278 } 277 279 280 // Physical input mix controls 281 for (unsigned int ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) { 282 std::ostringstream node_name; 283 node_name << "IN" << ch; 284 285 // result &= m_MixerContainer->addElement( 286 // new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Pad, ch, 0, node_name.str()+"Pad")); 287 result &= m_MixerContainer->addElement( 288 new BinaryControl(*this, eMT_PhysicalInputMix, eMC_Nominal, ch, 1, node_name.str()+"Nominal")); 289 } 290 291 // add hardware information controls 292 m_HwInfoContainer = new Control::Container(this, "HwInfo"); 293 result &= m_HwInfoContainer->addElement( 294 new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioOutCount, "PhysicalAudioOutCount")); 295 result &= m_HwInfoContainer->addElement( 296 new HwInfoControl(*this, HwInfoControl::eHIF_PhysicalAudioInCount, "PhysicalAudioInCount")); 297 result &= m_HwInfoContainer->addElement( 298 new HwInfoControl(*this, HwInfoControl::eHIF_1394PlaybackCount, "1394PlaybackCount")); 299 result &= m_HwInfoContainer->addElement( 300 new HwInfoControl(*this, HwInfoControl::eHIF_1394RecordCount, "1394RecordCount")); 301 result &= m_HwInfoContainer->addElement( 302 new HwInfoControl(*this, HwInfoControl::eHIF_GroupOutCount, "GroupOutCount")); 303 result &= m_HwInfoContainer->addElement( 304 new HwInfoControl(*this, HwInfoControl::eHIF_GroupInCount, "GroupInCount")); 305 result &= m_HwInfoContainer->addElement( 306 new HwInfoControl(*this, HwInfoControl::eHIF_PhantomPower, "PhantomPower")); 307 308 // add a save settings control 309 result &= this->addElement( 310 new MultiControl(*this, MultiControl::eT_SaveSession, "SaveSettings")); 311 312 // add an identify control 313 result &= this->addElement( 314 new MultiControl(*this, MultiControl::eT_Identify, "Identify")); 315 316 // spdif mode control 317 result &= this->addElement( 318 new SpdifModeControl(*this, "SpdifMode")); 319 278 320 // check for IO config controls and add them if necessary 279 321 if(m_HwInfo.hasMirroring()) { 280 result &= m_MixerContainer->addElement(322 result &= this->addElement( 281 323 new IOConfigControl(*this, eCR_Mirror, "ChannelMirror")); 282 324 } 283 325 if(m_HwInfo.hasSoftwarePhantom()) { 284 result &= m_MixerContainer->addElement(326 result &= this->addElement( 285 327 new IOConfigControl(*this, eCR_Phantom, "PhantomPower")); 286 328 } … … 300 342 } 301 343 344 if (!addElement(m_HwInfoContainer)) { 345 debugWarning("Could not register hwinfo to device\n"); 346 // clean up 347 destroyMixer(); 348 return false; 349 } 350 351 // load the session block 352 if (!loadSession()) { 353 debugWarning("Could not load session\n"); 354 } 355 302 356 return true; 303 357 } … … 310 364 if (m_MixerContainer == NULL) { 311 365 debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n"); 312 return true; 313 } 314 315 if (!deleteElement(m_MixerContainer)) { 316 debugError("Mixer present but not registered to the avdevice\n"); 317 return false; 318 } 319 320 // remove and delete (as in free) child control elements 321 m_MixerContainer->clearElements(true); 322 delete m_MixerContainer; 323 return true; 324 } 325 366 } else { 367 if (!deleteElement(m_MixerContainer)) { 368 debugError("Mixer present but not registered to the avdevice\n"); 369 return false; 370 } 371 372 // remove and delete (as in free) child control elements 373 m_MixerContainer->clearElements(true); 374 delete m_MixerContainer; 375 m_MixerContainer = NULL; 376 } 377 378 if (m_HwInfoContainer == NULL) { 379 debugOutput(DEBUG_LEVEL_VERBOSE, "no hwinfo to destroy...\n"); 380 } else { 381 if (!deleteElement(m_HwInfoContainer)) { 382 debugError("HwInfo present but not registered to the avdevice\n"); 383 return false; 384 } 385 386 // remove and delete (as in free) child control elements 387 m_HwInfoContainer->clearElements(true); 388 delete m_HwInfoContainer; 389 m_HwInfoContainer = NULL; 390 } 391 return true; 392 } 393 394 bool 395 Device::saveSession() 396 { 397 // save the session block 398 // if ( !updateSession() ) { 399 // debugError( "Could not update session\n" ); 400 // } else { 401 if ( !m_session.saveToDevice(*this) ) { 402 debugError( "Could not save session block\n" ); 403 } 404 // } 405 406 return true; 407 } 408 409 bool 410 Device::loadSession() 411 { 412 if ( !m_session.loadFromDevice(*this) ) { 413 debugError( "Could not load session block\n" ); 414 return false; 415 } 416 return true; 417 } 326 418 327 419 bool … … 329 421 Util::MutexLockHelper lock(*m_poll_lock); 330 422 return doEfcOverAVC(m_Polled); 423 } 424 425 #define ECHO_CHECK_AND_ADD_SR(v, x) \ 426 { if(x >= m_HwInfo.m_min_sample_rate && x <= m_HwInfo.m_max_sample_rate) \ 427 v.push_back(x); } 428 std::vector<int> 429 Device::getSupportedSamplingFrequencies() 430 { 431 std::vector<int> frequencies; 432 ECHO_CHECK_AND_ADD_SR(frequencies, 22050); 433 ECHO_CHECK_AND_ADD_SR(frequencies, 24000); 434 ECHO_CHECK_AND_ADD_SR(frequencies, 32000); 435 ECHO_CHECK_AND_ADD_SR(frequencies, 44100); 436 ECHO_CHECK_AND_ADD_SR(frequencies, 48000); 437 ECHO_CHECK_AND_ADD_SR(frequencies, 88200); 438 ECHO_CHECK_AND_ADD_SR(frequencies, 96000); 439 ECHO_CHECK_AND_ADD_SR(frequencies, 176400); 440 ECHO_CHECK_AND_ADD_SR(frequencies, 192000); 441 return frequencies; 331 442 } 332 443 … … 528 639 bool 529 640 Device::lockFlash(bool lock) { 641 // some hardware doesn't need/support flash lock 642 if (m_HwInfo.hasDSP()) { 643 debugOutput(DEBUG_LEVEL_VERBOSE, "flash lock not needed\n"); 644 return true; 645 } 646 530 647 EfcFlashLockCmd cmd; 531 648 cmd.m_lock = lock; … … 649 766 650 767 bool 768 Device::eraseFlashBlocks(uint32_t start_address, unsigned int nb_quads) 769 { 770 uint32_t blocksize_bytes; 771 uint32_t blocksize_quads; 772 unsigned int quads_left = nb_quads; 773 bool success = true; 774 775 const unsigned int max_nb_tries = 10; 776 unsigned int nb_tries = 0; 777 778 do { 779 // the erase block size is fixed by the HW, and depends 780 // on the flash section we're in 781 if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES) 782 blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES; 783 else 784 blocksize_bytes = MAINBLOCK_SIZE_BYTES; 785 start_address &= ~(blocksize_bytes - 1); 786 blocksize_quads = blocksize_bytes / 4; 787 788 uint32_t verify[blocksize_quads]; 789 790 // corner case: requested to erase less than one block 791 if (blocksize_quads > quads_left) { 792 blocksize_quads = quads_left; 793 } 794 795 // do the actual erase 796 if (!eraseFlash(start_address)) { 797 debugWarning("Could not erase flash block at 0x%08X\n", start_address); 798 success = false; 799 } else { 800 // wait for the flash to become ready again 801 if (!waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS)) { 802 debugError("Wait for flash timed out at address 0x%08X\n", start_address); 803 return false; 804 } 805 806 // verify that the block is empty as an extra precaution 807 if (!readFlash(start_address, blocksize_quads, verify)) { 808 debugError("Could not read flash block at 0x%08X\n", start_address); 809 return false; 810 } 811 812 // everything should be 0xFFFFFFFF if the erase was successful 813 for (unsigned int i = 0; i < blocksize_quads; i++) { 814 if (0xFFFFFFFF != verify[i]) { 815 debugWarning("Flash erase verification failed.\n"); 816 success = false; 817 break; 818 } 819 } 820 } 821 822 if (success) { 823 start_address += blocksize_bytes; 824 quads_left -= blocksize_quads; 825 nb_tries = 0; 826 } else { 827 nb_tries++; 828 } 829 if (nb_tries > max_nb_tries) { 830 debugError("Needed too many tries to erase flash at 0x%08X\n", start_address); 831 return false; 832 } 833 } while (quads_left > 0); 834 835 return true; 836 } 837 838 bool 651 839 Device::waitForFlash(unsigned int msecs) 652 840 { … … 678 866 } 679 867 868 uint32_t 869 Device::getSessionBase() 870 { 871 EfcFlashGetSessionBaseCmd cmd; 872 if(!doEfcOverAVC(cmd)) { 873 debugError("Could not get session base address\n"); 874 return 0; // FIXME: arbitrary 875 } 876 return cmd.m_address; 877 } 878 680 879 } // FireWorks trunk/libffado/src/fireworks/fireworks_device.h
r1239 r1336 32 32 #include "efc/efc_cmd.h" 33 33 #include "efc/efc_cmds_hardware.h" 34 #include "fireworks_session_block.h" 34 35 35 36 #include <pthread.h> … … 42 43 43 44 class Device : public GenericAVC::AvDevice { 45 friend class MonitorControl; 46 friend class SimpleControl; 47 friend class BinaryControl; 48 friend class IOConfigControl; 49 44 50 public: 45 51 Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ) ); 46 52 virtual ~Device(); 47 53 48 static bool probe( ConfigRom& configRom, bool generic = false );54 static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 49 55 static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 50 56 virtual bool discover(); … … 54 60 virtual bool buildMixer(); 55 61 virtual bool destroyMixer(); 62 63 virtual std::vector<int> getSupportedSamplingFrequencies(); 56 64 57 65 virtual ClockSourceVector getSupportedClockSources(); … … 95 103 */ 96 104 bool eraseFlash(uint32_t addr); 105 bool eraseFlashBlocks(uint32_t start_address, unsigned int nb_quads); 97 106 98 107 /** … … 102 111 */ 103 112 bool waitForFlash(unsigned int msecs); 113 114 /** 115 * @brief get the flash address of the session block 116 * @return session block base address 117 */ 118 uint32_t getSessionBase(); 119 120 /** 121 * load the session block from the device 122 * @return true if successful 123 */ 124 bool loadSession(); 125 /** 126 * save the session block to the device 127 * @return true if successful 128 */ 129 bool saveSession(); 104 130 105 131 // Echo specific stuff … … 123 149 bool m_efc_discovery_done; 124 150 151 protected: 152 Session m_session; 125 153 private: 126 154 Control::Container *m_MixerContainer; 155 Control::Container *m_HwInfoContainer; 127 156 128 157 }; trunk/libffado/src/fireworks/fireworks_firmware.cpp
r1234 r1336 37 37 #include <cstring> 38 38 39 #define ECHO_FLASH_ERASE_TIMEOUT_MILLISECS 200040 41 39 #define DAT_EXTENSION "dat" 42 40 43 41 // device id's 44 #define AUDIOFIRE2 45 #define AUDIOFIRE4 46 #define AUDIOFIRE8 47 #define AUDIOFIRE12 48 #define AUDIOFIRE12HD 49 #define FWHDMI 50 #define ONYX400F 51 #define ONYX1200F 52 #define FIREWORKS8 42 #define AUDIOFIRE2 0x000af2 43 #define AUDIOFIRE4 0x000af4 44 #define AUDIOFIRE8 0x000af8 45 #define AUDIOFIRE12 0x00af12 46 #define AUDIOFIRE12HD 0x0af12d 47 #define FWHDMI 0x00afd1 48 #define ONYX400F 0x00400f 49 #define ONYX1200F 0x01200f 50 #define FIREWORKS8 0x0000f8 53 51 54 52 using namespace std; … … 418 416 const char *Af2Dats[] = 419 417 { 420 418 "Fireworks3" 421 419 }; 422 420 423 421 const char *Af4Dats[] = 424 422 { 425 423 "Fireworks3" 426 424 }; 427 425 428 426 const char *Af8Dats[] = 429 427 { 430 431 432 433 428 "bootstrap", 429 "audiofire8", 430 "audiofire8_E", 431 "FireworksARM" 434 432 }; 435 433 436 434 const char *Af12Dats[] = 437 435 { 438 439 440 441 436 "bootstrap", 437 "audiofire12", 438 "audiofire12_E", 439 "FireworksARM" 442 440 }; 443 441 … … 448 446 struct dat_list datlists[4] = 449 447 { 450 { FW_VENDORID_ECHO, AUDIOFIRE2, 451 { FW_VENDORID_ECHO, AUDIOFIRE4, 452 { FW_VENDORID_ECHO, AUDIOFIRE8, 453 { FW_VENDORID_ECHO, AUDIOFIRE12, 448 { FW_VENDORID_ECHO, AUDIOFIRE2, 0x04010000, 1, Af2Dats }, 449 { FW_VENDORID_ECHO, AUDIOFIRE4, 0x04010000, 1, Af4Dats }, 450 { FW_VENDORID_ECHO, AUDIOFIRE8, 0x04010000, 4, Af8Dats }, 451 { FW_VENDORID_ECHO, AUDIOFIRE12, 0x04010000, 4, Af12Dats } 454 452 }; 455 453 … … 534 532 FirmwareUtil::eraseBlocks(uint32_t start_address, unsigned int nb_quads) 535 533 { 536 uint32_t blocksize_bytes; 537 uint32_t blocksize_quads; 538 unsigned int quads_left = nb_quads; 539 bool success = true; 540 541 const unsigned int max_nb_tries = 10; 542 unsigned int nb_tries = 0; 543 544 do { 545 // the erase block size is fixed by the HW, and depends 546 // on the flash section we're in 547 if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES) 548 blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES; 549 else 550 blocksize_bytes = MAINBLOCK_SIZE_BYTES; 551 start_address &= ~(blocksize_bytes - 1); 552 blocksize_quads = blocksize_bytes / 4; 553 554 uint32_t verify[blocksize_quads]; 555 556 // corner case: requested to erase less than one block 557 if (blocksize_quads > quads_left) { 558 blocksize_quads = quads_left; 559 } 560 561 // do the actual erase 562 if (!m_Parent.eraseFlash(start_address)) { 563 debugWarning("Could not erase flash block at 0x%08X\n", start_address); 564 success = false; 565 } else { 566 // wait for the flash to become ready again 567 if (!m_Parent.waitForFlash(ECHO_FLASH_ERASE_TIMEOUT_MILLISECS)) { 568 debugError("Wait for flash timed out at address 0x%08X\n", start_address); 569 return false; 570 } 571 572 // verify that the block is empty as an extra precaution 573 if (!m_Parent.readFlash(start_address, blocksize_quads, verify)) { 574 debugError("Could not read flash block at 0x%08X\n", start_address); 575 return false; 576 } 577 578 // everything should be 0xFFFFFFFF if the erase was successful 579 for (unsigned int i = 0; i < blocksize_quads; i++) { 580 if (0xFFFFFFFF != verify[i]) { 581 debugWarning("Flash erase verification failed.\n"); 582 success = false; 583 break; 584 } 585 } 586 } 587 588 if (success) { 589 start_address += blocksize_bytes; 590 quads_left -= blocksize_quads; 591 nb_tries = 0; 592 } else { 593 nb_tries++; 594 } 595 if (nb_tries > max_nb_tries) { 596 debugError("Needed too many tries to erase flash at 0x%08X\n", start_address); 597 return false; 598 } 599 } while (quads_left > 0); 600 601 return true; 534 return m_Parent.eraseFlashBlocks(start_address, nb_quads); 602 535 } 603 536 trunk/libffado/src/genericavc/avc_avdevice.cpp
r1254 r1336 23 23 */ 24 24 25 #include "config.h"26 25 //#include "config.h" 26 #include "devicemanager.h" 27 27 #include "genericavc/avc_avdevice.h" 28 28 … … 77 77 78 78 bool 79 AvDevice::probe( ConfigRom& configRom, bool generic )79 AvDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic ) 80 80 { 81 81 if(generic) { … … 102 102 unsigned int modelId = configRom.getModelId(); 103 103 104 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" ); 105 if ( vendorModel.parse() ) { 106 return vendorModel.isPresent( vendorId, modelId ); 107 } 104 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 105 return c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC; 108 106 return false; 109 107 } … … 120 118 { 121 119 Util::MutexLockHelper lock(m_DeviceMutex); 122 // check if we already have a valid VendorModel entry 123 // e.g. because a subclass called this function 124 if (!GenericAVC::VendorModel::isValid(m_model)) { 125 unsigned int vendorId = getConfigRom().getNodeVendorId(); 126 unsigned int modelId = getConfigRom().getModelId(); 127 128 GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" ); 129 if ( vendorModel.parse() ) { 130 m_model = vendorModel.find( vendorId, modelId ); 131 } 132 133 if (!GenericAVC::VendorModel::isValid(m_model)) { 134 debugWarning("Using generic AV/C support for unsupported device '%s %s'\n", 135 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 136 } else { 137 debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 138 m_model.vendor_name.c_str(), m_model.model_name.c_str()); 139 } 140 } 141 120 121 unsigned int vendorId = getConfigRom().getNodeVendorId(); 122 unsigned int modelId = getConfigRom().getModelId(); 123 124 Util::Configuration &c = getDeviceManager().getConfiguration(); 125 Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); 126 127 if (c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC) { 128 debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 129 vme.vendor_name.c_str(), 130 vme.model_name.c_str()); 131 } else { 132 debugWarning("Using generic AV/C support for unsupported device '%s %s'\n", 133 getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); 134 } 135 return discoverGeneric(); 136 } 137 138 bool 139 AvDevice::discoverGeneric() 140 { 142 141 if ( !Unit::discover() ) { 143 142 debugError( "Could not discover unit\n" ); … … 153 152 return false; 154 153 } 155 156 154 return true; 157 155 } … … 240 238 return false; 241 239 240 } 241 242 bool 243 AvDevice::supportsSamplingFrequency( int s ) 244 { 245 Util::MutexLockHelper lock(m_DeviceMutex); 246 247 AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 ); 248 if ( !plug ) { 249 debugError( "Could not retrieve iso input plug 0\n" ); 250 return false; 251 } 252 253 if ( !plug->supportsSampleRate( s ) ) 254 { 255 debugError( "sample rate not supported by input plug\n" ); 256 return false; 257 } 258 259 plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 ); 260 if ( !plug ) { 261 debugError( "Could not retrieve iso output plug 0\n" ); 262 return false; 263 } 264 265 if ( !plug->supportsSampleRate( s ) ) 266 { 267 debugError( "sample rate not supported by output plug\n" ); 268 return false; 269 } 270 return true; 271 } 272 273 #define GENERICAVC_CHECK_AND_ADD_SR(v, x) \ 274 { if(supportsSamplingFrequency(x)) \ 275 v.push_back(x); } 276 277 std::vector<int> 278 AvDevice::getSupportedSamplingFrequencies() 279 { 280 if (m_supported_frequencies_cache.size() == 0) { 281 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 22050); 282 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 24000); 283 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 32000); 284 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 44100); 285 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 48000); 286 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 88200); 287 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 96000); 288 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 176400); 289 GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 192000); 290 } 291 return m_supported_frequencies_cache; 242 292 } 243 293 trunk/libffado/src/genericavc/avc_avdevice.h
r1239 r1336 27 27 28 28 #include "ffadodevice.h" 29 #include " genericavc/avc_vendormodel.h"29 #include "libutil/Configuration.h" 30 30 31 31 #include "libavc/avc_definitions.h" … … 50 50 AvDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 51 51 virtual ~AvDevice(); 52 53 static bool probe( ConfigRom& configRom, bool generic = false );52 53 static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 54 54 virtual bool discover(); 55 bool discoverGeneric(); 55 56 static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 56 57 … … 62 63 63 64 virtual bool setSamplingFrequency( int ); 65 virtual bool supportsSamplingFrequency( int s ); 64 66 virtual int getSamplingFrequency( ); 67 virtual std::vector<int> getSupportedSamplingFrequencies(); 65 68 66 69 virtual ClockSourceVector getSupportedClockSources(); … … 91 94 AVC::ESamplingFrequency samplingFrequency );*/ 92 95 93 struct VendorModelEntry m_model;94 95 96 // streaming stuff 96 97 typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; … … 103 104 private: 104 105 ClockSource syncInfoToClockSource(const SyncInfo& si); 106 std::vector<int> m_supported_frequencies_cache; 105 107 }; 106 108 trunk/libffado/src/libavc/general/avc_plug.cpp
r1239 r1336 1015 1015 1016 1016 bool 1017 Plug::supportsSampleRate( int rate ) 1018 { 1019 // fallback: BeBoB style 1020 ESamplingFrequency samplingFrequency = parseSampleRate(rate); 1021 1022 ExtendedStreamFormatCmd extStreamFormatCmd( 1023 m_unit->get1394Service(), 1024 ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList ); 1025 UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 1026 getPlugId() ); 1027 1028 extStreamFormatCmd.setPlugAddress( 1029 PlugAddress( 1030 Plug::convertPlugDirection(getPlugDirection() ), 1031 PlugAddress::ePAM_Unit, 1032 unitPlugAddress ) ); 1033 1034 extStreamFormatCmd.setNodeId( m_unit->getConfigRom().getNodeId() ); 1035 extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); 1036 1037 int i = 0; 1038 bool cmdSuccess = false; 1039 bool correctFormatFound = false; 1040 1041 do { 1042 extStreamFormatCmd.setIndexInStreamFormat( i ); 1043 extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status ); 1044 extStreamFormatCmd.setVerbose( getDebugLevel() ); 1045 1046 cmdSuccess = extStreamFormatCmd.fire(); 1047 1048 if ( cmdSuccess 1049 && ( extStreamFormatCmd.getResponse() == 1050 AVCCommand::eR_Implemented ) ) 1051 { 1052 ESamplingFrequency foundFreq = eSF_DontCare; 1053 1054 FormatInformation* formatInfo = 1055 extStreamFormatCmd.getFormatInformation(); 1056 FormatInformationStreamsCompound* compoundStream 1057 = dynamic_cast< FormatInformationStreamsCompound* > ( 1058 formatInfo->m_streams ); 1059 if ( compoundStream ) { 1060 foundFreq = 1061 static_cast< ESamplingFrequency >( 1062 compoundStream->m_samplingFrequency ); 1063 } 1064 1065 FormatInformationStreamsSync* syncStream 1066 = dynamic_cast< FormatInformationStreamsSync* > ( 1067 formatInfo->m_streams ); 1068 if ( syncStream ) { 1069 foundFreq = 1070 static_cast< ESamplingFrequency >( 1071 syncStream->m_samplingFrequency ); 1072 } 1073 1074 if ( foundFreq == samplingFrequency ) 1075 { 1076 correctFormatFound = true; 1077 break; 1078 } 1079 } 1080 1081 ++i; 1082 } while ( cmdSuccess 1083 && ( extStreamFormatCmd.getResponse() == 1084 ExtendedStreamFormatCmd::eR_Implemented ) ); 1085 1086 if ( !cmdSuccess ) { 1087 debugError( "setSampleRatePlug: Failed to retrieve format info\n" ); 1088 return false; 1089 } 1090 1091 if ( !correctFormatFound ) { 1092 debugOutput(DEBUG_LEVEL_VERBOSE, 1093 "setSampleRatePlug: %s plug %d does not support sample rate %d\n", 1094 getName(), 1095 getPlugId(), 1096 convertESamplingFrequency( samplingFrequency ) ); 1097 return false; 1098 } 1099 return true; 1100 } 1101 1102 bool 1017 1103 Plug::discoverConnectionsFromSpecificData( 1018 1104 EPlugDirection discoverDirection, trunk/libffado/src/libavc/general/avc_plug.h
r1239 r1336 129 129 int getSampleRate() const; // 22050, 24000, 32000, ... 130 130 bool setSampleRate( int rate ); 131 bool supportsSampleRate( int rate ); 131 132 132 133 int getNrOfChannels() const; trunk/libffado/src/libavc/general/avc_unit.cpp
r1239 r1336 844 844 Unit::show() 845 845 { 846 m_pPlugManager->showPlugs(); 846 if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) { 847 m_pPlugManager->showPlugs(); 848 } 847 849 //SubunitMusic* s=getMusicSubunit(0); 848 850 //if(s) s->showMusicPlugs(); trunk/libffado/src/libcontrol/ClockSelect.cpp
r1217 r1336 44 44 if(idx >= (int)v.size()) { 45 45 debugError("index out of range\n"); 46 return false; 47 } 48 if(idx < 0) { 49 debugError("index < 0\n"); 46 50 return false; 47 51 } … … 84 88 if(idx >= (int)v.size()) { 85 89 debugError("index out of range\n"); 86 return false; 90 return "Error"; 91 } 92 if(idx < 0) { 93 debugError("index < 0\n"); 94 return "Error"; 87 95 } 88 96 return v.at(idx).description; … … 173 181 174 182 SamplerateSelect::SamplerateSelect(FFADODevice &d) 175 : Discrete(&d)183 : Enum(&d) 176 184 , m_Device( d ) 177 185 { … … 182 190 183 191 bool 184 SamplerateSelect::setValue(int v) 185 { 186 return m_Device.setSamplingFrequency(v); 187 } 188 189 int 190 SamplerateSelect::getValue() 191 { 192 return m_Device.getSamplingFrequency(); 193 } 194 195 bool 196 SamplerateSelect::setValue(int idx, int v) 197 { 198 return m_Device.setSamplingFrequency(v); 199 } 200 201 int 202 SamplerateSelect::getValue(int idx) 203 { 204 return m_Device.getSamplingFrequency(); 205 } 206 207 int 208 SamplerateSelect::getMinimum() 209 { 210 return 32000; 211 } 212 213 int 214 SamplerateSelect::getMaximum() 215 { 216 return 192000; 217 } 192 SamplerateSelect::select(int idx) 193 { 194 std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 195 if (idx >= 0 && idx < (int)freqs.size()) { 196 if(!m_Device.setSamplingFrequency(freqs.at(idx))) { 197 debugWarning("Could not select samplerate\n"); 198 return false; 199 } 200 return true; 201 } else { 202 debugWarning("bad index specified\n"); 203 return false; 204 } 205 } 206 207 int 208 SamplerateSelect::selected() 209 { 210 std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 211 int samplerate = m_Device.getSamplingFrequency(); 212 for (int i = 0; i < (int)freqs.size(); i++) { 213 if (samplerate == freqs.at(i)) { 214 return i; 215 } 216 } 217 debugError("could not find the selected samplerate\n"); 218 return -1; 219 } 220 221 int 222 SamplerateSelect::count() 223 { 224 return m_Device.getSupportedSamplingFrequencies().size(); 225 } 226 227 std::string 228 SamplerateSelect::getEnumLabel(int idx) 229 { 230 char tmp[16]; 231 std::string retval = "Error"; 232 std::vector<int> freqs = m_Device.getSupportedSamplingFrequencies(); 233 if (idx >= 0 && idx < (int)freqs.size()) { 234 snprintf(tmp, 16, "%u", freqs.at(idx)); 235 retval = tmp; 236 } else { 237 debugWarning("bad index specified\n"); 238 } 239 return retval; 240 } 241 242 void 243 SamplerateSelect::show() 244 { 245 debugOutput( DEBUG_LEVEL_NORMAL, "SamplerateSelect Element %s, current: %d\n", 246 getName().c_str(), m_Device.getSamplingFrequency()); 247 248 } 249 218 250 219 251 } // namespace Control trunk/libffado/src/libcontrol/ClockSelect.h
r1217 r1336 69 69 */ 70 70 class SamplerateSelect 71 : public Discrete71 : public Enum 72 72 { 73 73 public: … … 75 75 virtual ~SamplerateSelect() {}; 76 76 77 virtual bool se tValue(int v);78 virtual int getValue();79 virtual bool setValue(int idx, int v);80 virtual int getValue(int idx);77 virtual bool select(int idx); 78 virtual int selected(); 79 virtual int count(); 80 virtual std::string getEnumLabel(int idx); 81 81 82 virtual int getMinimum();83 virtual int getMaximum(); 82 virtual void show(); 83 84 84 protected: 85 85 FFADODevice &m_Device; trunk/libffado/src/libcontrol/Element.cpp
r1211 r1336 50 50 // this means we have to create a lock 51 51 if(parent == NULL) { 52 m_element_lock = new Util::PosixMutex( );52 m_element_lock = new Util::PosixMutex("CTLEL"); 53 53 } 54 54 } … … 65 65 // this means we have to create a lock 66 66 if(parent == NULL) { 67 m_element_lock = new Util::PosixMutex( );67 m_element_lock = new Util::PosixMutex("CTLEL"); 68 68 } 69 69 } … … 158 158 } 159 159 160 bool 161 Element::emitSignal(int id) 162 { 163 for ( std::vector< SignalFunctor* >::iterator it = m_signalHandlers.begin(); 164 it != m_signalHandlers.end(); 165 ++it ) 166 { 167 SignalFunctor *f = *it; 168 if(f && f->m_id == id) (*f)(); 169 } 170 return true; 171 } 172 160 173 //// --- Container --- //// 161 174 Container::Container(Element *p) … … 166 179 Container::Container(Element *p, std::string n) 167 180 : Element(p, n) 181 { 182 } 183 184 Container::~Container() 168 185 { 169 186 } trunk/libffado/src/libcontrol/Element.h
r1211 r1336 50 50 virtual ~SignalFunctor() {} 51 51 52 virtual void operator() (int arg) = 0; 52 virtual void operator() () = 0; 53 virtual void operator() (int) = 0; 53 54 protected: 54 55 int m_id; … … 103 104 protected: 104 105 bool emitSignal(int id, int value); 106 bool emitSignal(int id); 105 107 Util::Mutex& getLock(); 106 108 … … 138 140 Container(Element *); 139 141 Container(Element *, std::string n); 140 virtual ~Container() {};141 142 virtual ~Container(); 143 142 144 virtual bool addElement(Element *e); 143 145 virtual bool deleteElement(Element *e); trunk/libffado/src/libieee1394/configrom.cpp
r1254 r1336 548 548 } 549 549 550 debugOutput( DEBUG_LEVEL_ NORMAL,551 "Device with GUID 0x%0 8x%08xcould not be found on "550 debugOutput( DEBUG_LEVEL_VERBOSE, 551 "Device with GUID 0x%016llX could not be found on " 552 552 "the bus anymore (removed?)\n", 553 m_guid >> 32,554 m_guid & 0xffffffff );553 getGuid() ); 554 m_nodeId = INVALID_NODE_ID; 555 555 return false; 556 556 } trunk/libffado/src/libieee1394/configrom.h
r1154 r1336 112 112 } 113 113 114 bool isPresentOnBus() { 115 return m_nodeId != INVALID_NODE_ID; 116 }; 114 117 protected: 115 118 void processUnitDirectory( struct csr1212_csr* csr, trunk/libffado/src/libieee1394/CycleTimerHelper.cpp
r1184 r1336 73 73 , m_realtime ( false ) 74 74 , m_priority ( 0 ) 75 , m_update_lock( new Util::PosixMutex( ) )75 , m_update_lock( new Util::PosixMutex("CTRUPD") ) 76 76 , m_busreset_functor ( NULL) 77 77 , m_unhandled_busreset ( false ) … … 99 99 , m_realtime ( rt ) 100 100 , m_priority ( prio ) 101 , m_update_lock( new Util::PosixMutex( ) )101 , m_update_lock( new Util::PosixMutex("CTRUPD") ) 102 102 , m_busreset_functor ( NULL) 103 103 , m_unhandled_busreset ( false ) … … 131 131 } 132 132 133 m_Thread = new Util::PosixThread(this, m_realtime, m_priority,133 m_Thread = new Util::PosixThread(this, "CTRHLP", m_realtime, m_priority, 134 134 PTHREAD_CANCEL_DEFERRED); 135 135 if(!m_Thread) { … … 418 418 } 419 419 m_first_run = false; 420 } else if (diff_ticks > 20.0*m_ticks_per_update) { 421 debugOutput(DEBUG_LEVEL_VERBOSE, 422 "re-init dll due to too large tick diff: %f >> %f\n", 423 diff_ticks, (float)(20.0*m_ticks_per_update)); 424 if(!initDLL()) { 425 debugError("(%p) Could not init DLL\n", this); 426 return false; 427 } 420 428 } else { 421 429 // calculate next sleep time trunk/libffado/src/libieee1394/ieee1394service.cpp
r1254 r1336 47 47 #include <iomanip> 48 48 49 using namespace std; 50 49 51 IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL ); 50 52 51 53 Ieee1394Service::Ieee1394Service() 52 54 : m_handle( 0 ) 53 , m_handle_lock( new Util::PosixMutex( ) )55 , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 54 56 , m_resetHandle( 0 ) 55 57 , m_util_handle( 0 ) 56 58 , m_port( -1 ) 57 , m_RHThread_lock( new Util::PosixMutex( ) )59 , m_RHThread_lock( new Util::PosixMutex("SRVCRH") ) 58 60 , m_threadRunning( false ) 59 61 , m_realtime ( false ) … … 77 79 Ieee1394Service::Ieee1394Service(bool rt, int prio) 78 80 : m_handle( 0 ) 79 , m_handle_lock( new Util::PosixMutex( ) )81 , m_handle_lock( new Util::PosixMutex("SRCVHND") ) 80 82 , m_resetHandle( 0 ) 81 83 , m_util_handle( 0 ) 82 84 , m_port( -1 ) 83 , m_RHThread_lock( new Util::PosixMutex( ) )85 , m_RHThread_lock( new Util::PosixMutex("SRVCRH") ) 84 86 , m_threadRunning( false ) 85 87 , m_realtime ( rt ) … … 158 160 debugOutput(DEBUG_LEVEL_VERBOSE, "Issue bus reset on service %p (port %d).\n", this, getPort()); 159 161 raw1394_reset_bus(m_handle); 162 } 163 164 /** 165 * This function waits until there are no bus resets generated in a sleep_time_ms interval 166 * @param nb_tries number of tries to take 167 * @param sleep_time_ms sleep between tries 168 * @return true if the storm passed 169 */ 170 bool 171 Ieee1394Service::waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms ) { 172 unsigned int gen_current; 173 do { 174 gen_current = getGeneration(); 175 debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting... (gen: %u)\n", gen_current); 176 177 // wait for a while 178 Util::SystemTimeSource::SleepUsecRelative( sleep_time_ms * 1000); 179 } while (gen_current != getGeneration() && --nb_tries); 180 181 if (!nb_tries) { 182 debugError( "Bus reset storm did not stop on time...\n"); 183 return false; 184 } 185 return true; 160 186 } 161 187 … … 415 441 { 416 442 Util::MutexLockHelper lock(*m_handle_lock); 417 using namespace std; 443 if (nodeId == INVALID_NODE_ID) { 444 debugWarning("operation on invalid node\n"); 445 return false; 446 } 418 447 if ( raw1394_read( m_handle, nodeId, addr, length*4, buffer ) == 0 ) { 419 448 … … 460 489 { 461 490 Util::MutexLockHelper lock(*m_handle_lock); 462 using namespace std; 491 if (nodeId == INVALID_NODE_ID) { 492 debugWarning("operation on invalid node\n"); 493 return false; 494 } 463 495 464 496 #ifdef DEBUG … … 489 521 490 522 bool 491 Ieee1394Service::lockCompareSwap64( fb_nodeid_t nodeId, 492 fb_nodeaddr_t addr, 493 fb_octlet_t compare_value, 494 fb_octlet_t swap_value, 495 fb_octlet_t* result ) 496 { 523 Ieee1394Service::lockCompareSwap64( fb_nodeid_t nodeId, 524 fb_nodeaddr_t addr, 525 fb_octlet_t compare_value, 526 fb_octlet_t swap_value, 527 fb_octlet_t* result ) 528 { 529 if (nodeId == INVALID_NODE_ID) { 530 debugWarning("operation on invalid node\n"); 531 return false; 532 } 497 533 #ifdef DEBUG 498 534 debugOutput(DEBUG_LEVEL_VERBOSE,"lockCompareSwap64: node 0x%X, addr = 0x%016llX\n", … … 543 579 unsigned int* resp_len ) 544 580 { 581 if (nodeId == INVALID_NODE_ID) { 582 debugWarning("operation on invalid node\n"); 583 return false; 584 } 545 585 // FIXME: this requires transactionBlockClose to unlock 546 586 m_handle_lock->Lock(); … … 626 666 { 627 667 quadlet_t buf=0; 668 669 m_handle_lock->Lock(); 670 raw1394_update_generation(m_handle, generation); 671 m_handle_lock->Unlock(); 628 672 629 673 // do a simple read on ourself in order to update the internal structures … … 809 853 { 810 854 if ( m_threadRunning ) { 855 // wait for the thread to finish it's work 811 856 m_RHThread_lock->Lock(); 812 857 pthread_cancel (m_thread); … … 823 868 824 869 while (true) { 825 raw1394_loop_iterate (pIeee1394Service->m_resetHandle); 870 // protect ourselves from dying 871 { 872 // use a scoped lock such that it is unlocked 873 // even if we are cancelled while running 874 // FIXME: check if this is true! 875 // Util::MutexLockHelper lock(*(pIeee1394Service->m_RHThread_lock)); 876 raw1394_loop_iterate (pIeee1394Service->m_resetHandle); 877 } 826 878 pthread_testcancel (); 827 879 } … … 935 987 nodeid_t recv_node, int recv_plug 936 988 ) { 989 990 if (xmit_node == INVALID_NODE_ID) { 991 debugWarning("operation on invalid node (XMIT)\n"); 992 return -1; 993 } 994 if (recv_node == INVALID_NODE_ID) { 995 debugWarning("operation on invalid node (RECV)\n"); 996 return -1; 997 } 937 998 938 999 debugOutput(DEBUG_LEVEL_VERBOSE, "Allocating ISO channel using IEC61883 CMP...\n" ); trunk/libffado/src/libieee1394/ieee1394service.h
r1161 r1336 227 227 228 228 bool transactionBlockClose(); 229 // FIXME: private for thread safety !!230 raw1394handle_t getHandle() {return m_handle;};231 229 232 230 int getVerboseLevel(); … … 236 234 237 235 void doBusReset(); 236 bool waitForBusResetStormToEnd( int nb_tries, int sleep_time_ms ); 238 237 239 238 /** … … 297 296 bool registerIsoChannel(unsigned int c, struct ChannelInfo cinfo); 298 297 298 public: 299 // FIXME: should be private, but is used to do the PCR control in GenericAVC::AvDevice 300 raw1394handle_t getHandle() {return m_handle;}; 301 299 302 private: 300 301 303 bool startRHThread(); 302 304 void stopRHThread(); … … 307 309 308 310 static int resetHandlerLowLevel( raw1394handle_t handle, 309 unsigned int generation );311 unsigned int generation ); 310 312 bool resetHandler( unsigned int generation ); 311 313 trunk/libffado/src/libieee1394/IsoHandler.cpp
r1254 r1336 63 63 unsigned int length, unsigned char channel, 64 64 unsigned char tag, unsigned char sy, unsigned int cycle, 65 unsigned int dropped 1) {65 unsigned int dropped) { 66 66 67 67 IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 68 68 assert(recvHandler); 69 69 70 unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16; 71 unsigned int dropped = dropped1 & 0xFFFF; 72 73 return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped, skipped); 74 } 75 76 int IsoHandler::busreset_handler(raw1394handle_t handle, unsigned int generation) 77 { 78 debugOutput( DEBUG_LEVEL_VERBOSE, "Busreset happened, generation %d...\n", generation); 79 80 IsoHandler *handler = static_cast<IsoHandler *>(raw1394_get_userdata(handle)); 81 assert(handler); 82 return handler->handleBusReset(generation); 70 return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped); 83 71 } 84 72 … … 92 80 , m_last_cycle( -1 ) 93 81 , m_last_now( 0xFFFFFFFF ) 82 , m_last_packet_handled_at( 0xFFFFFFFF ) 94 83 , m_Client( 0 ) 95 84 , m_speed( RAW1394_ISO_SPEED_400 ) … … 100 89 , m_packets ( 0 ) 101 90 , m_dropped( 0 ) 91 , m_skipped( 0 ) 102 92 , m_min_ahead( 7999 ) 103 93 #endif … … 115 105 , m_last_cycle( -1 ) 116 106 , m_last_now( 0xFFFFFFFF ) 107 , m_last_packet_handled_at( 0xFFFFFFFF ) 117 108 , m_Client( 0 ) 118 109 , m_speed( RAW1394_ISO_SPEED_400 ) … … 122 113 , m_packets ( 0 ) 123 114 , m_dropped( 0 ) 115 , m_skipped( 0 ) 124 116 , m_min_ahead( 7999 ) 125 117 #endif … … 138 130 , m_last_cycle( -1 ) 139 131 , m_last_now( 0xFFFFFFFF ) 132 , m_last_packet_handled_at( 0xFFFFFFFF ) 140 133 , m_Client( 0 ) 141 134 , m_speed( speed ) … … 145 138 , m_packets( 0 ) 146 139 , m_dropped( 0 ) 140 , m_skipped( 0 ) 141 , m_min_ahead( 7999 ) 147 142 #endif 148 143 { … … 169 164 if(m_Client) { 170 165 bool result; 166 171 167 if (m_type == eHT_Receive) { 172 168 result = m_Client->canProducePacket(); … … 175 171 } 176 172 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 177 return result ;173 return result && (m_State != E_Error); 178 174 } else { 179 175 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n"); … … 234 230 raw1394_set_userdata(m_handle, static_cast<void *>(this)); 235 231 236 // bus reset handling237 if(raw1394_busreset_notify (m_handle, RAW1394_NOTIFY_ON)) {238 debugWarning("Could not enable busreset notification.\n");239 debugWarning(" Error message: %s\n",strerror(errno));240 debugWarning("Continuing without bus reset support.\n");241 } else {242 // apparently this cannot fail243 raw1394_set_bus_reset_handler(m_handle, busreset_handler);244 }245 246 232 // update the internal state 247 233 m_State=E_Initialized; … … 261 247 } 262 248 249 debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) wake up handle...\n", 250 this, (m_type==eHT_Receive?"Receive":"Transmit")); 251 252 // wake up any waiting reads/polls 253 raw1394_wake_up(m_handle); 254 263 255 // this is put here to try and avoid the 264 256 // Runaway context problem 265 257 // don't know if it will help though. 266 raw1394_iso_xmit_sync(m_handle); 258 /* if(m_State != E_Error) { // if the handler is dead, this might block forever 259 raw1394_iso_xmit_sync(m_handle); 260 }*/ 261 debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) stop...\n", 262 this, (m_type==eHT_Receive?"Receive":"Transmit")); 267 263 raw1394_iso_stop(m_handle); 268 264 m_State = E_Prepared; … … 276 272 */ 277 273 278 int 279 IsoHandler::handleBusReset(unsigned int generation) 280 { 281 debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 274 bool 275 IsoHandler::handleBusReset() 276 { 277 debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n"); 278 m_last_packet_handled_at = 0xFFFFFFFF; 282 279 283 280 #define CSR_CYCLE_TIME 0x200 … … 289 286 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 290 287 291 // notify the client of the fact that we have died 292 m_Client->handlerDied(); 293 294 if(!disable()) { 295 debugError("(%p) Could not disable IsoHandler\n", this); 296 } 297 298 // request the manager to update it's shadow map 299 m_manager.requestShadowMapUpdate(); 300 return 0; 288 return m_Client->handleBusReset(); 301 289 } 302 290 … … 308 296 IsoHandler::notifyOfDeath() 309 297 { 298 m_State = E_Error; 299 310 300 // notify the client of the fact that we have died 311 301 m_Client->handlerDied(); 302 303 // wake ourselves up 304 raw1394_wake_up(m_handle); 312 305 } 313 306 … … 331 324 } 332 325 #ifdef DEBUG 333 debugOutputShort( DEBUG_LEVEL_NORMAL, " Last cycle, dropped.........: %4d, %4u \n",334 m_last_cycle, m_dropped );326 debugOutputShort( DEBUG_LEVEL_NORMAL, " Last cycle, dropped.........: %4d, %4u, %4u\n", 327 m_last_cycle, m_dropped, m_skipped); 335 328 #endif 336 329 … … 340 333 { 341 334 setDebugLevel(l); 335 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 342 336 } 343 337 … … 381 375 unsigned char *data, unsigned int length, 382 376 unsigned char channel, unsigned char tag, unsigned char sy, 383 unsigned int cycle, unsigned int dropped , unsigned int skipped) {377 unsigned int cycle, unsigned int dropped) { 384 378 385 379 // keep track of dropped cycles … … 389 383 #ifdef DEBUG 390 384 if (dropped_cycles < 0) { 391 debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d , 'skipped'=%u\n",392 this, dropped_cycles, cycle, m_last_cycle, dropped , skipped);385 debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n", 386 this, dropped_cycles, cycle, m_last_cycle, dropped); 393 387 } 394 388 if (dropped_cycles > 0) { 395 debugOutput(DEBUG_LEVEL_ NORMAL,396 "(%p) dropped %d packets on cycle %u, 'dropped'=%u, 'skipped'=%u,cycle=%d, m_last_cycle=%d\n",397 this, dropped_cycles, cycle, dropped, skipped,cycle, m_last_cycle);389 debugOutput(DEBUG_LEVEL_VERBOSE, 390 "(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n", 391 this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); 398 392 m_dropped += dropped_cycles; 399 393 } … … 448 442 && dropped_cycles == 0) 449 443 { 450 debugOutput(DEBUG_LEVEL_VER BOSE, "Special non-unwrapping happened\n");444 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Special non-unwrapping happened\n"); 451 445 } 452 446 #endif … … 477 471 } 478 472 #endif 473 m_last_packet_handled_at = pkt_ctr; 479 474 480 475 // leave the offset field (for now?) 481 476 482 debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 483 "received packet: length=%d, channel=%d, cycle=%d\n", 484 length, channel, cycle); 477 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 478 "received packet: length=%d, channel=%d, cycle=%d, at %08X\n", 479 length, channel, cycle, pkt_ctr); 480 m_packets++; 485 481 #ifdef DEBUG 486 m_packets++;487 482 if (length > m_max_packet_size) { 488 483 debugWarning("(%p, %s) packet too large: len=%u max=%u\n", … … 496 491 // iterate the client if required 497 492 if(m_Client) { 498 enum raw1394_iso_disposition retval = m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles , skipped);493 enum raw1394_iso_disposition retval = m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles); 499 494 if (retval == RAW1394_ISO_OK) { 500 495 if (m_dont_exit_iterate_loop) { … … 527 522 pkt_ctr = cycle << 12; 528 523 529 #if 0 // we don't need this for xmit530 524 // if we assume that one iterate() loop doesn't take longer than 0.5 seconds, 531 525 // the seconds field won't change while the iterate loop runs … … 560 554 uint32_t pkt_ctr_ref = cycle << 12; 561 555 pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25; 562 556 563 557 if(pkt_ctr != pkt_ctr_ref) { 564 558 debugWarning("reconstructed CTR counter discrepancy\n"); … … 566 560 } 567 561 #endif 568 #endif 569 } 570 571 debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 572 "sending packet: length=%d, cycle=%d\n", 573 *length, cycle); 562 } 563 if (m_packets < m_buf_packets) { // these are still prebuffer packets 564 m_last_packet_handled_at = 0xFFFFFFFF; 565 } else { 566 m_last_packet_handled_at = pkt_ctr; 567 } 568 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 569 "sending packet: length=%d, cycle=%d, at %08X\n", 570 *length, cycle, pkt_ctr); 571 572 m_packets++; 574 573 575 574 #ifdef DEBUG 576 m_packets++;577 575 if(m_last_cycle == -1) { 578 576 debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %d)\n", getTypeString(), this, cycle); … … 590 588 #ifdef DEBUG 591 589 if(skipped) { 592 debugOutput(DEBUG_LEVEL_ NORMAL,590 debugOutput(DEBUG_LEVEL_VERBOSE, 593 591 "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n", 594 592 this, skipped, cycle, m_last_cycle, dropped); 593 m_skipped += skipped; 595 594 } 596 595 if (dropped_cycles < 0) { … … 599 598 } 600 599 if (dropped_cycles > 0) { 601 debugOutput(DEBUG_LEVEL_ NORMAL,600 debugOutput(DEBUG_LEVEL_VERBOSE, 602 601 "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n", 603 602 this, dropped_cycles, cycle, m_last_cycle, dropped, skipped); … … 616 615 } 617 616 617 #ifdef DEBUG 618 if (dropped > 0) { 619 debugOutput(DEBUG_LEVEL_VERBOSE, 620 "(%p) OHCI issue on cycle %u (dropped_cycles=%d, last_cycle=%u, dropped=%d, skipped: %d)\n", 621 this, cycle, dropped_cycles, m_last_cycle, dropped, skipped); 622 } 623 #endif 624 618 625 if(m_Client) { 619 626 enum raw1394_iso_disposition retval; 620 retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped , skipped, m_max_packet_size);627 retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped_cycles, skipped, m_max_packet_size); 621 628 #ifdef DEBUG 622 629 if (*length > m_max_packet_size) { trunk/libffado/src/libieee1394/IsoHandler.h
r1246 r1336 69 69 putPacket(unsigned char *data, unsigned int length, 70 70 unsigned char channel, unsigned char tag, unsigned char sy, 71 unsigned int cycle, unsigned int dropped , unsigned int skipped);71 unsigned int cycle, unsigned int dropped); 72 72 73 73 static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle, … … 162 162 uint32_t getLastIterateTime() {return m_last_now;}; 163 163 164 /** 165 * @brief returns the CTR value saved at the last iterate handler call 166 * @return CTR value saved at last iterate handler call 167 */ 168 uint32_t getLastPacketTime() {return m_last_packet_handled_at;}; 169 164 170 void notifyOfDeath(); 171 bool handleBusReset(); 172 165 173 private: 166 174 IsoHandlerManager& m_manager; … … 172 180 int m_last_cycle; 173 181 uint32_t m_last_now; 182 uint32_t m_last_packet_handled_at; 174 183 175 184 Streaming::StreamProcessor *m_Client; // FIXME: implement with functors 176 177 int handleBusReset(unsigned int generation);178 179 static int busreset_handler(raw1394handle_t handle, unsigned int generation);180 185 181 186 enum raw1394_iso_speed m_speed; … … 189 194 E_Prepared, 190 195 E_Running, 191 E_Error 196 E_Error, 192 197 }; 193 198 enum EHandlerStates m_State; 194 199 200 public: 201 unsigned int m_packets; 195 202 #ifdef DEBUG 196 unsigned int m_packets;197 203 unsigned int m_dropped; 204 unsigned int m_skipped; 198 205 int m_min_ahead; 199 206 #endif 200 207 208 protected: 201 209 DECLARE_DEBUG_MODULE; 202 210 }; trunk/libffado/src/libieee1394/IsoHandlerManager.cpp
r1254 r1336 48 48 , m_SyncIsoHandler ( NULL ) 49 49 , m_handlerType( t ) 50 , m_running( false ) 51 , m_in_busreset( false ) 50 52 { 51 53 } … … 74 76 75 77 sem_init(&m_activity_semaphore, 0, 0); 78 m_running = true; 76 79 return true; 77 80 } … … 82 85 debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) enter\n", this); 83 86 INC_ATOMIC(&request_update); 87 88 // get the thread going again 89 signalActivity(); 90 91 if (m_running) { 92 int timeout = 1000; 93 while(request_update && timeout--) { 94 Util::SystemTimeSource::SleepUsecRelative(1000); 95 } 96 if(timeout == 0) { 97 debugError("timeout waiting for shadow map update\n"); 98 } 99 } 100 debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) exit\n", this); 84 101 return true; 102 } 103 104 bool 105 IsoTask::handleBusReset() 106 { 107 bool retval = true; 108 m_in_busreset = true; 109 requestShadowMapUpdate(); 110 if(request_update) { 111 debugError("shadow map update request not honored\n"); 112 return false; 113 } 114 115 unsigned int i, max; 116 max = m_manager.m_IsoHandlers.size(); 117 for (i = 0; i < max; i++) { 118 IsoHandler *h = m_manager.m_IsoHandlers.at(i); 119 assert(h); 120 121 // skip the handlers not intended for us 122 if(h->getType() != m_handlerType) continue; 123 124 if (!h->handleBusReset()) { 125 debugWarning("Failed to handle busreset on %p\n"); 126 retval = false; 127 } 128 } 129 130 // re-enable processing 131 m_in_busreset = false; 132 requestShadowMapUpdate(); 133 if(request_update) { 134 debugError("shadow map update request not honored\n"); 135 return false; 136 } 137 return retval; 85 138 } 86 139 … … 92 145 { 93 146 debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updating shadow vars...\n", this); 147 // we are handling a busreset 148 if(m_in_busreset) { 149 m_poll_nfds_shadow = 0; 150 return; 151 } 94 152 unsigned int i, cnt, max; 95 153 max = m_manager.m_IsoHandlers.size(); … … 140 198 IsoTask::Execute() 141 199 { 142 debugOutput Extreme(DEBUG_LEVEL_VERY_VERBOSE,143 144 200 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 201 "(%p, %s) Execute\n", 202 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 145 203 int err; 146 204 unsigned int i; … … 158 216 if(m_successive_short_loops > 10000) { 159 217 debugError("Shutting down runaway thread\n"); 218 m_running = false; 160 219 return false; 161 220 } … … 210 269 211 270 if(no_one_to_poll) { 212 debugOutput Extreme(DEBUG_LEVEL_VERBOSE,213 214 271 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 272 "(%p, %s) No one to poll, waiting for something to happen\n", 273 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 215 274 // wait for something to happen 216 275 switch(waitForActivity()) { … … 248 307 } 249 308 debugFatal("poll error: %s\n", strerror (errno)); 309 m_running = false; 250 310 return false; 251 311 } … … 256 316 for (i = 0; i < m_poll_nfds_shadow; i++) { 257 317 // figure out if a handler has died 258 // all handlers in the poll() are active, so they should be iterated 259 // now and then. If they aren't, the handler has died.260 uint32_t last_ call = m_IsoHandler_map_shadow[i]->getLastIterateTime();261 if (last_ call== 0xFFFFFFFF) {318 319 // this is the time of the last packet we saw in the iterate() handler 320 uint32_t last_packet_seen = m_IsoHandler_map_shadow[i]->getLastPacketTime(); 321 if (last_packet_seen == 0xFFFFFFFF) { 262 322 // this was not iterated yet, so can't be dead 323 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 324 "(%p, %s) handler %d didn't see any packets yet\n", 325 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), i); 263 326 continue; 264 327 } 265 328 266 uint64_t last_call_ticks = CYCLE_TIMER_TO_TICKS(last_call); 267 // we use 4 seconds since that should not cause issues with startup 268 int64_t max_diff_ticks = TICKS_PER_SECOND * 4; 269 int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_call_ticks); 270 329 uint64_t last_packet_seen_ticks = CYCLE_TIMER_TO_TICKS(last_packet_seen); 330 // we use a relatively large value to distinguish between "death" and xrun 331 int64_t max_diff_ticks = TICKS_PER_SECOND * 2; 332 int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_packet_seen_ticks); 333 334 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 335 "(%p, %s) check handler %d: diff = %lld, max = %lld, now: %08lX, last: %08lX\n", 336 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), 337 i, measured_diff_ticks, max_diff_ticks, ctr_at_poll_return, last_packet_seen); 271 338 if(measured_diff_ticks > max_diff_ticks) { 272 339 debugFatal("(%p, %s) Handler died: now: %08lX, last: %08lX, diff: %lld (max: %lld)\n", 273 340 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), 274 ctr_at_poll_return, last_ call, measured_diff_ticks, max_diff_ticks);341 ctr_at_poll_return, last_packet_seen, measured_diff_ticks, max_diff_ticks); 275 342 m_IsoHandler_map_shadow[i]->notifyOfDeath(); 276 343 handler_died = true; … … 278 345 } 279 346 if(handler_died) { 347 m_running = false; 280 348 return false; // one or more handlers have died 281 349 } … … 321 389 struct timespec ts; 322 390 int result; 391 long long int timeout_nsec = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL; 323 392 324 393 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { … … 326 395 return eAR_Error; 327 396 } 328 long long int timeout_nsec=0; 329 int timeout_sec = 0; 330 331 timeout_nsec = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL; 332 timeout_sec = 0; 333 while(timeout_nsec >= 1000000000LL) { 334 timeout_sec += 1; 335 timeout_nsec -= 1000000000LL; 336 } 397 337 398 ts.tv_nsec += timeout_nsec; 338 ts.tv_sec += timeout_sec; 399 while(ts.tv_nsec >= 1000000000LL) { 400 ts.tv_sec += 1; 401 ts.tv_nsec -= 1000000000LL; 402 } 339 403 340 404 result = sem_timedwait(&m_activity_semaphore, &ts); … … 351 415 this, result); 352 416 return eAR_Interrupted; 417 } else if (errno == EINVAL) { 418 debugError("(%p) sem_timedwait error (result=%d errno=EINVAL)\n", 419 this, result); 420 debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n", 421 this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 422 return eAR_Error; 353 423 } else { 354 424 debugError("(%p) sem_timedwait error (result=%d errno=%d)\n", 355 425 this, result, errno); 356 debugError("(%p) timeout_ sec=%d timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",357 this, timeout_ sec, timeout_nsec, ts.tv_sec, ts.tv_nsec);426 debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n", 427 this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 358 428 return eAR_Error; 359 429 } 360 430 } 361 431 362 debugOutput Extreme(DEBUG_LEVEL_VERBOSE,363 364 432 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 433 "(%p, %s) got activity\n", 434 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 365 435 return eAR_Activity; 366 436 } … … 371 441 // signal the activity cond var 372 442 sem_post(&m_activity_semaphore); 373 debugOutput Extreme(DEBUG_LEVEL_VERBOSE,374 375 443 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 444 "(%p, %s) activity\n", 445 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive")); 376 446 } 377 447 378 448 void IsoTask::setVerboseLevel(int i) { 379 449 setDebugLevel(i); 450 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i ); 380 451 } 381 452 … … 426 497 } 427 498 499 bool 500 IsoHandlerManager::handleBusReset() 501 { 502 debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n"); 503 // A few things can happen on bus reset: 504 // 1) no devices added/removed => streams are still valid, but might have to be restarted 505 // 2) a device was removed => some streams become invalid 506 // 3) a device was added => same as 1, new device is ignored 507 if (!m_IsoTaskTransmit) { 508 debugError("No xmit task\n"); 509 return false; 510 } 511 if (!m_IsoTaskReceive) { 512 debugError("No receive task\n"); 513 return false; 514 } 515 if (!m_IsoTaskTransmit->handleBusReset()) { 516 debugWarning("could no handle busreset on xmit\n"); 517 } 518 if (!m_IsoTaskReceive->handleBusReset()) { 519 debugWarning("could no handle busreset on recv\n"); 520 } 521 return true; 522 } 523 428 524 void 429 525 IsoHandlerManager::requestShadowMapUpdate() … … 479 575 } 480 576 m_IsoTaskTransmit->setVerboseLevel(getDebugLevel()); 481 m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, m_realtime,577 m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, "ISOXMT", m_realtime, 482 578 m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 483 579 + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT, … … 497 593 } 498 594 m_IsoTaskReceive->setVerboseLevel(getDebugLevel()); 499 m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, m_realtime,595 m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, "ISORCV", m_realtime, 500 596 m_priority + ISOHANDLERMANAGER_ISO_PRIO_INCREASE 501 597 + ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV, … … 642 738 bool IsoHandlerManager::registerStream(StreamProcessor *stream) 643 739 { 644 debugOutput( DEBUG_LEVEL_VERBOSE, "Registering stream %p\n",stream);740 debugOutput( DEBUG_LEVEL_VERBOSE, "Registering %s stream %p\n", stream->getTypeString(), stream); 645 741 assert(stream); 646 742 … … 767 863 bool IsoHandlerManager::unregisterStream(StreamProcessor *stream) 768 864 { 769 debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering stream %p\n",stream);865 debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering %s stream %p\n", stream->getTypeString(), stream); 770 866 assert(stream); 771 867 … … 895 991 { 896 992 if((*it)->isStreamRegistered(stream)) { 897 return(*it)->flush();993 (*it)->flush(); 898 994 } 899 995 } 900 996 debugError("Stream %p has no attached handler\n", stream); 901 997 return; 998 } 999 1000 IsoHandler * 1001 IsoHandlerManager::getHandlerForStream(Streaming::StreamProcessor *stream) { 1002 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 1003 it != m_IsoHandlers.end(); 1004 ++it ) 1005 { 1006 if((*it)->isStreamRegistered(stream)) { 1007 return (*it); 1008 } 1009 } 1010 debugError("Stream %p has no attached handler\n", stream); 1011 return NULL; 902 1012 } 903 1013 … … 1005 1115 if(m_IsoThreadReceive) m_IsoThreadReceive->setVerboseLevel(i); 1006 1116 if(m_IsoTaskReceive) m_IsoTaskReceive->setVerboseLevel(i); 1117 setDebugLevel(i); 1118 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i ); 1007 1119 } 1008 1120 trunk/libffado/src/libieee1394/IsoHandlerManager.h
r1254 r1336 44 44 namespace Streaming { 45 45 class StreamProcessor; 46 class StreamProcessorManager;47 46 typedef std::vector<StreamProcessor *> StreamProcessorVector; 48 47 typedef std::vector<StreamProcessor *>::iterator StreamProcessorVectorIterator; … … 87 86 enum eActivityResult waitForActivity(); 88 87 88 /** 89 * @brief This should be called when a busreset has happened. 90 */ 91 bool handleBusReset(); 92 89 93 void setVerboseLevel(int i); 90 94 protected: … … 114 118 115 119 enum IsoHandler::EHandlerType m_handlerType; 120 bool m_running; 121 bool m_in_busreset; 122 116 123 // debug stuff 117 124 DECLARE_DEBUG_MODULE; … … 181 188 182 189 void flushHandlerForStream(Streaming::StreamProcessor *stream); 190 IsoHandler * getHandlerForStream(Streaming::StreamProcessor *stream); 183 191 184 192 Ieee1394Service& get1394Service() {return m_service;}; … … 186 194 void requestShadowMapUpdate(); 187 195 196 /** 197 * This should be called when a busreset has happened. 198 */ 199 bool handleBusReset(); 188 200 // the state machine 189 201 private: trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r1254 r1336 195 195 { 196 196 // we are too late 197 debugOutput(DEBUG_LEVEL_VER Y_VERBOSE,197 debugOutput(DEBUG_LEVEL_VERBOSE, 198 198 "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n", 199 199 CYCLE_TIMER_GET_CYCLES(pkt_ctr), … … 492 492 unsigned int j; 493 493 quadlet_t *target_event; 494 unsignedint i;494 int i; 495 495 496 496 for (i = 0; i < m_nb_audio_ports; i++) { … … 523 523 unsigned int j; 524 524 quadlet_t *target_event; 525 unsignedint i;525 int i; 526 526 527 527 float * client_buffers[4]; … … 543 543 // this assumes that audio ports are sorted by position, 544 544 // and that there are no gaps 545 for (i = 0; i < m_nb_audio_ports-4; i += 4) {545 for (i = 0; i < ((int)m_nb_audio_ports)-4; i += 4) { 546 546 struct _MBLA_port_cache *p; 547 547 … … 615 615 // do remaining ports 616 616 // NOTE: these can be time-SSE'd 617 for (; i < m_nb_audio_ports; i++) {617 for (; i < (int)m_nb_audio_ports; i++) { 618 618 struct _MBLA_port_cache &p = m_audio_ports.at(i); 619 619 target_event = (quadlet_t *)(data + i); … … 715 715 unsigned int j; 716 716 quadlet_t *target_event; 717 unsignedint i;717 int i; 718 718 719 719 uint32_t *client_buffers[4]; … … 729 729 // this assumes that audio ports are sorted by position, 730 730 // and that there are no gaps 731 for (i = 0; i < m_nb_audio_ports-4; i += 4) {731 for (i = 0; i < ((int)m_nb_audio_ports)-4; i += 4) { 732 732 struct _MBLA_port_cache *p; 733 733 … … 789 789 // do remaining ports 790 790 // NOTE: these can be time-SSE'd 791 for (; i < m_nb_audio_ports; i++) {791 for (; i < ((int)m_nb_audio_ports); i++) { 792 792 struct _MBLA_port_cache &p = m_audio_ports.at(i); 793 793 target_event = (quadlet_t *)(data + i); … … 872 872 unsigned int j; 873 873 quadlet_t *target_event; 874 unsignedint i;874 int i; 875 875 876 876 for (i = 0; i < m_nb_audio_ports; i++) { … … 913 913 unsigned int j; 914 914 quadlet_t *target_event; 915 unsignedint i;915 int i; 916 916 917 917 for (i = 0; i < m_nb_audio_ports; i++) { … … 962 962 { 963 963 quadlet_t *target_event; 964 unsigned int i,j; 964 int i; 965 unsigned int j; 965 966 966 967 for (i = 0; i < m_nb_midi_ports; i++) { … … 986 987 { 987 988 quadlet_t *target_event; 988 unsigned int i,j; 989 int i; 990 unsigned int j; 989 991 990 992 for (i = 0; i < m_nb_midi_ports; i++) { … … 1062 1064 } 1063 1065 1064 unsignedint idx;1066 int idx; 1065 1067 for (idx = 0; idx < m_nb_audio_ports; idx++) { 1066 1068 for(PortVectorIterator it = m_Ports.begin(); … … 1072 1074 "idx %u: looking at port %s at position %u\n", 1073 1075 idx, (*it)->getName().c_str(), pinfo->getPosition()); 1074 if(pinfo->getPosition() == idx) {1076 if(pinfo->getPosition() == (unsigned int)idx) { 1075 1077 struct _MBLA_port_cache p; 1076 1078 p.port = dynamic_cast<AmdtpAudioPort *>(*it); … … 1131 1133 void 1132 1134 AmdtpTransmitStreamProcessor::updatePortCache() { 1133 unsignedint idx;1135 int idx; 1134 1136 for (idx = 0; idx < m_nb_audio_ports; idx++) { 1135 1137 struct _MBLA_port_cache& p = m_audio_ports.at(idx); trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h
r1034 r1336 150 150 }; 151 151 std::vector<struct _MBLA_port_cache> m_audio_ports; 152 unsignedint m_nb_audio_ports;152 int m_nb_audio_ports; 153 153 154 154 struct _MIDI_port_cache { … … 163 163 }; 164 164 std::vector<struct _MIDI_port_cache> m_midi_ports; 165 unsignedint m_nb_midi_ports;165 int m_nb_midi_ports; 166 166 167 167 bool initPortCache(); trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp
r1254 r1336 93 93 } 94 94 95 void 95 bool 96 StreamProcessor::handleBusResetDo() 97 { 98 debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handling busreset\n", this); 99 m_state = ePS_Error; 100 // this will result in the SPM dying 101 m_in_xrun = true; 102 SIGNAL_ACTIVITY_ALL; 103 return true; 104 } 105 106 bool 96 107 StreamProcessor::handleBusReset() 97 108 { 98 109 debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handling busreset\n", this); 99 // for now, we try and make sure everything is cleanly shutdown 100 if(!stopRunning(-1)) { 101 debugError("Failed to stop SP\n"); 102 } 103 SIGNAL_ACTIVITY_ALL; 110 111 // we are sure that we're not iterated since this is called from within the ISO manager thread 112 113 // lock the wait loop of the SPM, such that the client leaves us alone 114 m_StreamProcessorManager.lockWaitLoop(); 115 116 // pass on to the implementing classes 117 bool retval = handleBusResetDo(); 118 119 // resume wait loop 120 m_StreamProcessorManager.unlockWaitLoop(); 121 122 return retval; 104 123 } 105 124 … … 109 128 m_state = ePS_Stopped; 110 129 m_in_xrun = true; 130 SIGNAL_ACTIVITY_ALL; 111 131 } 112 132 … … 287 307 unsigned char channel, unsigned char tag, unsigned char sy, 288 308 uint32_t pkt_ctr, 289 unsigned int dropped_cycles , unsigned int skipped) {309 unsigned int dropped_cycles) { 290 310 // bypass based upon state 291 311 #ifdef DEBUG … … 298 318 if (m_state == ePS_Created) { 299 319 return RAW1394_ISO_DEFER; 320 } 321 322 if (m_state == ePS_Error) { 323 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "skip due to error state\n"); 324 return RAW1394_ISO_OK; 300 325 } 301 326 … … 365 390 366 391 if (result == eCRV_OK) { 367 #ifdef DEBUG392 // #ifdef DEBUG 368 393 int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 369 394 int diff = diffTicks(m_last_timestamp, m_last_timestamp2); … … 376 401 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 377 402 m_last_timestamp, diff, ticks_per_packet); 403 // !!!HACK!!! FIXME: this is the result of a failure in wrapping/unwrapping somewhere 404 // it's definitely a bug. 405 // try to fix up the timestamp 406 int64_t last_timestamp_fixed; 407 // first try to add one second 408 last_timestamp_fixed = m_last_timestamp + TICKS_PER_SECOND; 409 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 410 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 411 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 412 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 413 m_last_timestamp, diff, ticks_per_packet); 414 debugWarning("HACK: fixed by adding one second of ticks. This is a bug being run-time fixed.\n"); 415 m_last_timestamp = last_timestamp_fixed; 416 } 417 // then try to subtract one second 418 last_timestamp_fixed = m_last_timestamp - TICKS_PER_SECOND; 419 if(last_timestamp_fixed >= 0) { 420 diff = diffTicks(last_timestamp_fixed, m_last_timestamp2); 421 if(diff-ticks_per_packet < 50 && diff-ticks_per_packet > -50) { 422 debugWarning("cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 423 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp2, 424 m_last_timestamp, diff, ticks_per_packet); 425 debugWarning("HACK: fixed by subtracing one second of ticks. This is a bug being run-time fixed.\n"); 426 m_last_timestamp = last_timestamp_fixed; 427 } 428 } 378 429 } 379 430 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, … … 382 433 m_last_timestamp2, m_last_timestamp, 383 434 diff, ticks_per_packet); 384 #endif435 // #endif 385 436 386 437 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, … … 488 539 return RAW1394_ISO_OK; 489 540 } 541 542 if (m_state == ePS_Error) { 543 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "skip due to error state\n"); 544 return RAW1394_ISO_OK; 545 } 546 490 547 uint64_t prev_timestamp; 491 492 548 // note that we can ignore skipped cycles since 493 549 // the protocol will take care of that … … 498 554 if(m_state == ePS_Running) { 499 555 debugShowBackLogLines(200); 500 debugOutput(DEBUG_LEVEL_NORMAL, "dropped packets xrun \n");556 debugOutput(DEBUG_LEVEL_NORMAL, "dropped packets xrun (%u)\n", dropped_cycles); 501 557 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packets xrun\n"); 502 558 m_cycle_to_switch_state = CYCLE_TIMER_GET_CYCLES(pkt_ctr) + 1; … … 554 610 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 555 611 "XMIT SILENT: CY=%04u TS=%011llu\n", 556 cycle, m_last_timestamp);612 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp); 557 613 558 614 // assumed not to xrun … … 605 661 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 606 662 "XMIT: CY=%04u TS=%011llu\n", 607 cycle, m_last_timestamp);663 CYCLE_TIMER_GET_CYCLES(pkt_ctr), m_last_timestamp); 608 664 609 665 // valid packet timestamp … … 876 932 StreamProcessor::shiftStream(int nbframes) 877 933 { 934 // FIXME: this is not a good idea since the ISO thread is also writing the buffer 935 // resulting in multiple writers (not supported) 878 936 bool result; 879 937 if(nbframes == 0) return true; 880 938 if(nbframes > 0) { 939 debugOutput(DEBUG_LEVEL_VERBOSE, 940 "(%p) dropping %d frames\n", 941 this, nbframes); 881 942 result = m_data_buffer->dropFrames(nbframes); 882 SIGNAL_ACTIVITY_ALL; 943 } else { 944 result = false; 883 945 return result; 884 } else { 885 result = true; 946 debugOutput(DEBUG_LEVEL_VERBOSE, 947 "(%p) adding %d frames\n", 948 this, nbframes); 886 949 while(nbframes++) { 887 950 result &= m_data_buffer->writeDummyFrame(); 888 951 } 889 SIGNAL_ACTIVITY_ALL;890 return result;891 }952 } 953 SIGNAL_ACTIVITY_ALL; 954 return result; 892 955 } 893 956 … … 1767 1830 case ePS_Running: return "ePS_Running"; 1768 1831 case ePS_WaitingForStreamDisable: return "ePS_WaitingForStreamDisable"; 1832 case ePS_Error: return "ePS_Error"; 1769 1833 default: return "error: unknown state"; 1770 1834 } … … 1793 1857 #ifdef DEBUG 1794 1858 debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor %p, %s:\n", this, ePTToString(m_processor_type)); 1795 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : %d, %d\n", m_1394service.getPort(), m_channel); 1859 debugOutputShort( DEBUG_LEVEL_NORMAL, " Port, Channel : %d, %d\n", m_1394service.getPort(), m_channel); 1860 IsoHandler *h = m_IsoHandlerManager.getHandlerForStream(this); 1861 if (h) { 1862 debugOutputShort( DEBUG_LEVEL_NORMAL, " Packets, Dropped, Skipped : %d, %d, %d\n", 1863 h->m_packets, h->m_dropped, h->m_skipped); 1864 } else { 1865 debugError("No handler for stream??\n"); 1866 } 1796 1867 uint64_t now = m_1394service.getCycleTimerTicks(); 1797 1868 debugOutputShort( DEBUG_LEVEL_NORMAL, " Now : %011llu (%03us %04uc %04ut)\n", … … 1835 1906 PortManager::setVerboseLevel(l); 1836 1907 m_data_buffer->setVerboseLevel(l); 1908 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 1837 1909 } 1838 1910 trunk/libffado/src/libstreaming/generic/StreamProcessor.h
r1036 r1336 79 79 ePS_Running, 80 80 ePS_WaitingForStreamDisable, 81 ePS_Error, 81 82 }; 82 83 … … 113 114 bool isWaitingForStream() 114 115 {return m_state == ePS_WaitingForStream;}; 116 bool inError() 117 {return m_state == ePS_Error;}; 115 118 116 119 // these schedule and wait for the state transition … … 131 134 bool prepare(); 132 135 133 void handleBusReset(); 136 bool handleBusReset(); 137 138 // the one to be implemented by the child class 139 virtual bool handleBusResetDo(); 140 141 FFADODevice& getParent() {return m_Parent;}; 134 142 135 143 public: // constructor/destructor … … 153 161 putPacket(unsigned char *data, unsigned int length, 154 162 unsigned char channel, unsigned char tag, unsigned char sy, 155 uint32_t pkt_ctr, unsigned int dropped , unsigned int skipped);163 uint32_t pkt_ctr, unsigned int dropped); 156 164 157 165 enum raw1394_iso_disposition trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r1254 r1336 29 29 #include "libieee1394/cycletimer.h" 30 30 31 #include "devicemanager.h" 32 31 33 #include "libutil/Time.h" 32 34 … … 39 41 IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE ); 40 42 41 StreamProcessorManager::StreamProcessorManager( )43 StreamProcessorManager::StreamProcessorManager(DeviceManager &p) 42 44 : m_is_slave( false ) 43 45 , m_SyncSource(NULL) 46 , m_parent( p ) 44 47 , m_xrun_happened( false ) 45 48 , m_activity_wait_timeout_usec( 1000*1000 ) … … 51 54 , m_shutdown_needed(false) 52 55 , m_nbperiods(0) 53 , m_WaitLock( new Util::PosixMutex )56 , m_WaitLock( new Util::PosixMutex("SPMWAIT") ) 54 57 { 55 58 addOption(Util::OptionContainer::Option("slaveMode",false)); … … 57 60 } 58 61 59 StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int framerate, unsigned int nb_buffers) 62 StreamProcessorManager::StreamProcessorManager(DeviceManager &p, unsigned int period, 63 unsigned int framerate, unsigned int nb_buffers) 60 64 : m_is_slave( false ) 61 65 , m_SyncSource(NULL) 66 , m_parent( p ) 62 67 , m_xrun_happened( false ) 63 68 , m_activity_wait_timeout_usec( 1000*1000 ) … … 69 74 , m_shutdown_needed(false) 70 75 , m_nbperiods(0) 71 , m_WaitLock( new Util::PosixMutex )76 , m_WaitLock( new Util::PosixMutex("SPMWAIT") ) 72 77 { 73 78 addOption(Util::OptionContainer::Option("slaveMode",false)); … … 81 86 } 82 87 83 void 84 StreamProcessorManager::handleBusReset() 85 { 86 debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset...\n", this); 87 88 // FIXME: we request shutdown for now. 89 m_shutdown_needed=true; 90 91 // note that all receive streams are gone once a device is unplugged 92 93 // synchronize with the wait lock 94 Util::MutexLockHelper lock(*m_WaitLock); 95 96 debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this); 97 // cause all SP's to bail out 98 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 99 it != m_ReceiveProcessors.end(); 100 ++it ) 101 { 102 (*it)->handleBusReset(); 103 } 104 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 105 it != m_TransmitProcessors.end(); 106 ++it ) 107 { 108 (*it)->handleBusReset(); 109 } 110 } 88 // void 89 // StreamProcessorManager::handleBusReset(Ieee1394Service &s) 90 // { 91 // // debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset on service %p...\n", this, &s); 92 // // 93 // // bool handled_at_least_one = false; 94 // // // note that all receive streams are gone once a device is unplugged 95 // // 96 // // // synchronize with the wait lock 97 // // Util::MutexLockHelper lock(*m_WaitLock); 98 // // 99 // // debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this); 100 // // // cause all SP's to bail out 101 // // for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 102 // // it != m_ReceiveProcessors.end(); 103 // // ++it ) 104 // // { 105 // // if(&s == &((*it)->getParent().get1394Service())) { 106 // // debugOutput(DEBUG_LEVEL_NORMAL, 107 // // "issue busreset on receive SPM on channel %d\n", 108 // // (*it)->getChannel()); 109 // // (*it)->handleBusReset(); 110 // // handled_at_least_one = true; 111 // // } else { 112 // // debugOutput(DEBUG_LEVEL_NORMAL, 113 // // "skipping receive SPM on channel %d since not on service %p\n", 114 // // (*it)->getChannel(), &s); 115 // // } 116 // // } 117 // // for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 118 // // it != m_TransmitProcessors.end(); 119 // // ++it ) 120 // // { 121 // // if(&s == &((*it)->getParent().get1394Service())) { 122 // // debugOutput(DEBUG_LEVEL_NORMAL, 123 // // "issue busreset on transmit SPM on channel %d\n", 124 // // (*it)->getChannel()); 125 // // (*it)->handleBusReset(); 126 // // handled_at_least_one = true; 127 // // } else { 128 // // debugOutput(DEBUG_LEVEL_NORMAL, 129 // // "skipping transmit SPM on channel %d since not on service %p\n", 130 // // (*it)->getChannel(), &s); 131 // // } 132 // // } 133 // // 134 // // // FIXME: we request shutdown for now. 135 // // m_shutdown_needed = handled_at_least_one; 136 // } 111 137 112 138 void … … 124 150 int result; 125 151 126 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {127 debugError("clock_gettime failed\n");128 return eAR_Error;129 }130 152 long long int timeout_nsec=0; 131 int timeout_sec = 0;132 153 if (m_activity_wait_timeout_usec >= 0) { 133 154 timeout_nsec = m_activity_wait_timeout_usec * 1000LL; 134 timeout_sec = 0; 135 while(timeout_nsec >= 1000000000LL) {136 timeout_sec += 1;137 timeout_nsec -= 1000000000LL;155 156 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 157 debugError("clock_gettime failed\n"); 158 return eAR_Error; 138 159 } 139 160 ts.tv_nsec += timeout_nsec; 140 ts.tv_sec += timeout_sec; 161 while(ts.tv_nsec >= 1000000000LL) { 162 ts.tv_sec += 1; 163 ts.tv_nsec -= 1000000000LL; 164 } 141 165 } 142 166 … … 158 182 this, result); 159 183 return eAR_Interrupted; 184 } else if (errno == EINVAL) { 185 debugError("(%p) sem_[timed]wait error (result=%d errno=EINVAL)\n", 186 this, result); 187 debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n", 188 this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 189 return eAR_Error; 160 190 } else { 161 191 debugError("(%p) sem_[timed]wait error (result=%d errno=%d)\n", 162 192 this, result, errno); 163 debugError("(%p) timeout_ sec=%d timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n",164 this, timeout_ sec, timeout_nsec, ts.tv_sec, ts.tv_nsec);193 debugError("(%p) timeout_nsec=%lld ts.sec=%d ts.nsec=%lld\n", 194 this, timeout_nsec, ts.tv_sec, ts.tv_nsec); 165 195 return eAR_Error; 166 196 } … … 319 349 return false; 320 350 } 351 352 // set the activity timeout value to two periods worth of usecs. 353 // since we can expect activity once every period, but we might have some 354 // offset, the safe value is two periods. 355 int timeout_usec = 2*1000LL * 1000LL * m_period / m_nominal_framerate; 356 debugOutput(DEBUG_LEVEL_VERBOSE, "setting activity timeout to %d\n", timeout_usec); 357 setActivityWaitTimeoutUsec(timeout_usec); 358 321 359 return true; 322 360 } … … 330 368 it != m_TransmitProcessors.end(); 331 369 ++it ) { 370 if ((*it)->inError()) { 371 debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 372 return false; 373 } 332 374 if (!(*it)->isDryRunning()) { 333 375 if(!(*it)->scheduleStartDryRunning(-1)) { … … 342 384 it != m_ReceiveProcessors.end(); 343 385 ++it ) { 386 if ((*it)->inError()) { 387 debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 388 return false; 389 } 344 390 if (!(*it)->isDryRunning()) { 345 391 if(!(*it)->scheduleStartDryRunning(-1)) { … … 687 733 } else { 688 734 debugOutput(DEBUG_LEVEL_VERBOSE, "Sync start try %d failed...\n", ntries); 735 if(m_shutdown_needed) { 736 debugOutput(DEBUG_LEVEL_VERBOSE, "Some fatal error occurred, stop trying.\n"); 737 return false; 738 } 689 739 } 690 740 } … … 693 743 return false; 694 744 } 695 745 debugOutput( DEBUG_LEVEL_VERBOSE, " Started...\n"); 696 746 return true; 697 747 } … … 730 780 it != m_ReceiveProcessors.end(); 731 781 ++it ) { 732 ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() );782 ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError()); 733 783 } 734 784 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 735 785 it != m_TransmitProcessors.end(); 736 786 ++it ) { 737 ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() );787 ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream() || (*it)->inError()); 738 788 } 739 789 SleepRelativeUsec(125); … … 759 809 it != m_ReceiveProcessors.end(); 760 810 ++it ) { 761 if(!(*it)->scheduleStopDryRunning(-1)) { 811 if ((*it)->inError()) { 812 debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 813 } else if(!(*it)->scheduleStopDryRunning(-1)) { 762 814 debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 763 815 return false; … … 767 819 it != m_TransmitProcessors.end(); 768 820 ++it ) { 769 if(!(*it)->scheduleStopDryRunning(-1)) { 821 if ((*it)->inError()) { 822 debugOutput(DEBUG_LEVEL_VERBOSE, "SP %p in error state\n", *it); 823 } else if(!(*it)->scheduleStopDryRunning(-1)) { 770 824 debugError("%p->scheduleStopDryRunning(-1) failed\n", *it); 771 825 return false; … … 780 834 it != m_ReceiveProcessors.end(); 781 835 ++it ) { 782 ready &= ( *it)->isStopped();836 ready &= ((*it)->isStopped() || (*it)->inError()); 783 837 } 784 838 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 785 839 it != m_TransmitProcessors.end(); 786 840 ++it ) { 787 ready &= ( *it)->isStopped();841 ready &= ((*it)->isStopped() || (*it)->inError()); 788 842 } 789 843 SleepRelativeUsec(125); … … 804 858 return false; 805 859 } 860 debugOutput( DEBUG_LEVEL_VERBOSE, " Stopped...\n"); 806 861 return true; 807 862 } … … 874 929 if(m_shutdown_needed) return false; 875 930 bool xrun_occurred = false; 931 bool in_error = false; 876 932 bool period_not_ready = true; 877 933 … … 889 945 case eAR_Error: 890 946 debugError("Error while waiting for activity\n"); 947 m_shutdown_needed = true; 891 948 return false; 892 949 case eAR_Interrupted: … … 895 952 break; 896 953 case eAR_Timeout: 897 // FIXME: what to do here?898 954 debugWarning("Timeout while waiting for activity\n"); 899 break; 955 // ignore this since it can also be due to some other hardware 956 // or high-prio software that preempts us. hence only an xrun should 957 // be generated (if necessary) 900 958 case eAR_Activity: 901 959 // do nothing … … 924 982 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, " period not ready? %d...\n", period_not_ready); 925 983 926 // check for underruns on the ISO side,984 // check for underruns/errors on the ISO side, 927 985 // those should make us bail out of the wait loop 928 986 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); … … 931 989 // a xrun has occurred on the Iso side 932 990 xrun_occurred |= (*it)->xrunOccurred(); 991 in_error |= (*it)->inError(); 933 992 } 934 993 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); … … 937 996 // a xrun has occurred on the Iso side 938 997 xrun_occurred |= (*it)->xrunOccurred(); 939 } 940 if(xrun_occurred) break; 941 // FIXME: make sure we also exit this loop when something else happens (e.g. signal, iso error) 942 943 // if we have to shutdown due to some async event (busreset), do so 944 if(m_shutdown_needed) break; 998 in_error |= (*it)->inError(); 999 } 1000 if(xrun_occurred | in_error | m_shutdown_needed) break; 945 1001 } 946 1002 947 1003 if(xrun_occurred) { 948 1004 debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to xrun...\n"); 1005 } 1006 if(in_error) { 1007 debugOutput( DEBUG_LEVEL_VERBOSE, "exit due to error...\n"); 1008 m_shutdown_needed = true; 949 1009 } 950 1010 … … 1204 1264 1205 1265 void StreamProcessorManager::setVerboseLevel(int l) { 1206 setDebugLevel(l);1207 1266 if(m_WaitLock) m_WaitLock->setVerboseLevel(l); 1208 1267 1209 debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n");1210 1268 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 1211 1269 it != m_ReceiveProcessors.end(); … … 1213 1271 (*it)->setVerboseLevel(l); 1214 1272 } 1215 1216 debugOutput( DEBUG_LEVEL_VERBOSE, " Transmit processors...\n");1217 1273 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 1218 1274 it != m_TransmitProcessors.end(); … … 1220 1276 (*it)->setVerboseLevel(l); 1221 1277 } 1222 } 1223 1278 setDebugLevel(l); 1279 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 1280 } 1224 1281 1225 1282 int StreamProcessorManager::getPortCount(enum Port::E_PortType type, enum Port::E_Direction direction) { … … 1262 1319 1263 1320 // TODO: implement a port map here, instead of the loop 1264 1265 1321 Port* StreamProcessorManager::getPortByIndex(int idx, enum Port::E_Direction direction) { 1266 1322 int count=0; trunk/libffado/src/libstreaming/StreamProcessorManager.h
r1045 r1336 36 36 #include <semaphore.h> 37 37 38 class DeviceManager; 39 38 40 namespace Streaming { 39 41 … … 56 58 }; 57 59 58 StreamProcessorManager(); 59 StreamProcessorManager(unsigned int period, unsigned int rate, unsigned int nb_buffers); 60 StreamProcessorManager(DeviceManager &parent); 61 StreamProcessorManager(DeviceManager &parent, unsigned int period, 62 unsigned int rate, unsigned int nb_buffers); 60 63 virtual ~StreamProcessorManager(); 61 62 void handleBusReset();63 64 64 65 bool prepare(); ///< to be called after the processors are registered … … 95 96 void setNbBuffers(unsigned int nb_buffers) 96 97 {m_nb_buffers = nb_buffers;}; 97 int getNbBuffers()98 unsigned int getNbBuffers() 98 99 {return m_nb_buffers;}; 100 101 // this is the amount of usecs we wait before an activity 102 // timeout occurs. 103 void setActivityWaitTimeoutUsec(int usec) 104 {m_activity_wait_timeout_usec = usec;}; 105 int getActivityWaitTimeoutUsec() 106 {return m_activity_wait_timeout_usec;}; 99 107 100 108 int getPortCount(enum Port::E_PortType, enum Port::E_Direction); … … 106 114 bool transfer(); 107 115 bool transfer(enum StreamProcessor::eProcessorType); 116 117 // for bus reset handling 118 void lockWaitLoop() {m_WaitLock->Lock();}; 119 void unlockWaitLoop() {m_WaitLock->Unlock();}; 120 108 121 private: 109 122 bool transferSilence(); … … 150 163 protected: // FIXME: private? 151 164 165 // parent device manager 166 DeviceManager &m_parent; 167 152 168 // thread related vars 153 169 bool m_xrun_happened; trunk/libffado/src/libutil/PosixMutex.cpp
r1211 r1336 49 49 PosixMutex::PosixMutex() 50 50 { 51 m_id = "?"; 51 52 pthread_mutexattr_t attr; 52 53 pthread_mutexattr_init(&attr); … … 64 65 } 65 66 67 PosixMutex::PosixMutex(std::string id) 68 { 69 m_id = id; 70 pthread_mutexattr_t attr; 71 pthread_mutexattr_init(&attr); 72 #ifdef DEBUG 73 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 74 #else 75 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 76 #endif 77 pthread_mutex_init(&m_mutex, &attr); 78 pthread_mutexattr_destroy(&attr); 79 80 #if DEBUG_LOCK_COLLISION_TRACING 81 m_locked_by = NULL; 82 #endif 83 } 84 66 85 PosixMutex::~PosixMutex() 67 86 { … … 73 92 { 74 93 int err; 75 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(% p) lock\n", this);94 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock\n", m_id.c_str(), this); 76 95 #if DEBUG_LOCK_COLLISION_TRACING 77 96 if(TryLock()) { … … 84 103 85 104 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 86 "(% p) %s obtained lock\n",87 this, name);105 "(%s, %p) %s obtained lock\n", 106 m_id.c_str(), this, name); 88 107 return; 89 108 } else { … … 97 116 debugGetFunctionNameFromAddr(m_locked_by, name2, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 98 117 99 debugWarning("(% p) lock collision: %s wants lock, %s has lock\n",100 this, name1, name2);118 debugWarning("(%s, %p) lock collision: %s wants lock, %s has lock\n", 119 m_id.c_str(), this, name1, name2); 101 120 if((err = pthread_mutex_lock(&m_mutex))) { 102 121 if (err == EDEADLK) { 103 debugError(" Resource deadlock detected\n");122 debugError("(%s, %p) Resource deadlock detected\n", m_id.c_str(), this); 104 123 debugPrintBacktrace(10); 105 124 } else { 106 debugError(" Error locking the mutex: %d\n", err);125 debugError("(%s, %p) Error locking the mutex: %d\n", m_id.c_str(), this, err); 107 126 } 108 127 } else { 109 debugWarning("(% p) lock collision: %s got lock (from %s?)\n",110 this, name1, name2);128 debugWarning("(%s, %p) lock collision: %s got lock (from %s?)\n", 129 m_id.c_str(), this, name1, name2); 111 130 } 112 131 } … … 115 134 if((err = pthread_mutex_lock(&m_mutex))) { 116 135 if (err == EDEADLK) { 117 debugError(" Resource deadlock detected\n");136 debugError("(%s, %p) Resource deadlock detected\n", m_id.c_str(), this); 118 137 debugPrintBacktrace(10); 119 138 } else { 120 debugError(" Error locking the mutex: %d\n", err);139 debugError("(%s, %p) Error locking the mutex: %d\n", m_id.c_str(), this, err); 121 140 } 122 141 } … … 130 149 PosixMutex::TryLock() 131 150 { 132 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(% p) trying to lock\n", this);151 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) trying to lock\n", m_id.c_str(), this); 133 152 return pthread_mutex_trylock(&m_mutex) == 0; 134 153 } … … 137 156 PosixMutex::isLocked() 138 157 { 139 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(% p) checking lock\n", this);140 int res =pthread_mutex_trylock(&m_mutex);158 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) checking lock\n", m_id.c_str(), this); 159 int res = pthread_mutex_trylock(&m_mutex); 141 160 if(res == 0) { 142 161 pthread_mutex_unlock(&m_mutex); 143 162 return false; 144 163 } else { 145 if(res != EBUSY) { 146 debugError("Bogus error code: %d\n", res); 164 if (res == EDEADLK) { 165 // this means that the current thread already has the lock, 166 // iow it's locked. 167 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock taken by current thread\n", m_id.c_str(), this); 168 } else if(res == EBUSY) { 169 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) lock taken\n", m_id.c_str(), this); 170 } else { 171 debugError("(%s, %p) Bogus error code: %d\n", m_id.c_str(), this, res); 147 172 } 148 173 return true; … … 153 178 PosixMutex::Unlock() 154 179 { 155 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(% p) unlock\n", this);180 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "(%s, %p) unlock\n", m_id.c_str(), this); 156 181 #if DEBUG_LOCK_COLLISION_TRACING 157 182 // unlocking … … 162 187 debugGetFunctionNameFromAddr(unlocker, name, DEBUG_LOCK_COLLISION_TRACING_NAME_MAXLEN); 163 188 debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 164 "(% p)%s releases lock\n",165 this, name);189 "(%s, %p) %s releases lock\n", 190 m_id.c_str(), this, name); 166 191 #endif 167 192 … … 169 194 int err; 170 195 if((err = pthread_mutex_unlock(&m_mutex))) { 171 debugError(" Error unlocking the mutex: %d\n", err);196 debugError("(%s, %p) Error unlocking the mutex: %d\n", m_id.c_str(), this, err); 172 197 } 173 198 #else … … 179 204 PosixMutex::show() 180 205 { 181 debugOutput(DEBUG_LEVEL_NORMAL, "(% p) mutex (%s)\n", this, (isLocked() ? "Locked" : "Unlocked"));206 debugOutput(DEBUG_LEVEL_NORMAL, "(%s, %p) mutex (%s)\n", m_id.c_str(), this, (isLocked() ? "Locked" : "Unlocked")); 182 207 } 183 208 trunk/libffado/src/libutil/PosixMutex.h
r1254 r1336 29 29 #include "Mutex.h" 30 30 #include <pthread.h> 31 #include <string> 31 32 32 33 #include "debugmodule/debugmodule.h" … … 43 44 public: 44 45 PosixMutex(); 46 PosixMutex(std::string id); 45 47 virtual ~PosixMutex(); 46 48 … … 60 62 pthread_mutex_t m_mutex; 61 63 64 std::string m_id; 65 62 66 #if DEBUG_LOCK_COLLISION_TRACING 63 67 void *m_locked_by; trunk/libffado/src/libutil/PosixThread.cpp
r1096 r1336 74 74 } 75 75 76 debugOutput( DEBUG_LEVEL_VERBOSE, " ThreadHandler: start %p\n", obj);76 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: start %p\n", obj->m_id.c_str(), obj); 77 77 78 78 // If Init succeed start the thread loop 79 79 bool res = true; 80 80 while (obj->fRunning && res) { 81 debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, " ThreadHandler: run %p\n", obj);81 debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "(%s) ThreadHandler: run %p\n", obj->m_id.c_str(), obj); 82 82 res = runnable->Execute(); 83 83 pthread_testcancel(); 84 84 } 85 85 86 debugOutput( DEBUG_LEVEL_VERBOSE, " ThreadHandler: exit %p\n", obj);86 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) ThreadHandler: exit %p\n", obj->m_id.c_str(), obj); 87 87 return 0; 88 88 } … … 95 95 if (fRealTime) { 96 96 97 debugOutput( DEBUG_LEVEL_VERBOSE, " Create RT thread %p with priority %d\n", this, fPriority);97 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create RT thread %p with priority %d\n", m_id.c_str(), this, fPriority); 98 98 99 99 /* Get the client thread to run as an RT-FIFO … … 139 139 return 0; 140 140 } else { 141 debugOutput( DEBUG_LEVEL_VERBOSE, " Create non RT thread %p\n", this);141 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Create non RT thread %p\n", m_id.c_str(), this); 142 142 143 143 if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) { … … 153 153 { 154 154 if (fThread) { // If thread has been started 155 debugOutput( DEBUG_LEVEL_VERBOSE, " PosixThread::Kill %p (thread: %p)\n", this, fThread);155 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Kill %p (thread: %p)\n", m_id.c_str(), this, fThread); 156 156 void* status; 157 157 pthread_cancel(fThread); 158 158 pthread_join(fThread, &status); 159 debugOutput( DEBUG_LEVEL_VERBOSE, " PosixThread::Killed %p (thread: %p)\n", this, fThread);159 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Killed %p (thread: %p)\n", m_id.c_str(), this, fThread); 160 160 return 0; 161 161 } else { … … 167 167 { 168 168 if (fThread) { // If thread has been started 169 debugOutput( DEBUG_LEVEL_VERBOSE, " PosixThread::Stop %p (thread: %p)\n", this, fThread);169 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stop %p (thread: %p)\n", m_id.c_str(), this, fThread); 170 170 void* status; 171 171 fRunning = false; // Request for the thread to stop 172 172 pthread_join(fThread, &status); 173 debugOutput( DEBUG_LEVEL_VERBOSE, " PosixThread::Stopped %p (thread: %p)\n", this, fThread);173 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Stopped %p (thread: %p)\n", m_id.c_str(), this, fThread); 174 174 return 0; 175 175 } else { … … 182 182 struct sched_param rtparam; 183 183 int res; 184 debugOutput( DEBUG_LEVEL_VERBOSE, "(% p) Aquire realtime, prio %d\n", this, fPriority);184 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Aquire realtime, prio %d\n", m_id.c_str(), this, fPriority); 185 185 186 186 if (!fThread) … … 211 211 struct sched_param rtparam; 212 212 int res; 213 debugOutput( DEBUG_LEVEL_VERBOSE, "(% p) Drop realtime\n", this);213 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s, %p) Drop realtime\n", m_id.c_str(), this); 214 214 215 215 if (!fThread) trunk/libffado/src/libutil/PosixThread.h
r864 r1336 87 87 {} 88 88 89 PosixThread(RunnableInterface* runnable, std::string id, bool real_time, int priority, int cancellation) 90 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(priority), fRealTime(real_time), fRunning(false), fCancellation(cancellation) 91 {} 92 PosixThread(RunnableInterface* runnable, std::string id) 93 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(PTHREAD_CANCEL_DEFERRED) 94 {} 95 PosixThread(RunnableInterface* runnable, std::string id, int cancellation) 96 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(cancellation) 97 {} 98 89 99 virtual ~PosixThread() 90 100 {} trunk/libffado/src/libutil/Thread.h
r1144 r1336 56 56 #include "Atomic.h" 57 57 #include <pthread.h> 58 #include <string> 58 59 59 60 namespace Util … … 94 95 public: 95 96 96 Thread(RunnableInterface* runnable): fRunnable(runnable) 97 Thread(RunnableInterface* runnable) 98 : fRunnable(runnable) 99 , m_id( "UNKNOWN" ) 100 {} 101 Thread(RunnableInterface* runnable, std::string id) 102 : fRunnable(runnable) 103 , m_id( id ) 97 104 {} 98 105 virtual ~Thread() … … 113 120 114 121 virtual void setVerboseLevel(int l) 115 {setDebugLevel(l);}; 122 { 123 setDebugLevel(l); 124 debugOutput( DEBUG_LEVEL_VERBOSE, "(%s) Setting verbose level to %d...\n", m_id.c_str(), l ); 125 }; 116 126 protected: 117 DECLARE_DEBUG_MODULE; 127 std::string m_id; 128 DECLARE_DEBUG_MODULE; 118 129 119 130 }; trunk/libffado/src/libutil/TimestampedBuffer.cpp
r1234 r1336 166 166 167 167 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 168 "for (%p) to "TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC","168 "for (%p) " 169 169 "NTS="TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 170 this, new_timestamp, ts,m_buffer_next_tail_timestamp, m_dll_e2, getRate());170 this, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 171 171 } 172 172 … … 289 289 * 290 290 * Resets the TimestampedBuffer, clearing the buffers and counters. 291 * (not true yet: Also resets the DLL to the nominal values.)291 * Also resets the DLL to the nominal values. 292 292 * 293 293 * \note when this is called, you should make sure that the buffer … … 300 300 ffado_ringbuffer_reset(m_event_buffer); 301 301 resetFrameCounter(); 302 303 m_current_rate = m_nominal_rate; 304 m_dll_e2=m_nominal_rate * (float)m_update_period; 305 // this will init the internal timestamps to a sensible value 306 setBufferTailTimestamp(m_buffer_tail_timestamp); 307 302 308 return true; 303 309 } trunk/libffado/src/libutil/TimestampedBuffer.h
r1001 r1336 25 25 #define __FFADO_TIMESTAMPEDBUFFER__ 26 26 27 #include " ../debugmodule/debugmodule.h"27 #include "debugmodule/debugmodule.h" 28 28 #include "libutil/ringbuffer.h" 29 29 #include <pthread.h> trunk/libffado/src/libutil/Watchdog.cpp
r1165 r1336 205 205 return false; 206 206 } 207 m_HartbeatThread = new Util::PosixThread(m_HartbeatTask, false,207 m_HartbeatThread = new Util::PosixThread(m_HartbeatTask, "WDGHBT", false, 208 208 0, PTHREAD_CANCEL_ASYNCHRONOUS); 209 209 if(!m_HartbeatThread) { … … 221 221 return false; 222 222 } 223 m_CheckThread = new Util::PosixThread(m_CheckTask, false,223 m_CheckThread = new Util::PosixThread(m_CheckTask,"WDGCHK", false, 224 224 0, PTHREAD_CANCEL_ASYNCHRONOUS); 225 225 if(!m_CheckThread) { trunk/libffado/src/metrichalo/mh_avdevice.cpp
r1239 r1336 126 126 } 127 127 128 std::vector<int> 129 MHAvDevice::getSupportedSamplingFrequencies() 130 { 131 std::vector<int> frequencies; 132 return frequencies; 133 } 134 128 135 FFADODevice::ClockSourceVector 129 136 MHAvDevice::getSupportedClockSources() { trunk/libffado/src/metrichalo/mh_avdevice.h
r1239 r1336 61 61 virtual bool setSamplingFrequency( int ); 62 62 virtual int getSamplingFrequency( ); 63 virtual std::vector<int> getSupportedSamplingFrequencies(); 63 64 64 65 virtual ClockSourceVector getSupportedClockSources(); trunk/libffado/src/motu/motu_avdevice.cpp
r1274 r1336 38 38 #include "libutil/DelayLockedLoop.h" 39 39 #include "libutil/Time.h" 40 #include "libutil/Configuration.h" 40 41 41 42 #include "libcontrol/BasicElements.h" … … 302 303 }; 303 304 304 const MixerCtrl MixerCtrls_828Mk2[] = { 305 const MatrixMixBus MixerBuses_Ultralite[] = { 306 {"Mix 1", 0x4000, }, 307 {"Mix 2", 0x4100, }, 308 {"Mix 3", 0x4200, }, 309 {"Mix 4", 0x4300, }, 310 }; 311 312 const MatrixMixChannel MixerChannels_Ultralite[] = { 313 {"Analog 1", MOTU_CTRL_STD_CHANNEL, 0x0000, }, 314 {"Analog 2", MOTU_CTRL_STD_CHANNEL, 0x0004, }, 315 {"Analog 3", MOTU_CTRL_STD_CHANNEL, 0x0008, }, 316 {"Analog 4", MOTU_CTRL_STD_CHANNEL, 0x000c, }, 317 {"Analog 5", MOTU_CTRL_STD_CHANNEL, 0x0010, }, 318 {"Analog 6", MOTU_CTRL_STD_CHANNEL, 0x0014, }, 319 {"Analog 7", MOTU_CTRL_STD_CHANNEL, 0x0018, }, 320 {"Analog 8", MOTU_CTRL_STD_CHANNEL, 0x001c, }, 321 {"SPDIF 1", MOTU_CTRL_STD_CHANNEL, 0x0020, }, 322 {"SPDIF 2", MOTU_CTRL_STD_CHANNEL, 0x0024, }, 323 }; 324 325 const MixerCtrl MixerCtrls_Ultralite[] = { 305 326 {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 306 327 {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, … … 326 347 }; 327 348 349 const MixerCtrl MixerCtrls_896HD[] = { 350 {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 351 {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 352 {"Mix3/Mix_", "Mix 3 ", "", MOTU_CTRL_STD_MIX, 0x0c28, }, 353 {"Mix4/Mix_", "Mix 4 ", "", MOTU_CTRL_STD_MIX, 0x0c2c, }, 354 355 /* For phones source control, "register" is currently unused */ 356 {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0}, 357 358 /* For optical mode controls, the "register" is used to indicate direction */ 359 {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 360 {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 361 362 /* For meter controls the "register" indicates which meter controls are available */ 363 {"Control/Meter_", "Meter ", "", MOTU_CTRL_METER, 364 MOTU_CTRL_METER_PEAKHOLD | MOTU_CTRL_METER_CLIPHOLD | MOTU_CTRL_METER_AESEBU_SRC | 365 MOTU_CTRL_METER_PROG_SRC}, 366 }; 367 368 const MixerCtrl MixerCtrls_828Mk2[] = { 369 {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 370 {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 371 {"Mix3/Mix_", "Mix 3 ", "", MOTU_CTRL_STD_MIX, 0x0c28, }, 372 {"Mix4/Mix_", "Mix 4 ", "", MOTU_CTRL_STD_MIX, 0x0c2c, }, 373 374 /* For mic/line input controls, the "register" is the zero-based channel number */ 375 {"Control/Ana1_", "Analog 1 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 0}, 376 {"Control/Ana2_", "Analog 2 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 1}, 377 {"Control/Ana3_", "Analog 3 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 2}, 378 {"Control/Ana4_", "Analog 4 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 3}, 379 {"Control/Ana5_", "Analog 5 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 4}, 380 {"Control/Ana6_", "Analog 6 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 5}, 381 {"Control/Ana7_", "Analog 7 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 6}, 382 {"Control/Ana8_", "Analog 8 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 7}, 383 384 /* For phones source control, "register" is currently unused */ 385 {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0}, 386 387 /* For optical mode controls, the "register" is used to indicate direction */ 388 {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 389 {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 390 }; 391 328 392 const MotuMixer Mixer_Traveler = MOTUMIXER( 329 393 MixerCtrls_Traveler, MixerBuses_Traveler, MixerChannels_Traveler); 330 394 395 const MotuMixer Mixer_Ultralite = MOTUMIXER( 396 MixerCtrls_Ultralite, MixerBuses_Ultralite, MixerChannels_Ultralite); 397 331 398 const MotuMixer Mixer_828Mk2 = MOTUMIXER( 332 399 MixerCtrls_828Mk2, MixerBuses_Traveler, MixerChannels_Traveler); 333 400 334 // For convenience during initial testing, just make the 896HD use the 335 // Traveler's mixer definition. Separate definitions for these models will 336 // come once the final mixer structure is in place. For now it's in a state 337 // of flux and subject to significant change. 338 #define Mixer_896HD Mixer_Traveler 401 const MotuMixer Mixer_896HD = MOTUMIXER( 402 MixerCtrls_896HD, MixerBuses_Traveler, MixerChannels_Traveler); 339 403 340 404 /* The order of DevicesProperty entries must match the numeric order of the … … 345 409 { Ports_828MKII, N_ELEMENTS( Ports_828MKII ), 96000, &Mixer_828Mk2, }, 346 410 { Ports_TRAVELER, N_ELEMENTS( Ports_TRAVELER ), 192000, &Mixer_Traveler, }, 347 { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ), 96000 },411 { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ), 96000, &Mixer_Ultralite, }, 348 412 { Ports_8PRE, N_ELEMENTS( Ports_8PRE ), 96000 }, 349 413 { Ports_828MKI, N_ELEMENTS( Ports_828MKI ), 48000 }, … … 549 613 type &= ~MOTU_CTRL_OPTICAL_MODE; 550 614 } 615 if (type & MOTU_CTRL_METER) { 616 if (ctrl->dev_register & MOTU_CTRL_METER_PEAKHOLD) { 617 snprintf(name, 100, "%s%s", ctrl->name, "peakhold_time"); 618 snprintf(label,100, "%s%s", ctrl->label,"peakhold time"); 619 result &= m_MixerContainer->addElement( 620 new MeterControl(*this, MOTU_METER_PEAKHOLD_MASK, 621 MOTU_METER_PEAKHOLD_SHIFT, name, label, ctrl->desc)); 622 } 623 if (ctrl->dev_register & MOTU_CTRL_METER_CLIPHOLD) { 624 snprintf(name, 100, "%s%s", ctrl->name, "cliphold_time"); 625 snprintf(label,100, "%s%s", ctrl->label,"cliphold time"); 626 result &= m_MixerContainer->addElement( 627 new MeterControl(*this, MOTU_METER_CLIPHOLD_MASK, 628 MOTU_METER_CLIPHOLD_SHIFT, name, label, ctrl->desc)); 629 } 630 if (ctrl->dev_register & MOTU_CTRL_METER_AESEBU_SRC) { 631 snprintf(name, 100, "%s%s", ctrl->name, "aesebu_src"); 632 snprintf(label,100, "%s%s", ctrl->label,"AESEBU source"); 633 result &= m_MixerContainer->addElement( 634 new MeterControl(*this, MOTU_METER_AESEBU_SRC_MASK, 635 MOTU_METER_AESEBU_SRC_SHIFT, name, label, ctrl->desc)); 636 } 637 if (ctrl->dev_register & MOTU_CTRL_METER_PROG_SRC) { 638 snprintf(name, 100, "%s%s", ctrl->name, "src"); 639 snprintf(label,100, "%s%s", ctrl->label,"source"); 640 result &= m_MixerContainer->addElement( 641 new MeterControl(*this, MOTU_METER_PROG_SRC_MASK, 642 MOTU_METER_PROG_SRC_SHIFT, name, label, ctrl->desc)); 643 } 644 type &= ~MOTU_CTRL_METER; 645 } 551 646 552 647 if (type) { … … 645 740 646 741 bool 647 MotuDevice::probe( ConfigRom& configRom, bool generic)742 MotuDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic) 648 743 { 649 744 if(generic) return false; … … 883 978 } 884 979 980 std::vector<int> 981 MotuDevice::getSupportedSamplingFrequencies() 982 { 983 std::vector<int> frequencies; 984 signed int max_freq = DevicesProperty[m_motu_model-1].MaxSampleRate; 985 986 /* All MOTUs support 1x rates. All others must be conditional. */ 987 frequencies.push_back(44100); 988 frequencies.push_back(48000); 989 990 if (88200 <= max_freq) 991 frequencies.push_back(88200); 992 if (96000 <= max_freq) 993 frequencies.push_back(96000); 994 if (176400 <= max_freq) 995 frequencies.push_back(176400); 996 if (192000 <= max_freq) 997 frequencies.push_back(192000); 998 return frequencies; 999 } 1000 885 1001 FFADODevice::ClockSource 886 1002 MotuDevice::clockIdToClockSource(unsigned int id) { … … 1007 1123 1008 1124 debugOutput(DEBUG_LEVEL_NORMAL, "Preparing MotuDevice...\n" ); 1125 1126 // Explicitly set the optical mode, primarily to ensure that the 1127 // MOTU_REG_OPTICAL_CTRL register is initialised. We need to do this to 1128 // because some interfaces (the Ultralite for example) appear to power 1129 // up without this set to anything sensible. In this case, writes to 1130 // MOTU_REG_ISOCTRL fail more often than not, which is bad. 1131 setOpticalMode(MOTU_DIR_IN, optical_in_mode); 1132 setOpticalMode(MOTU_DIR_OUT, optical_out_mode); 1009 1133 1010 1134 // Allocate bandwidth if not previously done. … … 1075 1199 std::string id=std::string("dev?"); 1076 1200 if(!getOption("id", id)) { 1077 debugWarning("Could not retrieve id parameter, defaul ing to 'dev?'\n");1201 debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n"); 1078 1202 } 1079 1203 … … 1310 1434 opt_ctrl |= 0x00000040; 1311 1435 1312 if ( mode& MOTU_DIR_IN) {1436 if (dir & MOTU_DIR_IN) { 1313 1437 reg &= ~MOTU_OPTICAL_IN_MODE_MASK; 1314 1438 reg |= (mode << 8) & MOTU_OPTICAL_IN_MODE_MASK; … … 1318 1442 opt_ctrl &= ~0x00000080; 1319 1443 } 1320 if ( mode& MOTU_DIR_OUT) {1444 if (dir & MOTU_DIR_OUT) { 1321 1445 reg &= ~MOTU_OPTICAL_OUT_MODE_MASK; 1322 1446 reg |= (mode <<10) & MOTU_OPTICAL_OUT_MODE_MASK; trunk/libffado/src/motu/motu_avdevice.h
r1265 r1336 68 68 #define MOTU_DIR_INOUT (MOTU_DIR_IN | MOTU_DIR_OUT) 69 69 70 #define MOTU_METER_PEAKHOLD_MASK 0x3800 71 #define MOTU_METER_PEAKHOLD_SHIFT 11 72 #define MOTU_METER_CLIPHOLD_MASK 0x0700 73 #define MOTU_METER_CLIPHOLD_SHIFT 8 74 #define MOTU_METER_AESEBU_SRC_MASK 0x0004 75 #define MOTU_METER_AESEBU_SRC_SHIFT 2 76 #define MOTU_METER_PROG_SRC_MASK 0x0003 77 #define MOTU_METER_PROG_SRC_SHIFT 0 78 70 79 /* Device registers */ 71 80 #define MOTU_REG_ISOCTRL 0x0b00 72 81 #define MOTU_REG_OPTICAL_CTRL 0x0b10 73 82 #define MOTU_REG_CLK_CTRL 0x0b14 83 #define MOTU_REG_896HD_METER_REG 0x0b1c 84 #define MOTU_REG_896HD_METER_CONF 0x0b24 74 85 #define MOTU_REG_ROUTE_PORT_CONF 0x0c04 75 86 #define MOTU_REG_INPUT_LEVEL 0x0c08 … … 95 106 class Ieee1394Service; 96 107 108 namespace Util { 109 class Configuration; 110 } 111 97 112 namespace Motu { 98 113 … … 174 189 virtual bool destroyMixer(); 175 190 176 static bool probe( ConfigRom& configRom, bool generic = false );191 static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false ); 177 192 static FFADODevice * createDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom )); 178 193 static int getConfigurationId( ); … … 184 199 virtual bool setSamplingFrequency( int samplingFrequency ); 185 200 virtual int getSamplingFrequency( ); 201 virtual std::vector<int> getSupportedSamplingFrequencies(); 186 202 187 203 FFADODevice::ClockSource clockIdToClockSource(unsigned int id); trunk/libffado/src/motu/motu_controls.cpp
r1274 r1336 727 727 } 728 728 729 MeterControl::MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift) 730 : MotuDiscreteCtrl(parent, ctrl_mask) 731 { 732 m_shift = ctrl_shift; 733 validate(); 734 } 735 736 MeterControl::MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift, 737 std::string name, std::string label, std::string descr) 738 : MotuDiscreteCtrl(parent, ctrl_mask, name, label, descr) 739 { 740 m_shift = ctrl_shift; 741 validate(); 742 } 743 744 void MeterControl::validate(void) { 745 if (m_register & (1<< m_shift) == 0) { 746 debugOutput(DEBUG_LEVEL_VERBOSE, "Inconsistent mask/shift: 0x%08x/%d\n", m_register, m_shift); 747 } 748 } 749 750 bool 751 MeterControl::setValue(int v) 752 { 753 unsigned int val; 754 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for meter control 0x%08x/%d: %d\n", 755 m_register, m_shift, v); 756 757 // Need to get current register setting so we can preserve the parts not 758 // being controlled by this object. m_register holds the mask for the 759 // parts we're changing. 760 val = m_parent.ReadRegister(MOTU_REG_896HD_METER_CONF) & ~m_register; 761 val |= (v << m_shift) & m_register; 762 763 m_parent.WriteRegister(MOTU_REG_896HD_METER_CONF, val); 764 765 // Drivers under other OSes set MOTU_REG_896HD_METER_REG (0x0b1c) to 766 // 0x0400 whenever MOTU_REG_896HD_METER_CONF (0x0b24) is changed. 767 // There's no obvious reason why they do this, but since it's no hassle 768 // we might as well do the same. 769 m_parent.WriteRegister(MOTU_REG_896HD_METER_REG, 0x0400); 770 771 return true; 772 } 773 774 int 775 MeterControl::getValue() 776 { 777 unsigned int val; 778 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for meter control 0x%08x/%d\n", 779 m_register, m_shift); 780 781 // m_register holds the mask of the part of interest 782 val = (m_parent.ReadRegister(MOTU_REG_896HD_METER_CONF) & m_register) >> m_shift; 783 784 return val; 785 } 786 729 787 InfoElement::InfoElement(MotuDevice &parent, unsigned infotype) 730 788 : MotuDiscreteCtrl(parent, infotype) trunk/libffado/src/motu/motu_controls.h
r1274 r1336 41 41 #define MOTU_CTRL_MIX_DEST 0x00000400 42 42 43 #define MOTU_CTRL_METER 0x00001000 44 43 45 #define MOTU_CTRL_INPUT_TRIMGAIN 0x01000000 44 46 #define MOTU_CTRL_INPUT_PAD 0x02000000 … … 73 75 #define MOTU_CTRL_MODE_PAD 0x00000000 74 76 #define MOTU_CTRL_MODE_TRIMGAIN 0x00000001 77 78 #define MOTU_CTRL_METER_PEAKHOLD 0x00000000 79 #define MOTU_CTRL_METER_CLIPHOLD 0x00000001 80 #define MOTU_CTRL_METER_AESEBU_SRC 0x00000002 81 #define MOTU_CTRL_METER_PROG_SRC 0x00000004 75 82 76 83 #define MOTU_INFO_MODEL 0x00000001 … … 293 300 }; 294 301 302 class MeterControl 303 : public MotuDiscreteCtrl 304 { 305 public: 306 MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift); 307 MeterControl(MotuDevice &parent, unsigned int ctrl_mask, unsigned int ctrl_shift, 308 std::string name, std::string label, std::string descr); 309 310 virtual bool setValue(int v); 311 virtual int getValue(); 312 protected: 313 void validate(); 314 unsigned int m_shift; 315 }; 316 295 317 class InfoElement 296 318 : public MotuDiscreteCtrl trunk/libffado/src/rme/rme_avdevice.cpp
r1239 r1336 177 177 } 178 178 179 #define RME_CHECK_AND_ADD_SR(v, x) \ 180 { \ 181 if (((x >= 32000*0.96 && x <= 32000*1.04) || \ 182 (x >= 44100*0.96 && x <= 44100*1.04) || \ 183 (x >= 48000*0.96 && x <= 48000*1.04) || \ 184 (x >= 64000*0.96 && x <= 64000*1.04) || \ 185 (x >= 88200*0.96 && x <= 88200*1.04) || \ 186 (x >= 96000*0.96 && x <= 96000*1.04) || \ 187 (x >= 128000*0.96 && x <= 128000*1.04) || \ 188 (x >= 176000*0.96 && x <= 176000*1.04) || \ 189 (x >= 192000*0.96 && x <= 192000*1.04))) { \ 190 v.push_back(x); \ 191 };}; 192 193 std::vector<int> 194 RmeDevice::getSupportedSamplingFrequencies() 195 { 196 std::vector<int> frequencies; 197 RME_CHECK_AND_ADD_SR(frequencies, 32000); 198 RME_CHECK_AND_ADD_SR(frequencies, 44100); 199 RME_CHECK_AND_ADD_SR(frequencies, 48000); 200 RME_CHECK_AND_ADD_SR(frequencies, 64000); 201 RME_CHECK_AND_ADD_SR(frequencies, 88200); 202 RME_CHECK_AND_ADD_SR(frequencies, 96000); 203 RME_CHECK_AND_ADD_SR(frequencies, 128000); 204 RME_CHECK_AND_ADD_SR(frequencies, 176400); 205 RME_CHECK_AND_ADD_SR(frequencies, 192000); 206 return frequencies; 207 } 208 179 209 FFADODevice::ClockSourceVector 180 210 RmeDevice::getSupportedClockSources() { trunk/libffado/src/rme/rme_avdevice.h
r1239 r1336 76 76 virtual bool setSamplingFrequency( int samplingFrequency ); 77 77 virtual int getSamplingFrequency( ); 78 virtual std::vector<int> getSupportedSamplingFrequencies(); 78 79 79 80 virtual ClockSourceVector getSupportedClockSources(); trunk/libffado/src/SConscript
r1210 r1336 75 75 libutil/IpcRingBuffer.cpp \ 76 76 libutil/PacketBuffer.cpp \ 77 libutil/Configuration.cpp \ 77 78 libutil/OptionContainer.cpp \ 78 79 libutil/PosixMessageQueue.cpp \ … … 124 125 maudio/fw410.xml \ 125 126 maudio/fwap.xml \ 126 bebob/ffado_driver_bebob.txt \127 127 ' ) 128 128 129 129 genericavc_source = env.Split( '\ 130 130 genericavc/avc_avdevice.cpp \ 131 genericavc/avc_vendormodel.cpp \132 131 ' ) 133 132 134 133 genericavc_pkgdata = env.Split( '\ 135 genericavc/ffado_driver_genericavc.txt \136 134 ' ) 137 135 … … 148 146 fireworks/efc/efc_cmds_monitor.cpp \ 149 147 fireworks/efc/efc_cmds_ioconfig.cpp \ 148 fireworks/fireworks_session_block.cpp \ 150 149 fireworks/audiofire/audiofire_device.cpp \ 151 150 ' ) 152 151 153 152 fireworks_pkgdata = env.Split( '\ 154 fireworks/ffado_driver_fireworks.txt \155 153 ' ) 156 154 … … 233 231 libenv.PrependUnique( LIBS=["expat"] ) 234 232 233 # add the libconfig 234 libenv.AppendUnique( CPPPATH=["#/external/libconfig"] ) 235 libenv.PrependUnique( LIBPATH=[env['build_base']+"external/libconfig"] ) 236 libenv.PrependUnique( LIBS=["libconfigpp"] ) 237 235 238 #env1.AppendUnique( LINKFLAGS = env.Split("-Wl,-rpath $libdir -Wl,-soname -Wl,libffado.so.1 --version-info=1:0:0") ) 236 239 ffadolib = libenv.SharedLibrary( "ffado", source ) trunk/libffado/support/alsa/alsa_plugin.cpp
r1255 r1336 181 181 // } 182 182 // } 183 184 // if (io->state != SND_PCM_STATE_RUNNING) {185 // if (io->stream == SND_PCM_STREAM_PLAYBACK) {186 // for (channel = 0; channel < io->channels; channel++)187 // snd_pcm_area_silence(&jack->areas[channel], 0, nframes, io->format);188 // return 0;189 // }190 // }191 //192 // areas = snd_pcm_ioplug_mmap_areas(io);193 //194 // while (xfer < nframes) {195 // snd_pcm_uframes_t frames = nframes - xfer;196 // snd_pcm_uframes_t offset = jack->hw_ptr;197 // snd_pcm_uframes_t cont = io->buffer_size - offset;198 //199 // if (cont < frames)200 // frames = cont;201 //202 // for (channel = 0; channel < io->channels; channel++) {203 // if (io->stream == SND_PCM_STREAM_PLAYBACK)204 // snd_pcm_area_copy(&jack->areas[channel], xfer, &areas[channel], offset, frames, io->format);205 // else206 // snd_pcm_area_copy(&areas[channel], offset, &jack->areas[channel], xfer, frames, io->format);207 // }208 //209 // jack->hw_ptr += frames;210 // jack->hw_ptr %= io->buffer_size;211 // xfer += frames;212 // }213 //214 // write(jack->fd, buf, 1); /* for polling */215 183 216 184 static int … … 473 441 unsigned int access_list[] = { 474 442 SND_PCM_ACCESS_MMAP_NONINTERLEAVED, 475 SND_PCM_ACCESS_RW_NONINTERLEAVED,443 // SND_PCM_ACCESS_RW_NONINTERLEAVED, 476 444 }; 477 445 trunk/libffado/support/dbus/control-interface.xml
r1173 r1336 31 31 <arg type="s" name="name" direction="out"/> 32 32 </method> 33 <signal name="Destroyed"></signal> 33 34 <signal name="Updated"></signal> 35 <signal name="PreUpdate"></signal> 36 <signal name="PostUpdate"></signal> 34 37 </interface> 35 38 trunk/libffado/support/dbus/controlserver.cpp
r1324 r1336 44 44 // allocate a lock 45 45 if(parent == NULL) { 46 m_UpdateLock = new Util::PosixMutex( );46 m_UpdateLock = new Util::PosixMutex("CTLSVEL"); 47 47 } else { 48 48 m_UpdateLock = NULL; … … 129 129 130 130 // register an update signal handler 131 m_updateFunctor = new MemberSignalFunctor < Container*,131 m_updateFunctor = new MemberSignalFunctor1< Container*, 132 132 void (Container::*)(int) > 133 133 ( this, &Container::updated, (int)Control::Container::eS_Updated ); … … 148 148 debugOutput( DEBUG_LEVEL_VERBOSE, "Deleting Container on '%s'\n", 149 149 path().c_str() ); 150 151 Destroyed(); //send dbus signal 152 150 153 if(m_updateFunctor) { 151 154 if(!m_Slave.remSignalHandler(m_updateFunctor)) { … … 201 204 bool something_changed = false; 202 205 debugOutput( DEBUG_LEVEL_VERBOSE, "Updating tree...\n"); 206 // send a pre update signal 207 PreUpdate(); 203 208 debugOutput( DEBUG_LEVEL_VERBOSE, "Add handlers for elements...\n"); 204 209 // add handlers for the slaves that don't have one yet … … 272 277 Updated(); 273 278 } 279 // send a post update signal 280 PostUpdate(); 274 281 } 275 282 trunk/libffado/support/dbus/controlserver.h
r1173 r1336 45 45 46 46 template< typename CalleePtr, typename MemFunPtr > 47 class MemberSignalFunctor 47 class MemberSignalFunctor0 48 48 : public Control::SignalFunctor 49 49 { 50 50 public: 51 MemberSignalFunctor ( const CalleePtr& pCallee,51 MemberSignalFunctor0( const CalleePtr& pCallee, 52 52 MemFunPtr pMemFun, 53 53 int pSignalId) … … 57 57 {} 58 58 59 virtual ~MemberSignalFunctor ()59 virtual ~MemberSignalFunctor0() 60 60 {} 61 62 virtual void operator() () 63 { 64 ( ( *m_pCallee ).*m_pMemFun )(); 65 } 66 virtual void operator() (int) {} 67 private: 68 CalleePtr m_pCallee; 69 MemFunPtr m_pMemFun; 70 }; 71 72 template< typename CalleePtr, typename MemFunPtr > 73 class MemberSignalFunctor1 74 : public Control::SignalFunctor 75 { 76 public: 77 MemberSignalFunctor1( const CalleePtr& pCallee, 78 MemFunPtr pMemFun, 79 int pSignalId) 80 : Control::SignalFunctor( pSignalId ) 81 , m_pCallee( pCallee ) 82 , m_pMemFun( pMemFun ) 83 {} 84 85 virtual ~MemberSignalFunctor1() 86 {} 87 88 virtual void operator() () {} 61 89 62 90 virtual void operator() (int value) … … 119 147 120 148 void updated(int new_nb_elements); 149 void destroyed(); 150 121 151 void setVerboseLevel( const DBus::Int32 &); 122 152 private: trunk/libffado/support/dbus/ffado-dbus-server.cpp
r1254 r1336 252 252 debugOutput( DEBUG_LEVEL_NORMAL, "Using ffado library version: %s\n\n", ffado_get_version() ); 253 253 254 m_deviceManager = new DeviceManager(); 255 if ( !m_deviceManager ) { 256 debugError("Could not allocate device manager\n" ); 257 return exitfunction(-1); 258 } 259 if ( !m_deviceManager->initialize() ) { 260 debugError("Could not initialize device manager\n" ); 261 delete m_deviceManager; 262 return exitfunction(-1); 263 } 264 if ( arguments.verbose ) { 265 m_deviceManager->setVerboseLevel(arguments.verbose); 266 } 267 if ( !m_deviceManager->discover(arguments.use_cache) ) { 268 debugError("Could not discover devices\n" ); 269 delete m_deviceManager; 270 return exitfunction(-1); 271 } 272 273 // add pre-update handler 274 Util::Functor* preupdate_functor = new Util::CallbackFunctor0< void (*)() > 275 ( &preUpdateHandler, false ); 276 if ( !preupdate_functor ) { 277 debugFatal( "Could not create pre-update handler\n" ); 278 return false; 279 } 280 if(!m_deviceManager->registerPreUpdateNotification(preupdate_functor)) { 281 debugError("could not register pre-update notifier"); 282 } 283 // add post-update handler 284 Util::Functor* postupdate_functor = new Util::CallbackFunctor0< void (*)() > 285 ( &postUpdateHandler, false ); 286 if ( !postupdate_functor ) { 287 debugFatal( "Could not create post-update handler\n" ); 288 return false; 289 } 290 if(!m_deviceManager->registerPostUpdateNotification(postupdate_functor)) { 291 debugError("could not register post-update notifier"); 292 } 293 294 signal (SIGINT, sighandler); 295 296 DBus::_init_threading(); 254 m_deviceManager = new DeviceManager(); 255 if ( !m_deviceManager ) { 256 debugError("Could not allocate device manager\n" ); 257 return exitfunction(-1); 258 } 259 if ( !m_deviceManager->initialize() ) { 260 debugError("Could not initialize device manager\n" ); 261 delete m_deviceManager; 262 return exitfunction(-1); 263 } 264 if ( arguments.verbose ) { 265 m_deviceManager->setVerboseLevel(arguments.verbose); 266 } 267 if ( !m_deviceManager->discover(arguments.use_cache) ) { 268 debugError("Could not discover devices\n" ); 269 delete m_deviceManager; 270 return exitfunction(-1); 271 } 272 273 // add pre-update handler 274 Util::Functor* preupdate_functor = new Util::CallbackFunctor0< void (*)() > 275 ( &preUpdateHandler, false ); 276 if ( !preupdate_functor ) { 277 debugFatal( "Could not create pre-update handler\n" ); 278 return false; 279 } 280 if(!m_deviceManager->registerPreUpdateNotification(preupdate_functor)) { 281 debugError("could not register pre-update notifier"); 282 } 283 // add post-update handler 284 Util::Functor* postupdate_functor = new Util::CallbackFunctor0< void (*)() > 285 ( &postUpdateHandler, false ); 286 if ( !postupdate_functor ) { 287 debugFatal( "Could not create post-update handler\n" ); 288 return false; 289 } 290 if(!m_deviceManager->registerPostUpdateNotification(postupdate_functor)) { 291 debugError("could not register post-update notifier"); 292 } 293 294 signal (SIGINT, sighandler); 297 295 298 // test DBUS stuff 299 DBus::default_dispatcher = &dispatcher; 300 DBus::Connection conn = DBus::Connection::SessionBus(); 301 global_conn = &conn; 302 conn.request_name("org.ffado.Control"); 303 304 // lock the control tree such that it does not get modified while we build our view 305 m_deviceManager->lockControl(); 306 container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager", 307 NULL, *m_deviceManager); 308 // unlock the control tree since the tree is built 309 m_deviceManager->unlockControl(); 310 311 printMessage("DBUS test service running\n"); 312 printMessage("press ctrl-c to stop it & exit\n"); 313 314 while(run) { 315 debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 316 dispatcher.enter(); 317 318 debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 319 sem_wait(&run_sem); 320 debugOutput( DEBUG_LEVEL_NORMAL, " activity handled...\n"); 321 } 322 323 if(!m_deviceManager->unregisterPreUpdateNotification(preupdate_functor)) { 324 debugError("could not unregister pre update notifier"); 325 } 326 delete preupdate_functor; 327 if(!m_deviceManager->unregisterPostUpdateNotification(postupdate_functor)) { 328 debugError("could not unregister post update notifier"); 329 } 330 delete postupdate_functor; 331 delete container; 332 333 signal (SIGINT, SIG_DFL); 334 335 printMessage("server stopped\n"); 336 delete m_deviceManager; 337 return exitfunction(0); 338 } 296 DBus::_init_threading(); 297 298 // test DBUS stuff 299 DBus::default_dispatcher = &dispatcher; 300 DBus::Connection conn = DBus::Connection::SessionBus(); 301 global_conn = &conn; 302 conn.request_name("org.ffado.Control"); 303 304 // lock the control tree such that it does not get modified while we build our view 305 m_deviceManager->lockControl(); 306 container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager", 307 NULL, *m_deviceManager); 308 // unlock the control tree since the tree is built 309 m_deviceManager->unlockControl(); 310 311 printMessage("DBUS test service running\n"); 312 printMessage("press ctrl-c to stop it & exit\n"); 313 314 while(run) { 315 debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 316 dispatcher.enter(); 317 debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 318 sem_wait(&run_sem); 319 debugOutput( DEBUG_LEVEL_NORMAL, " activity handled...\n"); 320 } 321 322 if(!m_deviceManager->unregisterPreUpdateNotification(preupdate_functor)) { 323 debugError("could not unregister pre update notifier"); 324 } 325 delete preupdate_functor; 326 if(!m_deviceManager->unregisterPostUpdateNotification(postupdate_functor)) { 327 debugError("could not unregister post update notifier"); 328 } 329 delete postupdate_functor; 330 delete container; 331 332 signal (SIGINT, SIG_DFL); 333 334 printMessage("server stopped\n"); 335 delete m_deviceManager; 336 return exitfunction(0); 337 } trunk/libffado/support/firmware/bridgeco-downloader.cpp
r1234 r1336 42 42 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; 43 43 const char *doc = "bridgeco-downloader -- firmware downloader application for BridgeCo devices\n\n" 44 "OPERATION: display\n"45 " setguidGUID\n"46 " firmware FILE\n"47 " cne FILE\n"48 " bcd FILE\n";44 "OPERATION: GUID display\n" 45 " GUID setguid NEW_GUID\n" 46 " GUID firmware FILE\n" 47 " GUID cne FILE\n" 48 " GUID bcd FILE\n"; 49 49 static struct argp_option _options[] = { 50 50 {"verbose", 'v', "level", 0, "Produce verbose output" }, … … 88 88 ConfigRom configRom(service, i); 89 89 configRom.initialize(); 90 90 91 91 if (configRom.getGuid() == guid) 92 92 node_id = configRom.getNodeId(); … … 135 135 } else { 136 136 cout << "Firmware download was successful" << endl; 137 cout << "Please reboot the device by removing the power and firewire connections." << endl; 137 138 } 138 139 } else if ( strcmp( args->args[1], "cne" ) == 0 ) { … … 148 149 } else { 149 150 cout << "CnE download was successful" << endl; 151 cout << "Please reboot the device by removing the power and firewire connections." << endl; 150 152 } 151 153 } else if ( strcmp( args->args[1], "display" ) == 0 ) { trunk/libffado/support/firmware/fireworks-downloader.cpp
r1234 r1336 25 25 #include "downloader.h" 26 26 27 #include "config.h" 28 27 29 #include "src/fireworks/fireworks_device.h" 28 30 #include "src/fireworks/fireworks_firmware.h" 31 #include "src/fireworks/fireworks_session_block.h" 29 32 30 33 #include "libieee1394/configrom.h" 31 34 #include "libieee1394/ieee1394service.h" 35 #include "libutil/Configuration.h" 32 36 33 37 #include "debugmodule/debugmodule.h" … … 49 53 // arg parsing 50 54 //////////////////////////////////////////////// 51 const char *argp_program_version = "fireworks-downloader 0. 2";55 const char *argp_program_version = "fireworks-downloader 0.3"; 52 56 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; 53 57 const char *doc = "fireworks-downloader -- firmware downloader application for ECHO Fireworks devices\n\n" … … 67 71 " Verify that the firmware contained in the device corresponds\n" 68 72 " to the one contained in FILE\n" 73 " session_display\n" 74 " show information about the session on the device\n" 75 " session_info FILE\n" 76 " show information about the session in FILE\n" 77 " session_download FILE\n" 78 " Download the session content from the device to FILE\n" 79 " session_upload FILE\n" 80 " Upload the session from FILE to the device\n" 69 81 ; 70 82 … … 148 160 f.dumpData(); 149 161 return 0; 162 } else if ( strcmp( args->args[0], "session_info" ) == 0 ) { 163 if (!args->args[1] ) { 164 printMessage("FILE argument is missing\n"); 165 return -1; 166 } 167 std::string str( args->args[1] ); 168 169 // load the file 170 Session s = Session(); 171 s.setVerboseLevel( args->verbose ); 172 173 if (!s.loadFromFile(str)) { 174 printMessage("Could not load session\n"); 175 return -1; 176 } 177 s.show(); 178 return 0; 150 179 } else if ( strcmp( args->args[0], "list" ) == 0 ) { 151 180 printDeviceList(); … … 169 198 ConfigRom configRom(service, i); 170 199 configRom.initialize(); 171 172 200 if (configRom.getGuid() == guid) { 173 201 node_id = configRom.getNodeId(); … … 195 223 } 196 224 197 if ( !FireWorks::Device::probe(*configRom) ) { 225 Util::Configuration c; 226 c.openFile( USER_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 227 c.openFile( SYSTEM_CONFIG_FILE, Util::Configuration::eFM_ReadOnly ); 228 229 if ( !FireWorks::Device::probe(c, *configRom) ) { 198 230 printMessage( "Device with node id %d is not an ECHO FireWorks device.\n", 199 231 node_id ); … … 201 233 return -1; 202 234 } 203 235 204 236 DeviceManager d = DeviceManager(); 205 237 Device *dev = new Device(d, std::auto_ptr<ConfigRom>(configRom) ); … … 382 414 printMessage(" => Verify successful. Firmware upload successful.\n"); 383 415 } 416 } else if ( strcmp( args->args[0], "session_display" ) == 0 ) { 417 // load the session 418 Session s = Session(); 419 s.setVerboseLevel( args->verbose ); 420 421 if (!s.loadFromDevice(*dev)) { 422 printMessage("Could not load session\n"); 423 return -1; 424 } 425 s.show(); 426 } else if ( strcmp( args->args[0], "session_download" ) == 0 ) { 427 if (!args->args[1] ) { 428 printMessage("FILE argument is missing\n"); 429 delete dev; 430 return -1; 431 } 432 std::string str( args->args[1] ); 433 434 printMessage("Downloading session to file: %s\n", str.c_str()); 435 436 printMessage(" loading session...\n"); 437 // load the session 438 Session s = Session(); 439 s.setVerboseLevel( args->verbose ); 440 441 if (!s.loadFromDevice(*dev)) { 442 printMessage("Could not load session from device\n"); 443 return -1; 444 } 445 446 printMessage(" saving session...\n"); 447 if (!s.saveToFile(str)) { 448 printMessage("Could not save session to file\n"); 449 return -1; 450 } 451 } else if ( strcmp( args->args[0], "session_upload" ) == 0 ) { 452 if (!args->args[1] ) { 453 printMessage("FILE argument is missing\n"); 454 delete dev; 455 return -1; 456 } 457 std::string str( args->args[1] ); 458 459 printMessage("Uploading session from file: %s\n", str.c_str()); 460 461 printMessage(" loading session...\n"); 462 // load the session 463 Session s = Session(); 464 s.setVerboseLevel( args->verbose ); 465 if (!s.loadFromFile(str)) { 466 printMessage("Could not load session from file\n"); 467 return -1; 468 } 469 470 printMessage(" saving session...\n"); 471 if (!s.saveToDevice(*dev)) { 472 printMessage("Could not save session to device\n"); 473 return -1; 474 } 475 384 476 } else { 385 477 printMessage("Unknown operation\n"); trunk/libffado/support/mixer/ffadomixer.in
r1326 r1336 43 43 from mixer_saffirele import * 44 44 from mixer_saffirepro import * 45 from mixer_a f2import *45 from mixer_audiofire import * 46 46 from mixer_bcoaudio5 import * 47 47 from mixer_edirolfa66 import * … … 69 69 [(0x00130e, 0x00000006),'SaffireProMixer'], 70 70 [(0x00130e, 0x00000000),'SaffireMixer'], 71 [(0x001486, 0x00000af2),'AudioFire2Mixer'], 71 [(0x001486, 0x00000af2),'AudioFireMixer'], 72 [(0x001486, 0x00000af4),'AudioFireMixer'], 73 [(0x001486, 0x00000af8),'AudioFireMixer'], 74 [(0x001486, 0x0000af12),'AudioFireMixer'], 72 75 [(0x0007f5, 0x00010049),'BCoAudio5Control'], 73 76 [(0x0040AB, 0x00010049),'EdirolFa66Control'], … … 77 80 [(0x0001f2, 0x00000000),'MotuMixer'], 78 81 ] 82 83 POLL_SLEEP_TIME_MSEC = 100 # 100ms 79 84 80 85 class ControlInterface: … … 271 276 return self.iface.getAttributeName(idx) 272 277 278 class SamplerateSelectInterface: 279 def __init__(self, servername, devicepath): 280 self.basepath=devicepath + '/Generic/SamplerateSelect' 281 self.servername=servername 282 self.bus=dbus.SessionBus() 283 self.dev = self.bus.get_object(self.servername, self.basepath) 284 self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Enum') 285 def count(self): 286 return self.iface.count() 287 def select(self, idx): 288 return self.iface.select(idx) 289 def selected(self): 290 return self.iface.selected() 291 def getEnumLabel(self, idx): 292 return self.iface.getEnumLabel(idx) 293 273 294 class TextInterface: 274 295 def __init__(self, servername, basepath): … … 291 312 self.setLineWidth( 2 ) 292 313 self.setMinimumHeight( 10 ) 314 315 class PollUpdateWidgets(QObject): 316 def __init__(self, widgets): 317 QObject.__init__(self) 318 self.widgets = widgets 319 320 def updateWidgets(self): 321 for w in self.widgets: 322 if 'polledUpdate' in dir(w): 323 try: 324 w.polledUpdate() 325 except: 326 print "error in polled update" 293 327 294 328 if __name__ == "__main__": … … 336 370 mw = QTabWidget() 337 371 372 mixerwidgets = [] 373 338 374 for idx in range(nbDevices): 339 375 path=devmgr.getDeviceName(idx) … … 372 408 # create a control object 373 409 hw = ControlInterface(server, basepath+'/DeviceManager/'+path) 410 clockselect = ClockSelectInterface( server, basepath+"/DeviceManager/"+path ) 411 samplerateselect = SamplerateSelectInterface( server, basepath+"/DeviceManager/"+path ) 412 nickname = TextInterface( server, basepath+"/DeviceManager/"+path+"/Generic/Nickname" ) 374 413 375 414 # … … 377 416 # 378 417 tmp = GlobalMixer( w ) 379 tmp.clockselect = ClockSelectInterface( server, basepath+"/DeviceManager/"+path ) 380 tmp.nickname = TextInterface( server, basepath+"/DeviceManager/"+path+"/Generic/Nickname" ) 418 tmp.configrom = cfgrom 419 tmp.clockselect = clockselect 420 tmp.samplerateselect = samplerateselect 421 tmp.nickname = nickname 381 422 tmp.hw = hw 382 423 tmp.initValues() … … 409 450 410 451 # different panel for different clock frequency 411 samplerate = hw.getDiscrete('/Generic/SamplerateSelect') 452 selected = samplerateselect.selected() 453 samplerate = int(samplerateselect.getEnumLabel( selected )) 412 454 413 455 # adat on PRO26 makes a difference … … 455 497 # 456 498 l.addWidget( mixerwidget, 10 ) 499 mixerwidget.configrom = cfgrom 500 mixerwidget.clockselect = clockselect 501 mixerwidget.samplerateselect = samplerateselect 502 mixerwidget.nickname = nickname 457 503 mixerwidget.hw = hw 458 mixerwidget.configrom = cfgrom 459 mixerwidget.clockselect = ClockSelectInterface(server, basepath+'/DeviceManager/'+path) 460 mixerwidget.initValues() 504 if 'buildMixer' in dir(mixerwidget): 505 mixerwidget.buildMixer() 506 if 'initValues' in dir(mixerwidget): 507 mixerwidget.initValues() 508 mixerwidgets.append(mixerwidget) 461 509 mw.addTab( w, mixerapp ) 462 510 … … 471 519 # 472 520 if mw.count() > 0: 521 puw = PollUpdateWidgets(mixerwidgets) 522 timer = QTimer(puw) 523 QObject.connect( timer, SIGNAL('timeout()'), puw.updateWidgets ); 524 timer.start( POLL_SLEEP_TIME_MSEC ); 525 526 # Adjust size of mixer window to the requirements of the selected device mixer(s) 527 mw.adjustSize() 528 473 529 mw.show() 474 530 … … 476 532 477 533 app.exec_loop() 478 trunk/libffado/support/mixer/ffadomixer_config.py.in
r1077 r1336 1 #!/usr/bin/python 2 #coding: utf-8 3 1 4 REGISTER_URL = '$REGISTRATION_URL' 2 5 INI_FILE_PATH = "$CONFIGDIR/registration.ini" trunk/libffado/support/mixer/mixer_global.py
r1108 r1336 41 41 self.clocksource.setCurrentItem( selected ) 42 42 43 def samplerateChanged( self, sr ): 44 print "samplerateChanged( " + str(sr) + " )" 45 self.samplerateselect.select( sr ) 46 selected = self.samplerateselect.selected() 47 48 if selected != sr: 49 srname = self.samplerateselect.getEnumLabel( sr ) 50 msg = QMessageBox() 51 msg.question( msg, "Failed to select sample rate", \ 52 "<qt>Could not select %s as samplerate.</qt>" % srname, \ 53 QMessageBox.Ok ) 54 self.samplerate.setCurrentItem( selected ) 55 43 56 def nicknameChanged( self, name ): 44 57 #print "nicknameChanged( %s )" % name … … 50 63 self.clocksource.insertItem( self.clockselect.getEnumLabel( i ) ) 51 64 self.clocksource.setCurrentItem( self.clockselect.selected() ) 65 66 for i in range( self.samplerateselect.count() ): 67 self.samplerate.insertItem( self.samplerateselect.getEnumLabel( i ) ) 68 self.samplerate.setCurrentItem( self.samplerateselect.selected() ) 69 52 70 self.txtNickname.setText( self.nickname.text() ) 53 71 trunk/libffado/support/mixer/mixer_global.ui
r1105 r1336 26 26 <x>0</x> 27 27 <y>0</y> 28 <width> 600</width>28 <width>721</width> 29 29 <height>191</height> 30 30 </rect> … … 41 41 <string>Global Mixer Options</string> 42 42 </property> 43 < grid>43 <hbox> 44 44 <property name="name"> 45 45 <cstring>unnamed</cstring> 46 46 </property> 47 <widget class="QLa bel" row="0" column="0">47 <widget class="QLayoutWidget"> 48 48 <property name="name"> 49 <cstring> textLabel1</cstring>49 <cstring>layout5</cstring> 50 50 </property> 51 <property name="text"> 52 <string>Device Nickname:</string> 53 </property> 54 <property name="buddy" stdset="0"> 55 <cstring>nickname</cstring> 56 </property> 51 <vbox> 52 <property name="name"> 53 <cstring>unnamed</cstring> 54 </property> 55 <widget class="QLayoutWidget"> 56 <property name="name"> 57 <cstring>layout2</cstring> 58 </property> 59 <hbox> 60 <property name="name"> 61 <cstring>unnamed</cstring> 62 </property> 63 <widget class="QLabel"> 64 <property name="name"> 65 <cstring>textLabel1</cstring> 66 </property> 67 <property name="text"> 68 <string>Device Nickname:</string> 69 </property> 70 <property name="buddy" stdset="0"> 71 <cstring>nickname</cstring> 72 </property> 73 </widget> 74 <widget class="QLineEdit"> 75 <property name="name"> 76 <cstring>txtNickname</cstring> 77 </property> 78 <property name="minimumSize"> 79 <size> 80 <width>100</width> 81 <height>0</height> 82 </size> 83 </property> 84 </widget> 85 </hbox> 86 </widget> 87 <widget class="QLayoutWidget"> 88 <property name="name"> 89 <cstring>layout4</cstring> 90 </property> 91 <hbox> 92 <property name="name"> 93 <cstring>unnamed</cstring> 94 </property> 95 <widget class="QLabel"> 96 <property name="name"> 97 <cstring>textLabel2</cstring> 98 </property> 99 <property name="text"> 100 <string>Clock Source:</string> 101 </property> 102 <property name="buddy" stdset="0"> 103 <cstring>clocksource</cstring> 104 </property> 105 </widget> 106 <widget class="QComboBox"> 107 <property name="name"> 108 <cstring>clocksource</cstring> 109 </property> 110 </widget> 111 <spacer> 112 <property name="name"> 113 <cstring>spacer2</cstring> 114 </property> 115 <property name="orientation"> 116 <enum>Horizontal</enum> 117 </property> 118 <property name="sizeType"> 119 <enum>Expanding</enum> 120 </property> 121 <property name="sizeHint"> 122 <size> 123 <width>31</width> 124 <height>21</height> 125 </size> 126 </property> 127 </spacer> 128 <widget class="QLabel"> 129 <property name="name"> 130 <cstring>textLabel2_2</cstring> 131 </property> 132 <property name="text"> 133 <string>Sample Rate:</string> 134 </property> 135 <property name="buddy" stdset="0"> 136 <cstring>clocksource</cstring> 137 </property> 138 </widget> 139 <widget class="QComboBox"> 140 <property name="name"> 141 <cstring>samplerate</cstring> 142 </property> 143 <property name="enabled"> 144 <bool>false</bool> 145 </property> 146 </widget> 147 </hbox> 148 </widget> 149 </vbox> 57 150 </widget> 58 <widget class="QLineEdit" row="0" column="1"> 59 <property name="name"> 60 <cstring>txtNickname</cstring> 61 </property> 62 <property name="minimumSize"> 63 <size> 64 <width>100</width> 65 <height>0</height> 66 </size> 67 </property> 68 </widget> 69 <widget class="QLabel" row="1" column="0"> 70 <property name="name"> 71 <cstring>textLabel2</cstring> 72 </property> 73 <property name="text"> 74 <string>Clock Source:</string> 75 </property> 76 <property name="buddy" stdset="0"> 77 <cstring>clocksource</cstring> 78 </property> 79 </widget> 80 <widget class="QComboBox" row="1" column="1"> 81 <property name="name"> 82 <cstring>clocksource</cstring> 83 </property> 84 </widget> 85 <spacer row="0" column="2" rowspan="2" colspan="1"> 151 <spacer> 86 152 <property name="name"> 87 153 <cstring>spacer1</cstring> … … 95 161 <property name="sizeHint"> 96 162 <size> 97 <width> 111</width>163 <width>330</width> 98 164 <height>71</height> 99 165 </size> 100 166 </property> 101 167 </spacer> 102 </ grid>168 </hbox> 103 169 </widget> 104 170 <connections> … … 115 181 <slot>nicknameChanged(const QString&)</slot> 116 182 </connection> 183 <connection> 184 <sender>samplerate</sender> 185 <signal>activated(int)</signal> 186 <receiver>GlobalMixerUi</receiver> 187 <slot>samplerateChanged(int)</slot> 188 </connection> 117 189 </connections> 118 190 <slots> 119 191 <slot>clockChanged( int )</slot> 120 192 <slot>nicknameChanged( const QString& )</slot> 193 <slot>samplerateChanged(int)</slot> 121 194 </slots> 122 195 <layoutdefaults spacing="6" margin="11"/> trunk/libffado/support/mixer/mixer_motu.py
r1274 r1336 505 505 # may end up using a matrix mixer. 506 506 self.PairSwitches={ 507 self.mix1ana1_2_pair: ['Mixer/Mix1/Ana1_2_pair'],508 self.mix1ana3_4_pair: ['Mixer/Mix1/Ana3_4_pair'],509 self.mix1ana5_6_pair: ['Mixer/Mix1/Ana5_6_pair'],510 self.mix1ana7_8_pair: ['Mixer/Mix1/Ana7_8_pair'],511 self.mix1aes1_2_pair: ['Mixer/Mix1/Aes1_2_pair'],512 self.mix1adat1_2_pair: ['Mixer/Mix1/Adat1_2_pair'],513 self.mix1adat3_4_pair: ['Mixer/Mix1/Adat3_4_pair'],514 self.mix1adat5_6_pair: ['Mixer/Mix1/Adat5_6_pair'],515 self.mix1adat7_8_pair: ['Mixer/Mix1/Adat7_8_pair'],516 self.mix1spdif1_2_pair: ['Mixer/Mix1/Spdif1_2_pair'],517 518 self.mix2ana1_2_pair: ['Mixer/Mix2/Ana1_2_pair'],519 self.mix2ana3_4_pair: ['Mixer/Mix2/Ana3_4_pair'],520 self.mix2ana5_6_pair: ['Mixer/Mix2/Ana5_6_pair'],521 self.mix2ana7_8_pair: ['Mixer/Mix2/Ana7_8_pair'],522 self.mix2aes1_2_pair: ['Mixer/Mix2/Aes1_2_pair'],523 self.mix2adat1_2_pair: ['Mixer/Mix2/Adat1_2_pair'],524 self.mix2adat3_4_pair: ['Mixer/Mix2/Adat3_4_pair'],525 self.mix2adat5_6_pair: ['Mixer/Mix2/Adat5_6_pair'],526 self.mix2adat7_8_pair: ['Mixer/Mix2/Adat7_8_pair'],527 self.mix2spdif1_2_pair: ['Mixer/Mix2/Spdif1_2_pair'],528 529 self.mix3ana1_2_pair: ['Mixer/Mix3/Ana1_2_pair'],530 self.mix3ana3_4_pair: ['Mixer/Mix3/Ana3_4_pair'],531 self.mix3ana5_6_pair: ['Mixer/Mix3/Ana5_6_pair'],532 self.mix3ana7_8_pair: ['Mixer/Mix3/Ana7_8_pair'],533 self.mix3aes1_2_pair: ['Mixer/Mix3/Aes1_2_pair'],534 self.mix3adat1_2_pair: ['Mixer/Mix3/Adat1_2_pair'],535 self.mix3adat3_4_pair: ['Mixer/Mix3/Adat3_4_pair'],536 self.mix3adat5_6_pair: ['Mixer/Mix3/Adat5_6_pair'],537 self.mix3adat7_8_pair: ['Mixer/Mix3/Adat7_8_pair'],538 self.mix3spdif1_2_pair: ['Mixer/Mix3/Spdif1_2_pair'],539 540 self.mix4ana1_2_pair: ['Mixer/Mix4/Ana1_2_pair'],541 self.mix4ana3_4_pair: ['Mixer/Mix4/Ana3_4_pair'],542 self.mix4ana5_6_pair: ['Mixer/Mix4/Ana5_6_pair'],543 self.mix4ana7_8_pair: ['Mixer/Mix4/Ana7_8_pair'],544 self.mix4aes1_2_pair: ['Mixer/Mix4/Aes1_2_pair'],545 self.mix4adat1_2_pair: ['Mixer/Mix4/Adat1_2_pair'],546 self.mix4adat3_4_pair: ['Mixer/Mix4/Adat3_4_pair'],547 self.mix4adat5_6_pair: ['Mixer/Mix4/Adat5_6_pair'],548 self.mix4adat7_8_pair: ['Mixer/Mix4/Adat7_8_pair'],549 self.mix4spdif1_2_pair: ['Mixer/Mix4/Spdif1_2_pair'],507 # self.mix1ana1_2_pair: ['Mixer/Mix1/Ana1_2_pair'], 508 # self.mix1ana3_4_pair: ['Mixer/Mix1/Ana3_4_pair'], 509 # self.mix1ana5_6_pair: ['Mixer/Mix1/Ana5_6_pair'], 510 # self.mix1ana7_8_pair: ['Mixer/Mix1/Ana7_8_pair'], 511 # self.mix1aes1_2_pair: ['Mixer/Mix1/Aes1_2_pair'], 512 # self.mix1adat1_2_pair: ['Mixer/Mix1/Adat1_2_pair'], 513 # self.mix1adat3_4_pair: ['Mixer/Mix1/Adat3_4_pair'], 514 # self.mix1adat5_6_pair: ['Mixer/Mix1/Adat5_6_pair'], 515 # self.mix1adat7_8_pair: ['Mixer/Mix1/Adat7_8_pair'], 516 # self.mix1spdif1_2_pair: ['Mixer/Mix1/Spdif1_2_pair'], 517 518 # self.mix2ana1_2_pair: ['Mixer/Mix2/Ana1_2_pair'], 519 # self.mix2ana3_4_pair: ['Mixer/Mix2/Ana3_4_pair'], 520 # self.mix2ana5_6_pair: ['Mixer/Mix2/Ana5_6_pair'], 521 # self.mix2ana7_8_pair: ['Mixer/Mix2/Ana7_8_pair'], 522 # self.mix2aes1_2_pair: ['Mixer/Mix2/Aes1_2_pair'], 523 # self.mix2adat1_2_pair: ['Mixer/Mix2/Adat1_2_pair'], 524 # self.mix2adat3_4_pair: ['Mixer/Mix2/Adat3_4_pair'], 525 # self.mix2adat5_6_pair: ['Mixer/Mix2/Adat5_6_pair'], 526 # self.mix2adat7_8_pair: ['Mixer/Mix2/Adat7_8_pair'], 527 # self.mix2spdif1_2_pair: ['Mixer/Mix2/Spdif1_2_pair'], 528 529 # self.mix3ana1_2_pair: ['Mixer/Mix3/Ana1_2_pair'], 530 # self.mix3ana3_4_pair: ['Mixer/Mix3/Ana3_4_pair'], 531 # self.mix3ana5_6_pair: ['Mixer/Mix3/Ana5_6_pair'], 532 # self.mix3ana7_8_pair: ['Mixer/Mix3/Ana7_8_pair'], 533 # self.mix3aes1_2_pair: ['Mixer/Mix3/Aes1_2_pair'], 534 # self.mix3adat1_2_pair: ['Mixer/Mix3/Adat1_2_pair'], 535 # self.mix3adat3_4_pair: ['Mixer/Mix3/Adat3_4_pair'], 536 # self.mix3adat5_6_pair: ['Mixer/Mix3/Adat5_6_pair'], 537 # self.mix3adat7_8_pair: ['Mixer/Mix3/Adat7_8_pair'], 538 # self.mix3spdif1_2_pair: ['Mixer/Mix3/Spdif1_2_pair'], 539 540 # self.mix4ana1_2_pair: ['Mixer/Mix4/Ana1_2_pair'], 541 # self.mix4ana3_4_pair: ['Mixer/Mix4/Ana3_4_pair'], 542 # self.mix4ana5_6_pair: ['Mixer/Mix4/Ana5_6_pair'], 543 # self.mix4ana7_8_pair: ['Mixer/Mix4/Ana7_8_pair'], 544 # self.mix4aes1_2_pair: ['Mixer/Mix4/Aes1_2_pair'], 545 # self.mix4adat1_2_pair: ['Mixer/Mix4/Adat1_2_pair'], 546 # self.mix4adat3_4_pair: ['Mixer/Mix4/Adat3_4_pair'], 547 # self.mix4adat5_6_pair: ['Mixer/Mix4/Adat5_6_pair'], 548 # self.mix4adat7_8_pair: ['Mixer/Mix4/Adat7_8_pair'], 549 # self.mix4spdif1_2_pair: ['Mixer/Mix4/Spdif1_2_pair'], 550 550 } 551 551 … … 560 560 self.optical_in_mode: ['/Mixer/Control/OpticalIn_mode'], 561 561 self.optical_out_mode: ['/Mixer/Control/OpticalOut_mode'], 562 563 self.meter_src_ctrl: ['/Mixer/Control/Meter_src'], 564 self.aesebu_meter_ctrl: ['/Mixer/Control/Meter_aesebu_src'], 565 self.peakhold_time_ctrl:['/Mixer/Control/Meter_peakhold_time'], 566 self.cliphold_time_ctrl:['/Mixer/Control/Meter_cliphold_time'], 562 567 } 563 568 … … 594 599 # Mic input controls displace AES/EBU since no current device 595 600 # has both. 596 self.mix1_ aes_group.setTitle("Mic inputs")597 self.mix2_ aes_group.setTitle("Mic inputs")598 self.mix3_ aes_group.setTitle("Mic inputs")599 self.mix4_ aes_group.setTitle("Mic inputs")601 self.mix1_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 602 self.mix2_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 603 self.mix3_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 604 self.mix4_tab.setTabLabel(self.mix1_tab.page(1), "Mic inputs"); 600 605 # FIXME: when implmented, will mic channels just reuse the AES/EBU 601 606 # dbus path? If not we'll have to reset the respective values in … … 603 608 else: 604 609 if (not(self.has_aesebu_inputs)): 605 self.mix1_ aes_group.setEnabled(False)606 self.mix2_ aes_group.setEnabled(False)607 self.mix3_ aes_group.setEnabled(False)608 self.mix4_ aes_group.setEnabled(False)610 self.mix1_tab.page(1).setEnabled(False) 611 self.mix2_tab.page(1).setEnabled(False) 612 self.mix3_tab.page(1).setEnabled(False) 613 self.mix4_tab.page(1).setEnabled(False) 609 614 if (not(self.has_spdif_inputs)): 610 self.mix1_spdif_group.setEnabled(False) 611 self.mix2_spdif_group.setEnabled(False) 612 self.mix3_spdif_group.setEnabled(False) 613 self.mix4_spdif_group.setEnabled(False) 614 615 # Devices without AES/EBU inputs/outputs have dedicated "MainOut" 616 # outputs instead. 617 if (not(self.has_aesebu_inputs)): 615 self.mix1_tab.page(2).setEnabled(False); 616 self.mix2_tab.page(2).setEnabled(False); 617 self.mix3_tab.page(2).setEnabled(False); 618 self.mix4_tab.page(2).setEnabled(False); 619 620 # Devices without AES/EBU inputs/outputs (normally ID 6 in the 621 # destination lists) have dedicated "MainOut" outputs instead. The 622 # 896HD is an exception: it uses ID 6 for MainOut and ID 7 623 # (nominally SPDIF) for AES/EBU. 624 if (not(self.has_aesebu_inputs) or self.model==MOTU_MODEL_896HD): 618 625 self.mix1_dest.changeItem("MainOut", 6) 619 626 self.mix2_dest.changeItem("MainOut", 6) 620 627 self.mix3_dest.changeItem("MainOut", 6) 621 628 self.mix4_dest.changeItem("MainOut", 6) 629 self.phones_src.changeItem("MainOut", 6) 630 # Change the SPDIF destination to AES/EBU for the 896HD. 631 if (self.model == MOTU_MODEL_896HD): 632 self.mix1_dest.changeItem("AES/EBU", 7) 633 self.mix2_dest.changeItem("AES/EBU", 7) 634 self.mix3_dest.changeItem("AES/EBU", 7) 635 self.mix4_dest.changeItem("AES/EBU", 7) 636 self.phones_src.changeItem("AES/EBU", 7) 622 637 623 638 # Some devices don't have the option of selecting an optical SPDIF … … 627 642 self.optical_out_mode.removeItem(2) 628 643 644 # Only the 896HD has meter controls 645 if (self.model != MOTU_MODEL_896HD): 646 self.disable_hide(self.meter_src) 647 self.disable_hide(self.aesebu_meter) 648 self.disable_hide(self.peakhold_time) 649 self.disable_hide(self.cliphold_time) 650 629 651 # Some controls must be disabled if the device is streaming 630 652 if (self.is_streaming): … … 636 658 if (self.sample_rate > 96000): 637 659 print "Disabling controls not present above 96 kHz" 638 self.mix1_ adat_group.setEnabled(False)639 self.mix1_ aes_group.setEnabled(False)640 self.mix1_ spdif_group.setEnabled(False)641 self.mix2_ adat_group.setEnabled(False)642 self.mix2_ aes_group.setEnabled(False)643 self.mix2_ spdif_group.setEnabled(False)644 self.mix3_ adat_group.setEnabled(False)645 self.mix3_ aes_group.setEnabled(False)646 self.mix3_ spdif_group.setEnabled(False)647 self.mix4_ adat_group.setEnabled(False)648 self.mix4_ aes_group.setEnabled(False)649 self.mix4_ spdif_group.setEnabled(False)660 self.mix1_tab.page(3).setEnabled(False) # ADAT 661 self.mix1_tab.page(2).setEnabled(False) # SPDIF 662 self.mix1_tab.page(1).setEnabled(False) # AES/EBU 663 self.mix2_tab.page(3).setEnabled(False) # ADAT 664 self.mix2_tab.page(2).setEnabled(False) # SPDIF 665 self.mix2_tab.page(1).setEnabled(False) # AES/EBU 666 self.mix3_tab.page(3).setEnabled(False) # ADAT 667 self.mix3_tab.page(2).setEnabled(False) # SPDIF 668 self.mix3_tab.page(1).setEnabled(False) # AES/EBU 669 self.mix4_tab.page(3).setEnabled(False) # ADAT 670 self.mix4_tab.page(2).setEnabled(False) # SPDIF 671 self.mix4_tab.page(1).setEnabled(False) # AES/EBU 650 672 if (self.sample_rate > 48000): 651 673 print "Disabling controls not present above 48 kHz" 652 self.mix1_adat58_group.setEnabled(False) 653 self.mix2_adat58_group.setEnabled(False) 654 self.mix3_adat58_group.setEnabled(False) 655 self.mix4_adat58_group.setEnabled(False) 674 self.mix1_adat5.setEnabled(False) 675 self.mix1_adat6.setEnabled(False) 676 self.mix1_adat7.setEnabled(False) 677 self.mix1_adat8.setEnabled(False) 678 self.mix2_adat5.setEnabled(False) 679 self.mix2_adat6.setEnabled(False) 680 self.mix2_adat7.setEnabled(False) 681 self.mix2_adat8.setEnabled(False) 682 self.mix3_adat5.setEnabled(False) 683 self.mix3_adat6.setEnabled(False) 684 self.mix3_adat7.setEnabled(False) 685 self.mix3_adat8.setEnabled(False) 686 self.mix4_adat5.setEnabled(False) 687 self.mix4_adat6.setEnabled(False) 688 self.mix4_adat7.setEnabled(False) 689 self.mix4_adat8.setEnabled(False) 656 690 657 691 # Ensure the correct input controls are active for a given interface 658 692 if (self.model == MOTU_MODEL_TRAVELER): 659 693 self.disable_hide(self.ana1_level) 660 self.disable_hide(self.ana1_level_label)661 694 self.disable_hide(self.ana2_level) 662 self.disable_hide(self.ana2_level_label)663 695 self.disable_hide(self.ana3_level) 664 self.disable_hide(self.ana3_level_label)665 696 self.disable_hide(self.ana4_level) 666 self.disable_hide(self.ana4_level_label)667 697 self.disable_hide(self.ana1_boost) 668 self.disable_hide(self.ana1_boost_label)669 698 self.disable_hide(self.ana2_boost) 670 self.disable_hide(self.ana2_boost_label)671 699 self.disable_hide(self.ana3_boost) 672 self.disable_hide(self.ana3_boost_label)673 700 self.disable_hide(self.ana4_boost) 674 self.disable_hide(self.ana4_boost_label) 701 self.disable_hide(self.ana5_trimgain) 702 self.disable_hide(self.ana5_trimgain_label) 703 self.disable_hide(self.ana6_trimgain) 704 self.disable_hide(self.ana6_trimgain_label) 705 self.disable_hide(self.ana7_trimgain) 706 self.disable_hide(self.ana7_trimgain_label) 707 self.disable_hide(self.ana8_trimgain) 708 self.disable_hide(self.ana8_trimgain_label) 709 self.disable_hide(self.ana5_pad) 710 self.disable_hide(self.ana6_pad) 711 self.disable_hide(self.ana7_pad) 712 self.disable_hide(self.ana8_pad) 675 713 else: 676 714 self.disable_hide(self.ana1_trimgain) … … 683 721 self.disable_hide(self.ana4_trimgain_label) 684 722 self.disable_hide(self.ana1_pad) 685 self.disable_hide(self.ana1_pad_label)686 723 self.disable_hide(self.ana2_pad) 687 self.disable_hide(self.ana2_pad_label)688 724 self.disable_hide(self.ana3_pad) 689 self.disable_hide(self.ana3_pad_label)690 725 self.disable_hide(self.ana4_pad) 691 self.disable_hide(self.ana4_pad_label) 726 self.disable_hide(self.ana5_trimgain) 727 self.disable_hide(self.ana5_trimgain_label) 728 self.disable_hide(self.ana6_trimgain) 729 self.disable_hide(self.ana6_trimgain_label) 730 self.disable_hide(self.ana7_trimgain) 731 self.disable_hide(self.ana7_trimgain_label) 732 self.disable_hide(self.ana8_trimgain) 733 self.disable_hide(self.ana8_trimgain_label) 734 self.disable_hide(self.ana5_pad) 735 self.disable_hide(self.ana6_pad) 736 self.disable_hide(self.ana7_pad) 737 self.disable_hide(self.ana8_pad) 692 738 693 739 # Now fetch the current values into the respective controls. Don't … … 735 781 val = self.hw.getMatrixMixerValue(info[0], info[1], info[2]) 736 782 print "%s for mix %d channel %d is %d" % (info[0] , info[1], info[2], val) 737 ctrl.set Checked(val)783 ctrl.setOn(val) 738 784 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateChannelBinarySwitch) 739 785 … … 743 789 val = self.hw.getDiscrete(info[0]) 744 790 print "%s switch is %d" % (info[0] , val) 745 ctrl.set Checked(val)791 ctrl.setOn(val) 746 792 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateBinarySwitch) 747 793 trunk/libffado/support/mixer/mixer_motu.ui
r1274 r1336 1 1 <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> 2 2 <class>MotuMixerUI</class> 3 <comment>Copyright (C) 200 5-2008 by Pieter Palmers4 Copyright (C) 2008 by Jonathan Woithe 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 3 <comment>Copyright (C) 2008 by Jonathan Woithe 4 Copyright (C) 2005-2008 by Pieter Palmers 5 6 This file is part of FFADO 7 FFADO = Free Firewire (pro-)audio drivers for linux 8 9 FFADO is based upon FreeBoB. 10 11 This program is free software: you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation, either version 2 of the License, or 14 (at your option) version 3 of the License. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 20 </comment> 21 21 <widget class="QWidget"> … … 27 27 <x>0</x> 28 28 <y>0</y> 29 <width> 800</width>30 <height> 750</height>29 <width>1004</width> 30 <height>693</height> 31 31 </rect> 32 32 </property> 33 <property name="sizePolicy">34 <sizepolicy>35 <hsizetype>0</hsizetype>36 <vsizetype>0</vsizetype>37 <horstretch>0</horstretch>38 <verstretch>0</verstretch>39 </sizepolicy>40 </property>41 33 <property name="minimumSize"> 42 <size>43 <width>800</width>44 <height>750</height>45 </size>46 </property>47 <property name="sizeIncrement">48 <size>49 <width>0</width>50 <height>0</height>51 </size>52 </property>53 <property name="baseSize">54 34 <size> 55 35 <width>0</width> … … 58 38 </property> 59 39 <property name="caption"> 60 <string> MOTU</string>40 <string>Form1</string> 61 41 </property> 62 < widget class="QGroupBox">42 <hbox> 63 43 <property name="name"> 64 <cstring> groupBox7</cstring>44 <cstring>unnamed</cstring> 65 45 </property> 66 <property name="geometry"> 67 <rect> 68 <x>10</x> 69 <y>470</y> 70 <width>170</width> 71 <height>140</height> 72 </rect> 73 </property> 74 <property name="title"> 75 <string>Output settings</string> 76 </property> 77 <widget class="QLabel"> 46 <widget class="QGroupBox"> 78 47 <property name="name"> 79 <cstring> textLabel1_2_11_3_2</cstring>48 <cstring>settings_pane</cstring> 80 49 </property> 81 <property name="geometry"> 82 <rect> 83 <x>10</x> 84 <y>50</y> 85 <width>90</width> 86 <height>22</height> 87 </rect> 50 <property name="title"> 51 <string>Device settings</string> 88 52 </property> 89 <property name="font"> 90 <font> 91 </font> 92 </property> 93 <property name="text"> 94 <string><qt><small>Phones assign</small></qt></string> 95 </property> 96 <property name="alignment"> 97 <set>WordBreak|AlignCenter</set> 98 </property> 99 </widget> 100 <widget class="QLabel"> 101 <property name="name"> 102 <cstring>textLabel1_2_11_3_2_2_2</cstring> 103 </property> 104 <property name="geometry"> 105 <rect> 106 <x>10</x> 107 <y>110</y> 108 <width>100</width> 109 <height>22</height> 110 </rect> 111 </property> 112 <property name="font"> 113 <font> 114 </font> 115 </property> 116 <property name="text"> 117 <string><qt><small>Optical out mode</small><qt></string> 118 </property> 119 <property name="alignment"> 120 <set>WordBreak|AlignCenter</set> 121 </property> 122 </widget> 123 <widget class="QComboBox"> 124 <item> 125 <property name="text"> 126 <string>Disabled</string> 53 <vbox> 54 <property name="name"> 55 <cstring>unnamed</cstring> 127 56 </property> 128 </item> 129 <item> 130 <property name="text"> 131 <string>Phones</string> 132 </property> 133 </item> 134 <item> 135 <property name="text"> 136 <string>Analog 1-2</string> 137 </property> 138 </item> 139 <item> 140 <property name="text"> 141 <string>Analog 3-4</string> 142 </property> 143 </item> 144 <item> 145 <property name="text"> 146 <string>Analog 5-6</string> 147 </property> 148 </item> 149 <item> 150 <property name="text"> 151 <string>Analog 7-8</string> 152 </property> 153 </item> 154 <item> 155 <property name="text"> 156 <string>AES/EBU</string> 157 </property> 158 </item> 159 <item> 160 <property name="text"> 161 <string>SPDIF</string> 162 </property> 163 </item> 164 <item> 165 <property name="text"> 166 <string>ADAT 1-2</string> 167 </property> 168 </item> 169 <item> 170 <property name="text"> 171 <string>ADAT 3-4</string> 172 </property> 173 </item> 174 <item> 175 <property name="text"> 176 <string>ADAT 5-6</string> 177 </property> 178 </item> 179 <item> 180 <property name="text"> 181 <string>ADAT 7-8</string> 182 </property> 183 </item> 184 <property name="name"> 185 <cstring>phones_src</cstring> 186 </property> 187 <property name="geometry"> 188 <rect> 189 <x>10</x> 190 <y>30</y> 191 <width>90</width> 192 <height>21</height> 193 </rect> 194 </property> 195 <property name="font"> 196 <font> 197 <pointsize>9</pointsize> 198 </font> 199 </property> 200 </widget> 201 <widget class="QComboBox"> 202 <item> 203 <property name="text"> 204 <string>Disabled</string> 205 </property> 206 </item> 207 <item> 208 <property name="text"> 209 <string>ADAT</string> 210 </property> 211 </item> 212 <item> 213 <property name="text"> 214 <string>Toslink</string> 215 </property> 216 </item> 217 <property name="name"> 218 <cstring>optical_out_mode</cstring> 219 </property> 220 <property name="geometry"> 221 <rect> 222 <x>10</x> 223 <y>90</y> 224 <width>90</width> 225 <height>21</height> 226 </rect> 227 </property> 228 <property name="font"> 229 <font> 230 <pointsize>9</pointsize> 231 </font> 232 </property> 233 </widget> 234 </widget> 235 <widget class="QTabWidget"> 236 <property name="name"> 237 <cstring>tabWidget2</cstring> 238 </property> 239 <property name="geometry"> 240 <rect> 241 <x>190</x> 242 <y>10</y> 243 <width>600</width> 244 <height>740</height> 245 </rect> 246 </property> 247 <widget class="QWidget"> 248 <property name="name"> 249 <cstring>tab</cstring> 250