void Device::showDevice() { unsigned int vendorId = getConfigRom().getNodeVendorId(); unsigned int modelId = getConfigRom().getModelId(); Util::Configuration &c = getDeviceManager().getConfiguration(); Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); debugOutput(DEBUG_LEVEL_VERBOSE, "%s %s at node %d\n", vme.vendor_name.c_str(), vme.model_name.c_str(), getNodeId()); }
void Device::showDevice() { unsigned int vendorId = getConfigRom().getNodeVendorId(); unsigned int modelId = getConfigRom().getModelId(); // This method is really just to aid debugging and can be used to to // print useful identification information to the debug output. Util::Configuration &c = getDeviceManager().getConfiguration(); Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); debugOutput(DEBUG_LEVEL_VERBOSE, "%s %s at node %d\n", vme.vendor_name.c_str(), vme.model_name.c_str(), getNodeId()); }
bool Device::discover() { unsigned int vendorId = getConfigRom().getNodeVendorId(); unsigned int modelId = getConfigRom().getModelId(); Util::Configuration &c = getDeviceManager().getConfiguration(); Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); if (c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB) { debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", vme.vendor_name.c_str(), vme.model_name.c_str()); } else { debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n", getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); } if ( !Unit::discover() ) { debugError( "Could not discover unit\n" ); return false; } if((getAudioSubunit( 0 ) == NULL)) { debugError( "Unit doesn't have an Audio subunit.\n"); return false; } if((getMusicSubunit( 0 ) == NULL)) { debugError( "Unit doesn't have a Music subunit.\n"); return false; } if(!buildMixer()) { debugWarning("Could not build mixer\n"); } // keep track of the config id of this discovery m_last_discovery_config_id = getConfigurationId(); return true; }
bool Device::discover() { unsigned int vendorId = getConfigRom().getNodeVendorId(); unsigned int modelId = getConfigRom().getModelId(); Util::Configuration &c = getDeviceManager().getConfiguration(); Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId ); if (c.isValid(vme) && vme.driver == Util::Configuration::eD_Digidesign) { debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", vme.vendor_name.c_str(), vme.model_name.c_str()); } else { debugWarning("Device '%s %s' unsupported by Digidesign driver (no generic Digidesign support)\n", getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); } // Here you work out what m_digidesign_model should be set to and // set it accordingly. This can then be used by the rest of the driver // whenever one needs to do different things for different interfaces. // // m_digidesign_model = DIGIDESIGN_MODEL_... // // This function should return true if the device is a supported device // or false if not. Presently only the 003 Rack is supported. if (m_digidesign_model != DIGIDESIGN_MODEL_003_RACK) { debugError("Unsupported model\n"); return false; } if (!buildMixer()) { debugWarning("Could not build mixer\n"); } return true; }
void DspDac::prepare() noexcept { shouldPerform(false); m_outputs.clear(); scDspDeviceManager device = getDeviceManager(); sDspContext contxt = getContext(); if(device && !m_channels.empty()) { for(vector<ulong>::size_type i = 0; i < m_channels.size(); i++) { if(m_channels[i] <= device->getNumberOfOutputs()) { sample* out = device->getOutputsSamples(m_channels[i] - 1); if(out) { m_outputs.push_back(device->getOutputsSamples(m_channels[i] - 1)); shouldPerform(true); } } } } }
bool Device::prepare() { signed int mult, bandwidth; signed int freq, init_samplerate; signed int err = 0; unsigned int stat[4]; debugOutput(DEBUG_LEVEL_NORMAL, "Preparing Device...\n" ); // If there is no iso data to send in a given cycle the RMEs simply // don't send anything. This is in contrast to most other interfaces // which at least send an empty packet. As a result the IsoHandler // contains code which detects missing packets as dropped packets. // For RME devices we must turn this test off since missing packets // are in fact to be expected. get1394Service().getIsoHandlerManager().setMissedCyclesOK(true); freq = getSamplingFrequency(); if (freq <= 0) { debugOutput(DEBUG_LEVEL_ERROR, "Can't continue: sampling frequency not set\n"); return false; } mult = freq<68100?1:(freq<136200?2:4); frames_per_packet = getFramesPerPacket(); // The number of active channels depends on sample rate and whether // bandwidth limitation is active. First set up the number of analog // channels (which differs between devices), then add SPDIF channels if // relevant. Finally, the number of channels available from each ADAT // interface depends on sample rate: 0 at 4x, 4 at 2x and 8 at 1x. if (m_rme_model == RME_MODEL_FIREFACE800) num_channels = 10; else num_channels = 8; if (settings->limit_bandwidth != FF_SWPARAM_BWLIMIT_ANALOG_ONLY) num_channels += 2; if (settings->limit_bandwidth==FF_SWPARAM_BWLIMIT_SEND_ALL_CHANNELS) num_channels += (mult==4?0:(mult==2?4:8)); if (m_rme_model==RME_MODEL_FIREFACE800 && settings->limit_bandwidth==FF_SWPARAM_BWLIMIT_SEND_ALL_CHANNELS) num_channels += (mult==4?0:(mult==2?4:8)); // Bandwidth is calculated here. For the moment we assume the device // is connected at S400, so 1 allocation unit is 1 transmitted byte. // There is 25 allocation units of protocol overhead per packet. Each // channel of audio data is sent/received as a 32 bit integer. bandwidth = 25 + num_channels*4*frames_per_packet; // Both the FF400 and FF800 require we allocate a tx iso channel and // then initialise the device. Device status is then read at least once // regardless of which interface is in use. The rx channel is then // allocated for the FF400 or acquired from the device in the case of // the FF800. Even though the FF800 chooses the rx channel it does not // handle the bus-level channel/bandwidth allocation so we must do that // here. if (iso_tx_channel < 0) { iso_tx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth); } if (iso_tx_channel < 0) { debugFatal("Could not allocate iso tx channel\n"); return false; } else { debugOutput(DEBUG_LEVEL_NORMAL, "iso tx channel: %d\n", iso_tx_channel); } // Call this to initialise the device's streaming system and, in the // case of the FF800, obtain the rx iso channel to use. Having that // functionality in resetForStreaming() means it's effectively done // twice when FFADO is first started, but this does no harm. resetForStreaming(); if (err) { if (iso_tx_channel >= 0) get1394Service().freeIsoChannel(iso_tx_channel); if (iso_rx_channel>=0 && m_rme_model==RME_MODEL_FIREFACE400) // The FF800 manages this channel itself. get1394Service().freeIsoChannel(iso_rx_channel); return false; } /* We need to manage the FF400's iso rx channel */ if (m_rme_model == RME_MODEL_FIREFACE400) { iso_rx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth); } if ((stat[1] & SR1_CLOCK_MODE_MASTER) || (stat[0] & SR0_AUTOSYNC_FREQ_MASK)==0 || (stat[0] & SR0_AUTOSYNC_SRC_MASK)==SR0_AUTOSYNC_SRC_NONE) { init_samplerate = dev_config->hardware_freq; } else { init_samplerate = (stat[0] & SR0_STREAMING_FREQ_MASK) * 250; } debugOutput(DEBUG_LEVEL_VERBOSE, "sample rate on start: %d\n", init_samplerate); // get the device specific and/or global SP configuration Util::Configuration &config = getDeviceManager().getConfiguration(); // base value is the config.h value float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; // we can override that globally config.getValueForSetting("streaming.spm.recv_sp_dll_bw", recv_sp_dll_bw); config.getValueForSetting("streaming.spm.xmit_sp_dll_bw", xmit_sp_dll_bw); // or override in the device section config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "recv_sp_dll_bw", recv_sp_dll_bw); config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "xmit_sp_dll_bw", xmit_sp_dll_bw); // Calculate the event size. Each audio channel is allocated 4 bytes in // the data stream. /* FIXME: this will still require fine-tuning, but it's a start */ signed int event_size = num_channels * 4; // Set up receive stream processor, initialise it and set DLL bw m_receiveProcessor = new Streaming::RmeReceiveStreamProcessor(*this, m_rme_model, event_size); m_receiveProcessor->setVerboseLevel(getDebugLevel()); if (!m_receiveProcessor->init()) { debugFatal("Could not initialize receive processor!\n"); return false; } if (!m_receiveProcessor->setDllBandwidth(recv_sp_dll_bw)) { debugFatal("Could not set DLL bandwidth\n"); delete m_receiveProcessor; m_receiveProcessor = NULL; return false; } // Add ports to the processor - TODO std::string id=std::string("dev?"); if (!getOption("id", id)) { debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n"); } addDirPorts(Streaming::Port::E_Capture); /* Now set up the transmit stream processor */ m_transmitProcessor = new Streaming::RmeTransmitStreamProcessor(*this, m_rme_model, event_size); m_transmitProcessor->setVerboseLevel(getDebugLevel()); if (!m_transmitProcessor->init()) { debugFatal("Could not initialise receive processor!\n"); return false; } if (!m_transmitProcessor->setDllBandwidth(xmit_sp_dll_bw)) { debugFatal("Could not set DLL bandwidth\n"); delete m_transmitProcessor; m_transmitProcessor = NULL; return false; } // Other things to be done: // * add ports to transmit stream processor addDirPorts(Streaming::Port::E_Playback); return true; }
bool Device::discover() { signed int i; unsigned int vendorId = getConfigRom().getNodeVendorId(); // See note in Device::probe() about why we use the unit version here. unsigned int unitVersion = getConfigRom().getUnitVersion(); Util::Configuration &c = getDeviceManager().getConfiguration(); Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion ); if (c.isValid(vme) && vme.driver == Util::Configuration::eD_RME) { debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", vme.vendor_name.c_str(), vme.model_name.c_str()); } else { debugWarning("Device '%s %s' unsupported by RME driver (no generic RME support)\n", getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str()); } if (unitVersion == RME_UNITVERSION_FF800) { m_rme_model = RME_MODEL_FIREFACE800; } else if (unitVersion == RME_MODEL_FIREFACE400) { m_rme_model = RME_MODEL_FIREFACE400; } else { debugError("Unsupported model\n"); return false; } // Set up the shared data object for configuration data i = rme_shm_open(&dev_config); if (i == RSO_OPEN_CREATED) { debugOutput( DEBUG_LEVEL_VERBOSE, "New configuration shared data object created\n"); } else if (i == RSO_OPEN_ATTACHED) { debugOutput( DEBUG_LEVEL_VERBOSE, "Attached to existing configuration shared data object\n"); } if (dev_config == NULL) { debugOutput( DEBUG_LEVEL_WARNING, "Could not create/access shared configuration memory object, using process-local storage\n"); memset(&local_dev_config_obj, 0, sizeof(local_dev_config_obj)); dev_config = &local_dev_config_obj; } settings = &dev_config->settings; tco_settings = &dev_config->tco_settings; // If device is FF800, check to see if the TCO is fitted if (m_rme_model == RME_MODEL_FIREFACE800) { dev_config->tco_present = (read_tco(NULL, 0) == 0); } debugOutput(DEBUG_LEVEL_VERBOSE, "TCO present: %s\n", dev_config->tco_present?"yes":"no"); init_hardware(); if (!buildMixer()) { debugWarning("Could not build mixer\n"); } // This is just for testing read_device_flash_settings(NULL); return true; }
bool Device::prepare() { signed int bandwidth; signed int err = 0; debugOutput(DEBUG_LEVEL_NORMAL, "Preparing Device...\n" ); // This method should prepare the device for streaming without actually // turning streaming on. It is mostly used to configure ports which // will ultimately show up as JACK ports - one per audio channel. // Store the number of frames per firewire packet. Depending on the // device protocol this may not need to be stored in a data field of // the object, in which case frames_per_packet could be come a local // variable. frames_per_packet = getFramesPerPacket(); // Similarly, the number of channels might not be needed beyond this // method. In any case, it must be set correctly to permit calculation // of required bus bandwidth. num_channels = 0; // Bus bandwidth is calculated here. We assume the device is an S400 // device, so 1 allocation unit is 1 transmitted byte. There is 25 // allocation units of protocol overhead per packet. The following // expression is correct if each channel of audio data is sent/received // as a 32 bit integer. bandwidth = 25 + num_channels*4*frames_per_packet; // Depending on the device, the onus on reserving bus bandwidth rests // either with the device or this driver. The following code shows // how iso channels can be requested from the IRM and then reserved // with the required amount of bandwidth. if (iso_tx_channel < 0) { iso_tx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth); } if (iso_tx_channel < 0) { debugFatal("Could not allocate iso tx channel\n"); return false; } if (iso_rx_channel < 0) { iso_rx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth); } if (iso_rx_channel < 0) { debugFatal("Could not allocate iso rx channel\n"); err = 1; } if (err) { if (iso_tx_channel >= 0) get1394Service().freeIsoChannel(iso_tx_channel); if (iso_rx_channel >= 0) get1394Service().freeIsoChannel(iso_rx_channel); return false; } // get the device specific and/or global SP configuration Util::Configuration &config = getDeviceManager().getConfiguration(); // base value is the config.h value float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ; // we can override that globally config.getValueForSetting("streaming.spm.recv_sp_dll_bw", recv_sp_dll_bw); config.getValueForSetting("streaming.spm.xmit_sp_dll_bw", xmit_sp_dll_bw); // or override in the device section config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "recv_sp_dll_bw", recv_sp_dll_bw); config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "xmit_sp_dll_bw", xmit_sp_dll_bw); // Calculate the event size. Each audio channel is allocated 4 bytes in // the data stream by the statement which follows. This will need to be // changed to suit the Digidesign interfaces. signed int event_size = num_channels * 4; // Set up receive stream processor, initialise it and set DLL bw m_receiveProcessor = new Streaming::DigidesignReceiveStreamProcessor(*this, event_size); m_receiveProcessor->setVerboseLevel(getDebugLevel()); if (!m_receiveProcessor->init()) { debugFatal("Could not initialize receive processor!\n"); return false; } if (!m_receiveProcessor->setDllBandwidth(recv_sp_dll_bw)) { debugFatal("Could not set DLL bandwidth\n"); delete m_receiveProcessor; m_receiveProcessor = NULL; return false; } // Add ports to the receive stream processor - one port per audio channel // expected from the device. std::string id=std::string("dev?"); // Ports can be added directly in this method. I (Jonathan Woithe) // prefer them in a separate method to keep the prepare() method as // clear as possible. addDirPorts(Streaming::Port::E_Capture); /* Now set up the transmit stream processor */ m_transmitProcessor = new Streaming::DigidesignTransmitStreamProcessor(*this, event_size); m_transmitProcessor->setVerboseLevel(getDebugLevel()); if (!m_transmitProcessor->init()) { debugFatal("Could not initialise receive processor!\n"); return false; } if (!m_transmitProcessor->setDllBandwidth(xmit_sp_dll_bw)) { debugFatal("Could not set DLL bandwidth\n"); delete m_transmitProcessor; m_transmitProcessor = NULL; return false; } // Add ports to the transmit stream processor. This is one port // per audio channel to be sent to the device. addDirPorts(Streaming::Port::E_Playback); return true; }