pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format) { pa_sample_spec spec; spec.rate = format.frequency(); spec.channels = format.channels(); if (format.sampleSize() == 8) { spec.format = PA_SAMPLE_U8; } else if (format.sampleSize() == 16) { switch (format.byteOrder()) { case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S16BE; break; case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S16LE; break; } } else if (format.sampleSize() == 24) { switch (format.byteOrder()) { case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S24BE; break; case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S24LE; break; } } else if (format.sampleSize() == 32) { switch (format.byteOrder()) { case QAudioFormat::BigEndian: format.sampleType() == QAudioFormat::Float ? spec.format = PA_SAMPLE_FLOAT32BE : spec.format = PA_SAMPLE_S32BE; break; case QAudioFormat::LittleEndian: format.sampleType() == QAudioFormat::Float ? spec.format = PA_SAMPLE_FLOAT32LE : spec.format = PA_SAMPLE_S32LE; break; } } else { spec.format = PA_SAMPLE_INVALID; } return spec; }
void tst_QAudioFormat::checkByteOrder() { QAudioFormat audioFormat; audioFormat.setByteOrder(QAudioFormat::LittleEndian); QVERIFY(audioFormat.byteOrder() == QAudioFormat::LittleEndian); audioFormat.setByteOrder(QAudioFormat::BigEndian); QVERIFY(audioFormat.byteOrder() == QAudioFormat::BigEndian); }
void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate) { const int channelBytes = format.sampleSize() / 8;//разрядность const int sampleBytes = format.channelCount() * channelBytes;//количество байт умнож на кол-во каналов qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8)) * durationUs / 1000000; Q_ASSERT(length % sampleBytes == 0); Q_UNUSED(sampleBytes) // suppress warning in release builds m_buffer.resize(length); unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data()); int sampleIndex = 0; while (length) { const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate()); for (int i=0; i<format.channelCount(); ++i) { if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) { const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255); *reinterpret_cast<quint8*>(ptr) = value; } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) { const qint8 value = static_cast<qint8>(x * 127); *reinterpret_cast<quint8*>(ptr) = value; } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) { quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535); if (format.byteOrder() == QAudioFormat::LittleEndian) qToLittleEndian<quint16>(value, ptr); else qToBigEndian<quint16>(value, ptr); } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) { qint16 value = static_cast<qint16>(x * 32767); if (format.byteOrder() == QAudioFormat::LittleEndian) qToLittleEndian<qint16>(value, ptr); else qToBigEndian<qint16>(value, ptr); } ptr += channelBytes;//кол-во каналов length -= channelBytes; } ++sampleIndex; } }
void tst_QAudioFormat::checkByteOrder() { QAudioFormat audioFormat; audioFormat.setByteOrder(QAudioFormat::LittleEndian); QVERIFY(audioFormat.byteOrder() == QAudioFormat::LittleEndian); QTest::ignoreMessage(QtDebugMsg, "LittleEndian"); qDebug() << QAudioFormat::LittleEndian; audioFormat.setByteOrder(QAudioFormat::BigEndian); QVERIFY(audioFormat.byteOrder() == QAudioFormat::BigEndian); QTest::ignoreMessage(QtDebugMsg, "BigEndian"); qDebug() << QAudioFormat::BigEndian; }
bool formatQtToNative(const QAudioFormat &inputFormat, TUint32 &outputFourCC, TMMFCapabilities &outputFormat) { bool result = false; // Need to use temporary variables because TMMFCapabilities fields are all // TInt, rather than MMF enumerated types. TMMFSampleRate outputSampleRate; TMMFMonoStereo outputChannels; TMMFSoundEncoding outputEncoding; if (inputFormat.codec() == "audio/pcm") { result = sampleRateQtToNative(inputFormat.frequency(), outputSampleRate) && channelsQtToNative(inputFormat.channels(), outputChannels) && sampleInfoQtToNative(inputFormat.sampleSize(), inputFormat.byteOrder(), inputFormat.sampleType(), outputFourCC, outputEncoding); } if (result) { outputFormat.iRate = outputSampleRate; outputFormat.iChannels = outputChannels; outputFormat.iEncoding = outputEncoding; } return result; }
ViAudioFormat::ViAudioFormat(const QAudioFormat &other) { if(other.sampleType() == QAudioFormat::SignedInt) { setSampleType(ViAudioFormat::SignedInt); } else if(other.sampleType() == QAudioFormat::UnSignedInt) { setSampleType(ViAudioFormat::UnSignedInt); } else if(other.sampleType() == QAudioFormat::Float) { setSampleType(ViAudioFormat::Float); } else { setSampleSize(ViAudioFormat::Unknown); } if(other.byteOrder() == QAudioFormat::BigEndian) { setByteOrder(ViAudioFormat::BigEndian); } else { setByteOrder(ViAudioFormat::LittleEndian); } mQuality = ViAudioFormat::Average; mSampleSize = other.sampleSize(); mSampleRate = other.sampleRate(); mChannelCount = other.channelCount(); mCodec = NULL; }
AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat) { AudioStreamBasicDescription sf; sf.mFormatFlags = kAudioFormatFlagIsPacked; sf.mSampleRate = audioFormat.frequency(); sf.mFramesPerPacket = 1; sf.mChannelsPerFrame = audioFormat.channels(); sf.mBitsPerChannel = audioFormat.sampleSize(); sf.mBytesPerFrame = sf.mChannelsPerFrame * (sf.mBitsPerChannel / 8); sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame; sf.mFormatID = kAudioFormatLinearPCM; switch (audioFormat.sampleType()) { case QAudioFormat::SignedInt: sf.mFormatFlags |= kAudioFormatFlagIsSignedInteger; break; case QAudioFormat::UnSignedInt: /* default */ break; case QAudioFormat::Float: sf.mFormatFlags |= kAudioFormatFlagIsFloat; break; case QAudioFormat::Unknown: default: break; } if (audioFormat.byteOrder() == QAudioFormat::BigEndian) sf.mFormatFlags |= kAudioFormatFlagIsBigEndian; return sf; }
bool isPCMS16LE(const QAudioFormat &format) { return isPCM(format) && format.sampleType() == QAudioFormat::SignedInt && format.sampleSize() == 16 && format.byteOrder() == QAudioFormat::LittleEndian; }
bool WaveFileWriter::writeHeader(const QAudioFormat &format) { // check if format is supported if (format.byteOrder() == QAudioFormat::BigEndian || format.sampleType() != QAudioFormat::SignedInt) return false; CombinedHeader header; memset(&header, 0, HeaderLength); #ifndef Q_LITTLE_ENDIAN // only implemented for LITTLE ENDIAN return false; #else // RIFF header memcpy(header.riff.descriptor.id, "RIFF", 4); header.riff.descriptor.size = 0; // this will be updated with correct duration: // m_dataLength + HeaderLength - 8 // WAVE header memcpy(header.riff.type, "WAVE", 4); memcpy(header.wave.descriptor.id, "fmt ", 4); header.wave.descriptor.size = quint32(16); header.wave.audioFormat = quint16(1); header.wave.numChannels = quint16(format.channelCount()); header.wave.sampleRate = quint32(format.sampleRate()); header.wave.byteRate = quint32(format.sampleRate() * format.channelCount() * format.sampleSize() / 8); header.wave.blockAlign = quint16(format.channelCount() * format.sampleSize() / 8); header.wave.bitsPerSample = quint16(format.sampleSize()); // DATA header memcpy(header.data.descriptor.id,"data", 4); header.data.descriptor.size = 0; // this will be updated with correct data length: m_dataLength return (file.write(reinterpret_cast<const char *>(&header), HeaderLength) == HeaderLength); #endif }
void tst_QWaveDecoder::file() { QFETCH(QString, file); QFETCH(tst_QWaveDecoder::Corruption, corruption); QFETCH(int, channels); QFETCH(int, samplesize); QFETCH(int, samplerate); QFETCH(QAudioFormat::Endian, byteorder); QFile stream; stream.setFileName(file); stream.open(QIODevice::ReadOnly); QVERIFY(stream.isOpen()); QWaveDecoder waveDecoder(&stream); QSignalSpy validFormatSpy(&waveDecoder, SIGNAL(formatKnown())); QSignalSpy parsingErrorSpy(&waveDecoder, SIGNAL(parsingError())); if (corruption == NotAWav) { QSKIP("Not all failures detected correctly yet"); QTRY_COMPARE(parsingErrorSpy.count(), 1); QCOMPARE(validFormatSpy.count(), 0); } else if (corruption == NoSampleData) { QTRY_COMPARE(validFormatSpy.count(), 1); QCOMPARE(parsingErrorSpy.count(), 0); QVERIFY(waveDecoder.audioFormat().isValid()); QVERIFY(waveDecoder.size() == 0); QVERIFY(waveDecoder.duration() == 0); } else if (corruption == FormatDescriptor) { QTRY_COMPARE(parsingErrorSpy.count(), 1); QCOMPARE(validFormatSpy.count(), 0); } else if (corruption == FormatString) { QTRY_COMPARE(parsingErrorSpy.count(), 1); QCOMPARE(validFormatSpy.count(), 0); QVERIFY(!waveDecoder.audioFormat().isValid()); } else if (corruption == DataDescriptor) { QTRY_COMPARE(parsingErrorSpy.count(), 1); QCOMPARE(validFormatSpy.count(), 0); QVERIFY(waveDecoder.size() == 0); } else if (corruption == None) { QTRY_COMPARE(validFormatSpy.count(), 1); QCOMPARE(parsingErrorSpy.count(), 0); QVERIFY(waveDecoder.audioFormat().isValid()); QVERIFY(waveDecoder.size() > 0); QVERIFY(waveDecoder.duration() == 250); QAudioFormat format = waveDecoder.audioFormat(); QVERIFY(format.isValid()); QVERIFY(format.channelCount() == channels); QVERIFY(format.sampleSize() == samplesize); QVERIFY(format.sampleRate() == samplerate); if (format.sampleSize() != 8) { QVERIFY(format.byteOrder() == byteorder); } } stream.close(); }
void Generator::generateData(const QAudioFormat& format, unsigned char* ptr, qint64 length) { const int channelBytes = format.sampleSize() / 8; if (length <= 0) return; QMutexLocker lock(m_mutex); QVector<qreal> channels; channels.resize(2); // LOG_INFO() << "generating Sounds" << QDateTime::currentDateTime() << length; initializeSounds(); while (length) { generateTone(channels[0], channels[1], m_sampleIndex); //const qreal x = soundFunc(2 * M_PI * frequency * qreal(sampleIndex ) / format.sampleRate()); for (int i=0; i<format.channelCount(); ++i) { if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) { const quint8 value = static_cast<quint8>((1.0 + channels[i]) / 2 * 255); *reinterpret_cast<quint8*>(ptr) = value; } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) { const qint8 value = static_cast<qint8>(channels[i] * 127); *reinterpret_cast<quint8*>(ptr) = value; } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) { quint16 value = static_cast<quint16>((1.0 + channels[i]) / 2 * 65535); if (format.byteOrder() == QAudioFormat::LittleEndian) qToLittleEndian<quint16>(value, ptr); else qToBigEndian<quint16>(value, ptr); } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) { qint16 value = static_cast<qint16>(channels[i] * 32767); if (format.byteOrder() == QAudioFormat::LittleEndian) qToLittleEndian<qint16>(value, ptr); else qToBigEndian<qint16>(value, ptr); } ptr += channelBytes; length -= channelBytes; } ++m_sampleIndex; } }
void TSoundOutputDeviceImp::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1, bool loop, bool scrubbing) { if (!doSetStreamFormat(st->getFormat())) return; MyData *myData = new MyData(); myData->imp = shared_from_this(); myData->totalPacketCount = s1 - s0; myData->fileByteCount = (s1 - s0) * st->getSampleSize(); myData->entireFileBuffer = new char[myData->fileByteCount]; memcpy(myData->entireFileBuffer, st->getRawData() + s0 * st->getSampleSize(), myData->fileByteCount); m_isPlaying = true; myData->isLooping = loop; QAudioFormat format; QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); format.setSampleSize(st->getBitPerSample()); format.setCodec("audio/pcm"); format.setChannelCount(st->getChannelCount()); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(st->getFormat().m_signedSample ? QAudioFormat::SignedInt : QAudioFormat::UnSignedInt); format.setSampleRate(st->getSampleRate()); QList<QAudioFormat::Endian> sbos = info.supportedByteOrders(); QList<int> sccs = info.supportedChannelCounts(); QList<int> ssrs = info.supportedSampleRates(); QList<QAudioFormat::SampleType> sstypes = info.supportedSampleTypes(); QList<int> ssss = info.supportedSampleSizes(); QStringList supCodes = info.supportedCodecs(); if (!info.isFormatSupported((format))) { format = info.nearestFormat(format); int newChannels = format.channelCount(); int newBitsPerSample = format.sampleSize(); int newSampleRate = format.sampleRate(); QAudioFormat::SampleType newSampleType = format.sampleType(); QAudioFormat::Endian newBo = format.byteOrder(); } int test = st->getSampleCount() / st->getSampleRate(); QByteArray *data = new QByteArray(myData->entireFileBuffer, myData->fileByteCount); QBuffer *newBuffer = new QBuffer; newBuffer->setBuffer(data); newBuffer->open(QIODevice::ReadOnly); newBuffer->seek(0); if (m_audioOutput == NULL) { m_audioOutput = new QAudioOutput(format, NULL); } m_audioOutput->start(newBuffer); m_audioOutput->setVolume(m_volume); }
QDebug operator<<(QDebug dbg, const QAudioFormat &f) { dbg.nospace() << "QAudioFormat(" << f.sampleRate(); dbg.nospace() << "Hz, " << f.sampleSize(); dbg.nospace() << "bit, channelCount=" << f.channelCount(); dbg.nospace() << ", sampleType=" << f.sampleType(); dbg.nospace() << ", byteOrder=" << f.byteOrder(); dbg.nospace() << ", codec=" << f.codec(); dbg.nospace() << ")"; return dbg.space(); }
bool QAudioDeviceInfoInternal::isFormatSupported( const QAudioFormat &format) const { getSupportedFormats(); const bool supported = m_codecs.contains(format.codec()) && m_frequencies.contains(format.frequency()) && m_channels.contains(format.channels()) && m_sampleSizes.contains(format.sampleSize()) && m_byteOrders.contains(format.byteOrder()) && m_sampleTypes.contains(format.sampleType()); return supported; }
QString formatToString(const QAudioFormat &format) { QString result; if (QAudioFormat() != format) { if (format.codec() == "audio/pcm") { Q_ASSERT(format.sampleType() == QAudioFormat::SignedInt); const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian) ? QString("LE") : QString("BE"); QString formatType; switch (format.sampleType()) { case QAudioFormat::SignedInt: formatType = "signed"; break; case QAudioFormat::UnSignedInt: formatType = "unsigned"; break; case QAudioFormat::Float: formatType = "float"; break; case QAudioFormat::Unknown: formatType = "unknown"; break; } QString formatChannels = QString("%1 channels").arg(format.channelCount()); switch (format.channelCount()) { case 1: formatChannels = "mono"; break; case 2: formatChannels = "stereo"; break; } result = QString("%1 Hz %2 bit %3 %4 %5") .arg(format.sampleRate()) .arg(format.sampleSize()) .arg(formatType) .arg(formatEndian) .arg(formatChannels); } else { result = format.codec(); } } return result; }
QT_BEGIN_NAMESPACE // Debugging QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat) { dbg.nospace() << "QAudioFormat(" << audioFormat.frequency() << "," << audioFormat.channels() << "," << audioFormat.sampleSize()<< "," << audioFormat.codec() << "," << audioFormat.byteOrder() << "," << audioFormat.sampleType() << ")"; return dbg.space(); }
bool QAudioDeviceInfoInternal::isFormatSupported( const QAudioFormat &format) const { getSupportedFormats(); bool supported = false; if (m_capabilities.contains(format.codec())) { const Capabilities &codecCaps = m_capabilities[format.codec()]; supported = codecCaps.m_frequencies.contains(format.frequency()) && codecCaps.m_channels.contains(format.channels()) && codecCaps.m_sampleSizes.contains(format.sampleSize()) && codecCaps.m_byteOrders.contains(format.byteOrder()) && codecCaps.m_sampleTypes.contains(format.sampleType()); } return supported; }
void AudioTest::test() { // tries to set all the settings picked. logOutput->clear(); logOutput->append("NOTE: an invalid codec audio/test exists for testing, to get a fail condition."); if (!deviceInfo.isNull()) { if (deviceInfo.isFormatSupported(settings)) { logOutput->append(tr("Success")); nearestFreq->setText(""); nearestChannel->setText(""); nearestCodec->setText(""); nearestSampleSize->setText(""); nearestSampleType->setText(""); nearestEndian->setText(""); } else { QAudioFormat nearest = deviceInfo.nearestFormat(settings); logOutput->append(tr("Failed")); nearestFreq->setText(QString("%1").arg(nearest.frequency())); nearestChannel->setText(QString("%1").arg(nearest.channels())); nearestCodec->setText(nearest.codec()); nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize())); switch(nearest.sampleType()) { case QAudioFormat::SignedInt: nearestSampleType->setText("SignedInt"); break; case QAudioFormat::UnSignedInt: nearestSampleType->setText("UnSignedInt"); break; case QAudioFormat::Float: nearestSampleType->setText("Float"); break; case QAudioFormat::Unknown: nearestSampleType->setText("Unknown"); } switch(nearest.byteOrder()) { case QAudioFormat::LittleEndian: nearestEndian->setText("LittleEndian"); break; case QAudioFormat::BigEndian: nearestEndian->setText("BigEndian"); } } } else logOutput->append(tr("No Device")); }
/*! Returns the closest QAudioFormat to the supplied \a settings that the system supports. These settings are provided by the platform/audio plugin being used. They are also dependent on the \l {QAudio}::Mode being used. */ QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const { if (isFormatSupported(settings)) return settings; QAudioFormat nearest = settings; QList<QString> testCodecs = supportedCodecs(); QList<int> testChannels = supportedChannelCounts(); QList<QAudioFormat::Endian> testByteOrders = supportedByteOrders(); QList<QAudioFormat::SampleType> testSampleTypes; QList<QAudioFormat::SampleType> sampleTypesAvailable = supportedSampleTypes(); QMap<int,int> testSampleRates; QList<int> sampleRatesAvailable = supportedSampleRates(); QMap<int,int> testSampleSizes; QList<int> sampleSizesAvailable = supportedSampleSizes(); // Get sorted lists for checking if (testCodecs.contains(settings.codec())) { testCodecs.removeAll(settings.codec()); testCodecs.insert(0, settings.codec()); } testChannels.removeAll(settings.channelCount()); testChannels.insert(0, settings.channelCount()); testByteOrders.removeAll(settings.byteOrder()); testByteOrders.insert(0, settings.byteOrder()); if (sampleTypesAvailable.contains(settings.sampleType())) testSampleTypes.append(settings.sampleType()); if (sampleTypesAvailable.contains(QAudioFormat::SignedInt)) testSampleTypes.append(QAudioFormat::SignedInt); if (sampleTypesAvailable.contains(QAudioFormat::UnSignedInt)) testSampleTypes.append(QAudioFormat::UnSignedInt); if (sampleTypesAvailable.contains(QAudioFormat::Float)) testSampleTypes.append(QAudioFormat::Float); if (sampleSizesAvailable.contains(settings.sampleSize())) testSampleSizes.insert(0,settings.sampleSize()); sampleSizesAvailable.removeAll(settings.sampleSize()); foreach (int size, sampleSizesAvailable) { int larger = (size > settings.sampleSize()) ? size : settings.sampleSize(); int smaller = (size > settings.sampleSize()) ? settings.sampleSize() : size; bool isMultiple = ( 0 == (larger % smaller)); int diff = larger - smaller; testSampleSizes.insert((isMultiple ? diff : diff+100000), size); }
SLDataFormat_PCM QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudioFormat &format) { SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = format.channelCount(); format_pcm.samplesPerSec = format.sampleRate() * 1000; format_pcm.bitsPerSample = format.sampleSize(); format_pcm.containerSize = format.sampleSize(); format_pcm.channelMask = (format.channelCount() == 1 ? SL_SPEAKER_FRONT_CENTER : SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT); format_pcm.endianness = (format.byteOrder() == QAudioFormat::LittleEndian ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN); return format_pcm; }
bool QAlsaAudioDeviceInfo::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). int err = -1; snd_pcm_t* pcmHandle; snd_pcm_hw_params_t *params; QString dev; #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = device; if (dev.compare(QLatin1String("default")) == 0) { QList<QByteArray> devices = availableDevices(QAudio::AudioOutput); if (!devices.isEmpty()) dev = QLatin1String(devices.first().constData()); } #else if (dev.compare(QLatin1String("default")) == 0) { dev = QLatin1String("hw:0,0"); } else { int idx = 0; char *name; QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1); while(snd_card_get_name(idx,&name) == 0) { if(shortName.compare(QLatin1String(name)) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); } #endif snd_pcm_stream_t stream = mode == QAudio::AudioOutput ? SND_PCM_STREAM_PLAYBACK : SND_PCM_STREAM_CAPTURE; if (snd_pcm_open(&pcmHandle, dev.toLocal8Bit().constData(), stream, 0) < 0) return false; snd_pcm_nonblock(pcmHandle, 0); snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(pcmHandle, params); // set the values! snd_pcm_hw_params_set_channels(pcmHandle, params, format.channelCount()); snd_pcm_hw_params_set_rate(pcmHandle, params, format.sampleRate(), 0); snd_pcm_format_t pcmFormat = SND_PCM_FORMAT_UNKNOWN; switch (format.sampleSize()) { case 8: if (format.sampleType() == QAudioFormat::SignedInt) pcmFormat = SND_PCM_FORMAT_S8; else if (format.sampleType() == QAudioFormat::UnSignedInt) pcmFormat = SND_PCM_FORMAT_U8; break; case 16: if (format.sampleType() == QAudioFormat::SignedInt) { pcmFormat = format.byteOrder() == QAudioFormat::LittleEndian ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_S16_BE; } else if (format.sampleType() == QAudioFormat::UnSignedInt) { pcmFormat = format.byteOrder() == QAudioFormat::LittleEndian ? SND_PCM_FORMAT_U16_LE : SND_PCM_FORMAT_U16_BE; } break; case 32: if (format.sampleType() == QAudioFormat::SignedInt) { pcmFormat = format.byteOrder() == QAudioFormat::LittleEndian ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_S32_BE; } else if (format.sampleType() == QAudioFormat::UnSignedInt) { pcmFormat = format.byteOrder() == QAudioFormat::LittleEndian ? SND_PCM_FORMAT_U32_LE : SND_PCM_FORMAT_U32_BE; } else if (format.sampleType() == QAudioFormat::Float) { pcmFormat = format.byteOrder() == QAudioFormat::LittleEndian ? SND_PCM_FORMAT_FLOAT_LE : SND_PCM_FORMAT_FLOAT_BE; } } if (pcmFormat != SND_PCM_FORMAT_UNKNOWN) err = snd_pcm_hw_params_set_format(pcmHandle, params, pcmFormat); // For now, just accept only audio/pcm codec if (!format.codec().startsWith(QLatin1String("audio/pcm"))) err = -1; if (err >= 0 && format.channelCount() != -1) { err = snd_pcm_hw_params_test_channels(pcmHandle, params, format.channelCount()); if (err >= 0) err = snd_pcm_hw_params_set_channels(pcmHandle, params, format.channelCount()); } if (err >= 0 && format.sampleRate() != -1) { err = snd_pcm_hw_params_test_rate(pcmHandle, params, format.sampleRate(), 0); if (err >= 0) err = snd_pcm_hw_params_set_rate(pcmHandle, params, format.sampleRate(), 0); } if (err >= 0 && pcmFormat != SND_PCM_FORMAT_UNKNOWN) err = snd_pcm_hw_params_set_format(pcmHandle, params, pcmFormat); if (err >= 0) err = snd_pcm_hw_params(pcmHandle, params); snd_pcm_close(pcmHandle); return (err == 0); }
void MainWindow::adjustSettings() { QAudioFormat inputFormat = m_audio_lib->inputAudioFormat(); QAudioFormat format = m_audio_lib->audioFormat(); QString str; str.append("Input format:\n\n"); str.append(QString("Sample size: %0 bits\n").arg(inputFormat.sampleSize())); str.append(QString("Sample rate: %0 hz\n").arg(inputFormat.sampleRate())); str.append(QString("Channels: %0\n").arg(inputFormat.channelCount())); str.append(QString("Sample type: %0\n").arg((inputFormat.sampleType() == QAudioFormat::Float) ? "Float" : "Integer")); str.append(QString("Byte order: %0\n").arg((inputFormat.byteOrder() == QAudioFormat::LittleEndian) ? "Little endian" : "Big endian")); str.append("\n"); str.append("Resampled format:\n\n"); str.append(QString("Sample size: %0 bits\n").arg(format.sampleSize())); str.append(QString("Sample rate: %0 hz\n").arg(format.sampleRate())); str.append(QString("Channels: %0\n").arg(format.channelCount())); str.append(QString("Sample type: %0\n").arg((format.sampleType() == QAudioFormat::Float) ? "Float" : "Integer")); str.append(QString("Byte order: %0").arg((format.byteOrder() == QAudioFormat::LittleEndian) ? "Little endian" : "Big endian")); str.append("\n\n"); str.append("Eigen instructions set:\n"); str.append(AudioStreamingLibCore::EigenInstructionsSet()); texteditsettings->setPlainText(str); if (!m_spectrum_analyzer) { m_spectrum_analyzer = new SpectrumAnalyzer(); QThread *thread = new QThread(); m_spectrum_analyzer->moveToThread(thread); connect(m_audio_lib, &AudioStreamingLibCore::veryInputData, m_spectrum_analyzer, &SpectrumAnalyzer::calculateSpectrum); connect(m_spectrum_analyzer, &SpectrumAnalyzer::spectrumChanged, bars, &BarsWidget::setValues); connect(m_spectrum_analyzer, &SpectrumAnalyzer::destroyed, bars, &BarsWidget::clear); connect(m_audio_lib, &AudioStreamingLibCore::finished, m_spectrum_analyzer, &SpectrumAnalyzer::deleteLater); connect(this, &MainWindow::destroyed, m_spectrum_analyzer, &SpectrumAnalyzer::deleteLater); connect(m_spectrum_analyzer, &SpectrumAnalyzer::destroyed, thread, &QThread::quit); connect(thread, &QThread::finished, thread, &QThread::deleteLater); QMetaObject::invokeMethod(m_spectrum_analyzer, "start", Qt::QueuedConnection, Q_ARG(QAudioFormat, format)); thread->start(); } { waveform->start(format); connect(m_audio_lib, &AudioStreamingLibCore::veryInputData, waveform, &WaveFormWidget::calculateWaveForm); connect(m_audio_lib, &AudioStreamingLibCore::finished, waveform, &WaveFormWidget::clear); } { connect(m_audio_lib, &AudioStreamingLibCore::veryInputData, level, &LevelWidget::calculateRMSLevel); } }
void QOggSimplePlayer::open() { QMutexLocker mutexLocker(&mutex); if(!QFile(filePath).exists()) return; QAudioFormat format; format.setSampleRate(48000); format.setChannelCount(1); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); int returnCode=ov_fopen(QDir::toNativeSeparators(filePath).toLocal8Bit().data(), &vf); if(returnCode < 0) { qDebug() << "Input does not appear to be an Ogg bitstream for " << QDir::toNativeSeparators(filePath) << ", return code: " << returnCode; ov_clear(&vf); return; } { char **ptr=ov_comment(&vf,-1)->user_comments; vorbis_info *vi=ov_info(&vf,-1); while(*ptr){ fprintf(stderr,"%s\n",*ptr); ++ptr; } qDebug() << QString("Bitstream is %1 channel, %2Hz").arg(vi->channels).arg(vi->rate); qDebug() << QString("Encoded by: %1").arg(ov_comment(&vf,-1)->vendor); qDebug() << QString("Play on: %1").arg(QAudioDeviceInfo::defaultOutputDevice().deviceName()); format.setChannelCount(vi->channels); format.setSampleRate(vi->rate); } if(format.channelCount()!=1) { qDebug() << "Only mono sound is supported due to a bug"; ov_clear(&vf); return; } QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); if (!info.isFormatSupported(format)) { qDebug() << QString("raw audio format not supported by backend, cannot play audio: SampleRate: %1, ChannelCount: %2, SampleSize: %3, Codec: %4, ByteOrder: %5, SampleType: %6") .arg(format.sampleRate()) .arg(format.channelCount()) .arg(format.sampleSize()) .arg(format.codec()) .arg(format.byteOrder()) .arg(format.sampleType()) ; QAudioFormat preferedFormat=info.preferredFormat(); qDebug() << QString("prefered format: SampleRate: %1, ChannelCount: %2, SampleSize: %3, Codec: %4, ByteOrder: %5, SampleType: %6") .arg(preferedFormat.sampleRate()) .arg(preferedFormat.channelCount()) .arg(preferedFormat.sampleSize()) .arg(preferedFormat.codec()) .arg(preferedFormat.byteOrder()) .arg(preferedFormat.sampleType()) ; QAudioFormat nearestFormat=info.nearestFormat(format); qDebug() << QString("nearest format: SampleRate: %1, ChannelCount: %2, SampleSize: %3, Codec: %4, ByteOrder: %5, SampleType: %6") .arg(nearestFormat.sampleRate()) .arg(nearestFormat.channelCount()) .arg(nearestFormat.sampleSize()) .arg(nearestFormat.codec()) .arg(nearestFormat.byteOrder()) .arg(nearestFormat.sampleType()) ; ov_clear(&vf); return; } if(output!=NULL) delete output; output = new QAudioOutput(format); output->setVolume(volume); output->setBufferSize(4096); connect(output,&QAudioOutput::stateChanged,this,&QOggSimplePlayer::finishedPlaying,Qt::QueuedConnection); if(needPlay) start(); }
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). int err = 0; snd_pcm_t* handle; snd_pcm_hw_params_t *params; QString dev = device; QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = QLatin1String(devices.first().constData()); #else dev = QLatin1String("hw:0,0"); #endif } else { #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) dev = device; #else int idx = 0; char *name; QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1); while(snd_card_get_name(idx,&name) == 0) { if(shortName.compare(QLatin1String(name)) == 0) break; idx++; } dev = QString(QLatin1String("hw:%1,0")).arg(idx); #endif } if(mode == QAudio::AudioOutput) { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); } else { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); } if(err < 0) { handle = 0; return false; } bool testChannel = false; bool testCodec = false; bool testFreq = false; bool testType = false; bool testSize = false; int dir = 0; snd_pcm_nonblock( handle, 0 ); snd_pcm_hw_params_alloca( ¶ms ); snd_pcm_hw_params_any( handle, params ); // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); err = -1; switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } // For now, just accept only audio/pcm codec if(!format.codec().startsWith(QLatin1String("audio/pcm"))) { err=-1; } else testCodec = true; if(err>=0 && format.channels() != -1) { err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); if(err>=0) err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); if(err>=0) testChannel = true; } if(err>=0 && format.frequency() != -1) { err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); if(err>=0) err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); if(err>=0) testFreq = true; } if((err>=0 && format.sampleSize() != -1) && (format.sampleType() != QAudioFormat::Unknown)) { switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } if(err>=0) { testSize = true; testType = true; } } if(err>=0) err = snd_pcm_hw_params(handle, params); if(err == 0) { // settings work // close() if(handle) snd_pcm_close(handle); return true; } if(handle) snd_pcm_close(handle); return false; }
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). bool failed = false; bool match = false; // check codec for( int i = 0; i < codecz.count(); i++) { if (format.codec() == codecz.at(i)) match = true; } if (!match) failed = true; // check channel match = false; if (!failed) { for( int i = 0; i < channelz.count(); i++) { if (format.channels() == channelz.at(i)) { match = true; break; } } if (!match) failed = true; } // check frequency match = false; if (!failed) { for( int i = 0; i < freqz.count(); i++) { if (format.frequency() == freqz.at(i)) { match = true; break; } } if (!match) failed = true; } // check sample size match = false; if (!failed) { for( int i = 0; i < sizez.count(); i++) { if (format.sampleSize() == sizez.at(i)) { match = true; break; } } if (!match) failed = true; } // check byte order match = false; if (!failed) { for( int i = 0; i < byteOrderz.count(); i++) { if (format.byteOrder() == byteOrderz.at(i)) { match = true; break; } } if (!match) failed = true; } // check sample type match = false; if (!failed) { for( int i = 0; i < typez.count(); i++) { if (format.sampleType() == typez.at(i)) { match = true; break; } } if (!match) failed = true; } if(!failed) { // settings work return true; } return false; }
bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const { // Set nearest to closest settings that do work. // See if what is in settings will work (return value). int err = 0; snd_pcm_t* handle; snd_pcm_hw_params_t *params; QString dev = device; // open() if(!dev.contains(QLatin1String("default"))) { int idx = snd_card_get_index(dev.toLocal8Bit().constData()); dev = QString(QLatin1String("hw:%1,0")).arg(idx); } if(mode == QAudio::AudioOutput) { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); } else { err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0); } if(err < 0) { handle = 0; return false; } bool testChannel = false; bool testCodec = false; bool testFreq = false; bool testType = false; bool testSize = false; int dir = 0; snd_pcm_nonblock( handle, 0 ); snd_pcm_hw_params_alloca( ¶ms ); snd_pcm_hw_params_any( handle, params ); // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } // For now, just accept only audio/pcm codec if(!format.codec().startsWith(QLatin1String("audio/pcm"))) { err=-1; } else testCodec = true; if(err>=0 && format.channels() != -1) { err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); if(err>=0) err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); if(err>=0) testChannel = true; } if(err>=0 && format.frequency() != -1) { err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); if(err>=0) err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); if(err>=0) testFreq = true; } if((err>=0 && format.sampleSize() != -1) && (format.sampleType() != QAudioFormat::Unknown)) { switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } if(err>=0) { testSize = true; testType = true; } } if(err>=0) err = snd_pcm_hw_params(handle, params); if(err == 0) { // settings work // close() if(handle) snd_pcm_close(handle); return true; } if(handle) snd_pcm_close(handle); return false; }