void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate) { const int channelBytes = format.sampleSize() / 8; qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8)) * durationUs / 1000000; m_buffer.resize(length); unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data()); int sampleIndex = 0; PHDBG() << "Type :" << format.sampleType() << " Size : " << format.sampleSize() << " Channel Count : " << format.channelCount(); while (length) { const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate()); for (int i = 0; i < format.channelCount(); ++i) { qint16 value = static_cast<qint16>(x * 32767); qToLittleEndian<qint16>(value, ptr); ptr += channelBytes; length -= channelBytes; } ++sampleIndex; } }
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 qMultiplySamples(qreal factor, const QAudioFormat &format, const void* src, void* dest, int len) { int samplesCount = len / (format.sampleSize()/8); switch ( format.sampleSize() ) { case 8: if (format.sampleType() == QAudioFormat::SignedInt) QAudioHelperInternal::adjustSamples<qint8>(factor,src,dest,samplesCount); else if (format.sampleType() == QAudioFormat::UnSignedInt) QAudioHelperInternal::adjustUnsignedSamples<quint8>(factor,src,dest,samplesCount); break; case 16: if (format.sampleType() == QAudioFormat::SignedInt) QAudioHelperInternal::adjustSamples<qint16>(factor,src,dest,samplesCount); else if (format.sampleType() == QAudioFormat::UnSignedInt) QAudioHelperInternal::adjustUnsignedSamples<quint16>(factor,src,dest,samplesCount); break; default: if (format.sampleType() == QAudioFormat::SignedInt) QAudioHelperInternal::adjustSamples<qint32>(factor,src,dest,samplesCount); else if (format.sampleType() == QAudioFormat::UnSignedInt) QAudioHelperInternal::adjustUnsignedSamples<quint32>(factor,src,dest,samplesCount); else if (format.sampleType() == QAudioFormat::Float) QAudioHelperInternal::adjustSamples<float>(factor,src,dest,samplesCount); } }
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds) { qint64 result = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8)) * microSeconds / 1000000; result -= result % (format.channelCount() * format.sampleSize()); return result; }
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; // For now, just accept only audio/pcm codec if(!format.codec().startsWith(QLatin1String("audio/pcm"))) failed = true; if(!failed && !(format.channels() == 1 || format.channels() == 2)) failed = true; if(!failed) { if(!(format.frequency() == 8000 || format.frequency() == 11025 || format.frequency() == 22050 || format.frequency() == 44100 || format.frequency() == 48000 || format.frequency() == 96000)) failed = true; } if(!failed && !(format.sampleSize() == 8 || format.sampleSize() == 16)) failed = true; if(!failed) { // settings work return true; } return false; }
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_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(); }
// Returns position in bytes, given position in microSeconds. qint64 audioLength(const QAudioFormat &format, qint64 microSeconds) { // format.sampleRate() is in Hz, format.sampleSize() in bits qint64 result = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8)) * microSeconds / 1000000; // Round off to start of the channel 0. result -= result % (format.channelCount() * format.sampleSize()); return result; }
void xmppClient::slotConnected() { QXmppCall *call = qobject_cast<QXmppCall*>(sender()); Q_ASSERT(call); qDebug() << "Call connected"; QXmppRtpChannel *channel = call->audioChannel(); // prepare audio format QAudioFormat format; format.setFrequency(channel->payloadType().clockrate()); format.setChannels(channel->payloadType().channels()); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); // the size in bytes of the audio buffers to/from sound devices // 160 ms seems to be the minimum to work consistently on Linux/Mac/Windows const int bufferSize = (format.frequency() * format.channels() * (format.sampleSize() / 8) * 160) / 1000; // initialise audio output QAudioOutput *audioOutput = new QAudioOutput(format, this); audioOutput->setBufferSize(bufferSize); audioOutput->start(channel); // initialise audio input QAudioInput *audioInput = new QAudioInput(format, this); audioInput->setBufferSize(bufferSize); audioInput->start(channel); }
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; }
void xmppClient::slotAudioModeChanged(QIODevice::OpenMode mode) { QXmppCall *call = qobject_cast<QXmppCall*>(sender()); Q_ASSERT(call); QXmppRtpAudioChannel *channel = call->audioChannel(); // prepare audio format QAudioFormat format; format.setSampleRate(channel->payloadType().clockrate()); format.setChannelCount(channel->payloadType().channels()); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); // the size in bytes of the audio buffers to/from sound devices // 160 ms seems to be the minimum to work consistently on Linux/Mac/Windows const int bufferSize = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8) * 160) / 1000; if (mode & QIODevice::ReadOnly) { // initialise audio output QAudioOutput *audioOutput = new QAudioOutput(format, this); audioOutput->setBufferSize(bufferSize); audioOutput->start(channel); } if (mode & QIODevice::WriteOnly) { // initialise audio input QAudioInput *audioInput = new QAudioInput(format, this); audioInput->setBufferSize(bufferSize); audioInput->start(channel); } }
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; }
void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int frequency) { const int channelBytes = format.sampleSize() / 8; const int sampleBytes = format.channelCount() * channelBytes; qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8)) * durationUs / 100000; 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()); generateData(format, ptr, length); }
void SpectrumAnalyser::calculate(const QByteArray &buffer, const QAudioFormat &format, bool isSample,char phoneme) { // QThread::currentThread is marked 'for internal use only', but // we're only using it for debug output here, so it's probably OK :) SPECTRUMANALYSER_DEBUG << "SpectrumAnalyser::calculate" << QThread::currentThread() << "state" << m_state; if (isReady()) { Q_ASSERT(isPCMS16LE(format)); const int bytesPerSample = format.sampleSize() * format.channels() / 8; #ifdef DUMP_SPECTRUMANALYSER m_count++; const QString pcmFileName = m_outputDir.filePath(QString("spectrum_%1.pcm").arg(m_count, 4, 10, QChar('0'))); QFile pcmFile(pcmFileName); pcmFile.open(QIODevice::WriteOnly); const int bufferLength = m_numSamples * bytesPerSample; pcmFile.write(buffer, bufferLength); m_textStream << "TimeDomain " << m_count << "\n"; const qint16* input = reinterpret_cast<const qint16*>(buffer); for (int i=0; i<m_numSamples; ++i) { m_textStream << i << "\t" << *input << "\n"; input += format.channels(); } #endif m_state = Busy; // Invoke SpectrumAnalyserThread::calculateSpectrum using QMetaObject. If // m_thread is in a different thread from the current thread, the // calculation will be done in the child thread. // Once the calculation is finished, a calculationChanged signal will be // emitted by m_thread. const bool b = QMetaObject::invokeMethod(m_thread, "calculateSpectrum", Qt::AutoConnection, Q_ARG(QByteArray, buffer), Q_ARG(int, format.frequency()), Q_ARG(int, bytesPerSample), Q_ARG(bool,isSample), Q_ARG(char,phoneme)); Q_ASSERT(b); Q_UNUSED(b) // suppress warnings in release builds #ifdef DUMP_SPECTRUMANALYSER m_textStream << "FrequencySpectrum " << m_count << "\n"; FrequencySpectrum::const_iterator x = m_spectrum.begin(); for (int i=0; i<m_numSamples; ++i, ++x) m_textStream << i << "\t" << x->frequency << "\t" << x->amplitude<< "\t" << x->phase << "\n"; #endif } }
QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const { if (isFormatSupported(settings)) return settings; QAudioFormat nearest = settings; nearest.setCodec(QLatin1String("audio/pcm")); if (nearest.sampleType() == QAudioFormat::Unknown) { QAudioFormat preferred = preferredFormat(); nearest.setSampleType(preferred.sampleType()); } QMap<int,int> testFrequencies; QList<int> frequenciesAvailable = supportedFrequencies(); QMap<int,int> testSampleSizes; QList<int> sampleSizesAvailable = supportedSampleSizes(); // Get sorted sampleSizes (equal to and ascending values only) 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; if (size >= settings.sampleSize()) { int diff = larger - smaller; testSampleSizes.insert(diff, size); } }
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; } }
bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { QAudioDeviceInfoInternal *self = const_cast<QAudioDeviceInfoInternal*>(this); return format.isValid() && format.codec() == QString::fromLatin1("audio/pcm") && self->supportedSampleRates().contains(format.sampleRate()) && self->supportedChannelCounts().contains(format.channelCount()) && self->supportedSampleSizes().contains(format.sampleSize()); }
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(); }
CircularBuffer::CircularBuffer(const QAudioFormat& format, qint64 samples, QObject* parent) : QIODevice(parent), m_format(format), m_bytesPerSample((format.sampleSize() / 8) * format.channelCount()) { m_readPtr = 0; m_writePtr = 0; m_bufferSize = 0; m_bufferCapacity = samples; m_buffer.resize(m_bufferCapacity); m_buffer.fill(0); open(QIODevice::ReadWrite); }
void AudioFileWav::addHeader(const QAudioFormat& audioFormat) { QDataStream stream(&_file); stream.setByteOrder(QDataStream::LittleEndian); // RIFF stream.writeRawData("RIFF", 4); stream << quint32(0); stream.writeRawData("WAVE", 4); // Format description PCM = 16 stream.writeRawData("fmt ", 4); stream << quint32(16); stream << quint16(1); stream << quint16(audioFormat.channelCount()); stream << quint32(audioFormat.sampleRate()); stream << quint32(audioFormat.sampleRate() * audioFormat.channelCount() * audioFormat.sampleSize() / 8); // bytes per second stream << quint16(audioFormat.channelCount() * audioFormat.sampleSize() / 8); // block align stream << quint16(audioFormat.sampleSize()); // bits Per Sample // Init data chunck stream.writeRawData("data", 4); stream << quint32(0); }
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; }
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; }
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(); }
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")); }
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; }
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; } }