Beispiel #1
0
bool AudioDevOSS::uninit()
{
    QMutexLocker mutexLockeer(&this->m_mutex);

    this->m_deviceFile.close();
    this->m_curCaps = AkAudioCaps();

    return true;
}
Beispiel #2
0
void AudioDeviceElement::resetCaps()
{
    this->m_mutexLib.lock();
    auto preferredFormat = this->m_audioDevice->preferredFormat(this->m_device);
    this->m_mutexLib.unlock();

    auto audioCaps = this->m_device == DUMMY_OUTPUT_DEVICE?
                                AkAudioCaps("audio/x-raw,"
                                            "format=s16,"
                                            "bps=2,"
                                            "channels=2,"
                                            "rate=44100,"
                                            "layout=stereo,"
                                            "align=false"):
                                preferredFormat;

    this->setCaps(audioCaps.toCaps());
}
Beispiel #3
0
void AudioDeviceElement::setDevice(const QString &device)
{
    if (this->m_device == device)
        return;

    this->m_device = device;
    emit this->deviceChanged(device);

    this->m_mutexLib.lock();
    auto preferredFormat = this->m_audioDevice->preferredFormat(device);
    this->m_mutexLib.unlock();

    AkAudioCaps audioCaps = device == DUMMY_OUTPUT_DEVICE?
                                AkAudioCaps("audio/x-raw,"
                                            "format=s16,"
                                            "bps=2,"
                                            "channels=2,"
                                            "rate=44100,"
                                            "layout=stereo,"
                                            "align=false"):
                                preferredFormat;

    this->setCaps(audioCaps.toCaps());
}
Beispiel #4
0
AkAudioCaps AudioDevOSS::deviceCaps(const QString &device, int *fragmentSize) const
{
    QFile pcmFile(QString(device)
                    .remove(QRegExp(":Input$|:Output$")));

    if (!pcmFile.open(device.endsWith(":Input")?
                      QIODevice::ReadOnly: QIODevice::WriteOnly))
        return AkAudioCaps();

    int formats = AFMT_QUERY;

    if (ioctl(pcmFile.handle(), SNDCTL_DSP_GETFMTS, &formats) < 0)
        goto deviceCaps_fail;

    static const QVector<int> preferredFormats = {
        AFMT_S16_NE,
        AFMT_S16_LE,
        AFMT_S16_BE,
        AFMT_U16_LE,
        AFMT_U16_BE,
        AFMT_S8,
        AFMT_U8
    };

    int format;
    format = AFMT_QUERY;

    for (const auto &fmt: preferredFormats)
        if (formats & fmt) {
            format = fmt;

            break;
        }

    if (format == AFMT_QUERY)
        goto deviceCaps_fail;

    if (ioctl(pcmFile.handle(), SNDCTL_DSP_SETFMT, &format) < 0)
        goto deviceCaps_fail;

    int stereo;
    stereo = 1;

    if (ioctl(pcmFile.handle(), SNDCTL_DSP_STEREO, &stereo) < 0)
        goto deviceCaps_fail;

    static const QVector<int> preferredSampleRates {
        48000,
        44100,
        22050,
        11025,
        8000
    };

    int sampleRate;
    sampleRate = 0;

    for (int rate: preferredSampleRates)
        if (ioctl(pcmFile.handle(), SNDCTL_DSP_SPEED, &rate) >= 0){
            sampleRate = rate;

            break;
        }

    if (sampleRate < 1)
        goto deviceCaps_fail;

    int channels;
    channels = stereo? 2: 1;
    AkAudioCaps::SampleFormat sampleFormat;
    sampleFormat = sampleFormats->key(format,
                                      AkAudioCaps::SampleFormat_none);

    if (fragmentSize
        && device.endsWith(":Output")) {
        // Set the buffer to a maximum of 1024 samples.
        int bufferSize;
        bufferSize = BUFFER_SIZE
                     * channels
                     * AkAudioCaps::bitsPerSample(sampleFormat)
                     / 8;

        // Let's try setting the fragmet to just 2 pieces, and the half of the
        // buffer size, for low latency.
        int fragment;
        fragment = (2 << 16) | (bufferSize / 2);
        ioctl(pcmFile.handle(), SNDCTL_DSP_SETFRAGMENT, &fragment);

        // Let's see what OSS did actually set,
        audio_buf_info info;
        ioctl(pcmFile.handle(), SNDCTL_DSP_GETOSPACE, &info);

        *fragmentSize = info.fragsize > 0?
                            ((bufferSize / info.fragsize) << 16) | info.fragsize:
                            0;
    }

    pcmFile.close();

    {
        AkAudioCaps audioCaps;
        audioCaps.isValid() = true;
        audioCaps.format() = sampleFormat;
        audioCaps.bps() = AkAudioCaps::bitsPerSample(audioCaps.format());
        audioCaps.channels() = channels;
        audioCaps.rate() = int(sampleRate);
        audioCaps.layout() = AkAudioCaps::defaultChannelLayout(audioCaps.channels());
        audioCaps.align() = false;

        return audioCaps;
    }

deviceCaps_fail:
    pcmFile.close();

    return AkAudioCaps();
}