Пример #1
0
AudioOutputSettings* AudioOutputNULL::GetOutputSettings(bool /*digital*/)
{
    // Pretend that we support everything
    AudioFormat fmt;
    int rate;
    AudioOutputSettings *settings = new AudioOutputSettings();

    while ((rate = settings->GetNextRate()))
    {
        settings->AddSupportedRate(rate);
    }

    while ((fmt = settings->GetNextFormat()))
    {
        settings->AddSupportedFormat(fmt);
    }

    for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++)
    {
        settings->AddSupportedChannels(channels);
    }

    settings->setPassthrough(-1);   // no passthrough

    return settings;
}
Пример #2
0
AudioOutputSettings* AudioOutputOSS::GetOutputSettings(bool /*digital*/)
{
    AudioOutputSettings *settings = new AudioOutputSettings();

    QByteArray device = main_device.toLatin1();
    audiofd = open(device.constData(), O_WRONLY | O_NONBLOCK);

    AudioFormat fmt;
    int rate, formats = 0;

    if (audiofd < 0)
    {
        VBERRENO(QString("Error opening audio device (%1)").arg(main_device));
        delete settings;
        return NULL;
    }

    while ((rate = settings->GetNextRate()))
    {
        int rate2 = rate;
        if(ioctl(audiofd, SNDCTL_DSP_SPEED, &rate2) >= 0
           && rate2 == rate)
            settings->AddSupportedRate(rate);
    }

    if(ioctl(audiofd, SNDCTL_DSP_GETFMTS, &formats) < 0)
        VBERRENO("Error retrieving formats");
    else
    {
        int ofmt;

        while ((fmt = settings->GetNextFormat()))
        {
            switch (fmt)
            {
                case FORMAT_U8:  ofmt = AFMT_U8;       break;
                case FORMAT_S16: ofmt = AFMT_S16_NE;   break;
                default: continue;
            }

            if (formats & ofmt)
                settings->AddSupportedFormat(fmt);
        }
    }

#if defined(AFMT_AC3)
        // Check if drivers supports AC3
    settings->setPassthrough(((formats & AFMT_AC3) != 0) - 1);
#endif

    for (int i = 1; i <= 2; i++)
    {
        int channel = i;

        if (ioctl(audiofd, SNDCTL_DSP_CHANNELS, &channel) >= 0 &&
            channel == i)
        {
            settings->AddSupportedChannels(i);
        }
    }

    close(audiofd);
    audiofd = -1;

    return settings;
}
Пример #3
0
AudioOutputSettings* AudioOutputALSA::GetOutputSettings(bool passthrough)
{
    snd_pcm_hw_params_t *params;
    snd_pcm_format_t afmt = SND_PCM_FORMAT_UNKNOWN;
    AudioFormat fmt;
    int rate;
    int err;

    AudioOutputSettings *settings = new AudioOutputSettings();

    if (pcm_handle)
    {
        snd_pcm_close(pcm_handle);
        pcm_handle = NULL;
    }

    if ((err = TryOpenDevice(OPEN_FLAGS, passthrough)) < 0)
    {
        AERROR(QString("snd_pcm_open(\"%1\")").arg(m_lastdevice));
        delete settings;
        return NULL;
    }

    snd_pcm_hw_params_alloca(&params);

    if ((err = snd_pcm_hw_params_any(pcm_handle, params)) < 0)
    {
        snd_pcm_close(pcm_handle);
        if ((err = TryOpenDevice(OPEN_FLAGS&FILTER_FLAGS, passthrough)) < 0)
        {
            AERROR(QString("snd_pcm_open(\"%1\")").arg(m_lastdevice));
            delete settings;
            return NULL;
        }
        if ((err = snd_pcm_hw_params_any(pcm_handle, params)) < 0)
        {
            AERROR("No playback configurations available");
            snd_pcm_close(pcm_handle);
            pcm_handle = NULL;
            delete settings;
            return NULL;
        }
        Warn("Supported audio format detection will be inacurrate "
             "(using plugin?)");
    }

    while ((rate = settings->GetNextRate()))
        if(snd_pcm_hw_params_test_rate(pcm_handle, params, rate, 0) >= 0)
            settings->AddSupportedRate(rate);

    while ((fmt = settings->GetNextFormat()))
    {
        switch (fmt)
        {
            case FORMAT_U8:  afmt = SND_PCM_FORMAT_U8;    break;
            case FORMAT_S16: afmt = SND_PCM_FORMAT_S16;   break;
            case FORMAT_S24: afmt = SND_PCM_FORMAT_S24;   break;
            case FORMAT_S32: afmt = SND_PCM_FORMAT_S32;   break;
            case FORMAT_FLT: afmt = SND_PCM_FORMAT_FLOAT; break;
            default:         continue;
        }
        if (snd_pcm_hw_params_test_format(pcm_handle, params, afmt) >= 0)
            settings->AddSupportedFormat(fmt);
    }

    for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++)
        if (snd_pcm_hw_params_test_channels(pcm_handle, params, channels) >= 0)
            settings->AddSupportedChannels(channels);

    snd_pcm_close(pcm_handle);
    pcm_handle = NULL;

    /* Check if name or description contains information
       to know if device can accept passthrough or not */
    QMap<QString, QString> *alsadevs = GetALSADevices("pcm");
    while(1)
    {
        QString real_device = (((passthru || enc) && m_discretedigital) ?
                               passthru_device : main_device);

        QString desc = alsadevs->value(real_device);

        settings->setPassthrough(1);   // yes passthrough
        if (real_device.contains("digital", Qt::CaseInsensitive) ||
            desc.contains("digital", Qt::CaseInsensitive))
            break;
        if (real_device.contains("iec958", Qt::CaseInsensitive))
            break;
        if (real_device.contains("spdif", Qt::CaseInsensitive))
            break;
        if (real_device.contains("hdmi", Qt::CaseInsensitive))
            break;

        settings->setPassthrough(-1);   // no passthrough
        // PulseAudio does not support passthrough
        if (real_device.contains("pulse", Qt::CaseInsensitive) ||
            desc.contains("pulse", Qt::CaseInsensitive))
            break;
        if (real_device.contains("analog", Qt::CaseInsensitive) ||
            desc.contains("analog", Qt::CaseInsensitive))
            break;
        if (real_device.contains("surround", Qt::CaseInsensitive) ||
            desc.contains("surround", Qt::CaseInsensitive))
            break;

        settings->setPassthrough(0);   // maybe passthrough
        break;
    }
    delete alsadevs;
    return settings;
}