예제 #1
0
파일: engine.cpp 프로젝트: jimtendo/darcoi
void Engine::audioNotify()
{
    switch (m_mode) {
    case QAudio::AudioInput: {
            const qint64 recordPosition = qMin(m_bufferLength, audioLength(m_format, m_audioInput->processedUSecs()));
            setRecordPosition(recordPosition);
            const qint64 levelPosition = m_dataLength - m_levelBufferLength;
            if (levelPosition >= 0)
                calculateLevel(levelPosition, m_levelBufferLength);
            if (m_dataLength >= m_spectrumBufferLength) {
                const qint64 spectrumPosition = m_dataLength - m_spectrumBufferLength;
                calculateSpectrum(spectrumPosition);
            }
            emit bufferChanged(0, m_dataLength, m_buffer);
        }
        break;
    case QAudio::AudioOutput: {
            const qint64 playPosition = audioLength(m_format, m_audioOutput->processedUSecs());
            setPlayPosition(qMin(bufferLength(), playPosition));
            const qint64 levelPosition = playPosition - m_levelBufferLength;
            const qint64 spectrumPosition = playPosition - m_spectrumBufferLength;
            if (m_file) {
                if (levelPosition > m_bufferPosition ||
                    spectrumPosition > m_bufferPosition ||
                    qMax(m_levelBufferLength, m_spectrumBufferLength) > m_dataLength) {
                    m_bufferPosition = 0;
                    m_dataLength = 0;
                    // Data needs to be read into m_buffer in order to be analysed
                    const qint64 readPos = qMax(qint64(0), qMin(levelPosition, spectrumPosition));
                    const qint64 readEnd = qMin(m_analysisFile->size(), qMax(levelPosition + m_levelBufferLength, spectrumPosition + m_spectrumBufferLength));
                    const qint64 readLen = readEnd - readPos + audioLength(m_format, WaveformWindowDuration);
                    qDebug() << "Engine::audioNotify [1]"
                             << "analysisFileSize" << m_analysisFile->size()
                             << "readPos" << readPos
                             << "readLen" << readLen;
                    if (m_analysisFile->seek(readPos + m_analysisFile->headerLength())) {
                        m_buffer.resize(readLen);
                        m_bufferPosition = readPos;
                        m_dataLength = m_analysisFile->read(m_buffer.data(), readLen);
                        qDebug() << "Engine::audioNotify [2]" << "bufferPosition" << m_bufferPosition << "dataLength" << m_dataLength;
                    } else {
                        qDebug() << "Engine::audioNotify [2]" << "file seek error";
                    }
                    emit bufferChanged(m_bufferPosition, m_dataLength, m_buffer);
                }
            } else {
                if (playPosition >= m_dataLength)
                    stopPlayback();
            }
            if (levelPosition >= 0 && levelPosition + m_levelBufferLength < m_bufferPosition + m_dataLength)
                calculateLevel(levelPosition, m_levelBufferLength);
            if (spectrumPosition >= 0 && spectrumPosition + m_spectrumBufferLength < m_bufferPosition + m_dataLength)
                calculateSpectrum(spectrumPosition);
        }
        break;
    }
}
예제 #2
0
void AudioDevice::init()
{
    // create the format
    m_format.setSampleRate(8000);	// frequency
    m_format.setSampleSize(16);	// bits
    m_format.setSampleType(QAudioFormat::SignedInt);
    m_format.setChannelCount(1);
    m_format.setByteOrder(QAudioFormat::LittleEndian);
    m_format.setCodec("audio/pcm");

    // choose audio device
    QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
    if (!info.isFormatSupported(m_format)) {
        qWarning() << "format not supported, choosing default";
        m_format = info.nearestFormat(m_format);
    }

    // set buffer size
    const qint64 bufferDurationUs = 1 * 1000000;	// 5 seconds
    m_bufferSize = audioLength(m_format, bufferDurationUs);

    m_buffer = new QByteArray(m_bufferSize, 0);
    m_buffer->fill(0);

    m_audioBuffer = new AudioBuffer(m_bufferSize, this);

    iInit(info);
}
예제 #3
0
파일: engine.cpp 프로젝트: jimtendo/darcoi
bool Engine::initialize()
{
    bool result = false;

    QAudioFormat format = m_format;

    if (selectFormat()) {
        if (m_format != format) {
            resetAudioDevices();
            if (m_file) {
                emit bufferLengthChanged(bufferLength());
                emit dataLengthChanged(dataLength());
                emit bufferChanged(0, 0, m_buffer);
                setRecordPosition(bufferLength());
                result = true;
            } else {
                m_bufferLength = audioLength(m_format, BufferDurationUs);
                m_buffer.resize(m_bufferLength);
                m_buffer.fill(0);
                emit bufferLengthChanged(bufferLength());
                if (m_generateTone) {
                    if (0 == m_tone.endFreq) {
                        const qreal nyquist = nyquistFrequency(m_format);
                        m_tone.endFreq = qMin(qreal(SpectrumHighFreq), nyquist);
                    }
                    // Call function defined in utils.h, at global scope
                    ::generateTone(m_tone, m_format, m_buffer);
                    m_dataLength = m_bufferLength;
                    emit dataLengthChanged(dataLength());
                    emit bufferChanged(0, m_dataLength, m_buffer);
                    setRecordPosition(m_bufferLength);
                    result = true;
                } else {
                    emit bufferChanged(0, 0, m_buffer);
                    m_audioInput = new QAudioInput(m_audioInputDevice, m_format, this);
                    m_audioInput->setNotifyInterval(NotifyIntervalMs);
                    result = true;
                }
            }
            m_audioOutput = new QAudioOutput(m_audioOutputDevice, m_format, this);
            m_audioOutput->setNotifyInterval(NotifyIntervalMs);
        }
    } else {
        if (m_file)
            emit errorMessage(tr("Audio format not supported"),
                              formatToString(m_format));
        else if (m_generateTone)
            emit errorMessage(tr("No suitable format found"), "");
        else
            emit errorMessage(tr("No common input / output format found"), "");
    }

    ENGINE_DEBUG << "Engine::initialize" << "m_bufferLength" << m_bufferLength;
    ENGINE_DEBUG << "Engine::initialize" << "m_dataLength" << m_dataLength;
    ENGINE_DEBUG << "Engine::initialize" << "format" << m_format;

    return result;
}
예제 #4
0
void Waveform::initialize(const QAudioFormat &format, qint64 audioBufferSize, qint64 windowDurationUs)
{
    WAVEFORM_DEBUG << "Waveform::initialize"
                   << "audioBufferSize" << audioBufferSize
                   << "windowDurationUs" << windowDurationUs;

    reset();

    m_format = format;

    // Calculate tile size
    m_tileLength = audioBufferSize;

    // Calculate window size
    m_windowLength = audioLength(m_format, windowDurationUs);

    // Calculate number of tiles required
    int nTiles;
    if (m_tileLength > m_windowLength) {
        nTiles = 2;
    } else {
        nTiles = m_windowLength / m_tileLength + 1;
        if (m_windowLength % m_tileLength)
            ++nTiles;
    }

    WAVEFORM_DEBUG << "Waveform::initialize"
                   << "tileLength" << m_tileLength
                   << "windowLength" << m_windowLength
                   << "nTiles" << nTiles;

    m_pixmaps.fill(0, nTiles);
    m_tiles.resize(nTiles);

    createPixmaps(rect().size());

    m_active = true;
}