示例#1
0
void AlsaLayer::playback(int maxFrames)
{
    unsigned framesToGet = Manager::instance().getMainBuffer().availableForGet(MainBuffer::DEFAULT_ID);

    // no audio available, play tone or silence
    if (framesToGet <= 0) {
        // FIXME: not thread safe! we only lock the mutex when we get the
        // pointer, we have no guarantee that it will stay safe to use
        AudioLoop *tone = Manager::instance().getTelephoneTone();
        AudioLoop *file_tone = Manager::instance().getTelephoneFile();

        playbackBuff_.setFormat(audioFormat_);
        playbackBuff_.resize(maxFrames);

        if (tone)
            tone->getNext(playbackBuff_, playbackGain_);
        else if (file_tone && !ringtoneHandle_)
            file_tone->getNext(playbackBuff_, playbackGain_);
        else
            playbackBuff_.reset();

        playbackBuff_.interleave(playbackIBuff_);
        write(playbackIBuff_.data(), playbackBuff_.frames(), playbackHandle_);
    } else {
        // play the regular sound samples
        const AudioFormat mainBufferFormat = Manager::instance().getMainBuffer().getInternalAudioFormat();
        const bool resample = audioFormat_.sample_rate != mainBufferFormat.sample_rate;

        double resampleFactor = 1.0;
        unsigned maxNbFramesToGet = maxFrames;

        if (resample) {
            resampleFactor = static_cast<double>(audioFormat_.sample_rate) / mainBufferFormat.sample_rate;
            maxNbFramesToGet = maxFrames / resampleFactor;
        }

        framesToGet = std::min(framesToGet, maxNbFramesToGet);

        playbackBuff_.setFormat(mainBufferFormat);
        playbackBuff_.resize(framesToGet);

        Manager::instance().getMainBuffer().getData(playbackBuff_, MainBuffer::DEFAULT_ID);
        playbackBuff_.applyGain(isPlaybackMuted_ ? 0.0 : playbackGain_);

        if (audioFormat_.nb_channels != mainBufferFormat.nb_channels) {
            playbackBuff_.setChannelNum(audioFormat_.nb_channels, true);
        }
        if (resample) {
            const size_t outFrames = framesToGet * resampleFactor;
            AudioBuffer rsmpl_out(outFrames, audioFormat_);
            resampler_.resample(playbackBuff_, rsmpl_out);
            rsmpl_out.interleave(playbackIBuff_);
            write(playbackIBuff_.data(), outFrames, playbackHandle_);
        } else {
            playbackBuff_.interleave(playbackIBuff_);
            write(playbackIBuff_.data(), framesToGet, playbackHandle_);
        }
    }
}
示例#2
0
void JackLayer::fillWithToneOrRingtone(AudioBuffer &buffer)
{
    buffer.resize(hardwareBufferSize_);
    AudioLoop *tone = Manager::instance().getTelephoneTone();
    AudioLoop *file_tone = Manager::instance().getTelephoneFile();

    // In case of a dtmf, the pointers will be set to nullptr once the dtmf length is
    // reached. For this reason we need to fill audio buffer with zeros if pointer is nullptr
    if (tone) {
        tone->getNext(buffer, playbackGain_);
    } else if (file_tone) {
        file_tone->getNext(buffer, playbackGain_);
    } else {
        buffer.reset();
    }
}