예제 #1
0
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());
}
예제 #2
0
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());
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
    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);
                    }
                }
            }
        }
    }
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}