QVariant S60AudioEncoderControl::encodingOption(const QString &codec, const QString &name) const { if (codec == "PCM") { QAudioFormat fmt = m_session->format(); if(qstrcmp(name.toLocal8Bit().constData(), "quality") == 0) { return QVariant(quality()); } else if(qstrcmp(name.toLocal8Bit().constData(), "channels") == 0) { return QVariant(fmt.channels()); } else if(qstrcmp(name.toLocal8Bit().constData(), "samplerate") == 0) { return QVariant(fmt.frequency()); } } return QVariant(); }
S60AudioEncoderControl::S60AudioEncoderControl(QObject *session, QObject *parent) : QAudioEncoderControl(parent), m_quality(QtMultimediaKit::NormalQuality) { TRACE("S60AudioEncoderControl::S60AudioEncoderControl" << qtThisPtr()); m_session = qobject_cast<S60AudioCaptureSession*>(session); QAudioFormat fmt = m_session->format(); // medium, 22050Hz mono S16 fmt.setSampleType(QAudioFormat::SignedInt); if (fmt.codec().compare("PCM", Qt::CaseInsensitive) == 0) { fmt.setSampleSize(16); fmt.setFrequency(22050); } fmt.setChannels(1); m_session->setFormat(fmt); m_settings.setChannelCount(fmt.channels()); m_settings.setCodec(fmt.codec()); m_settings.setSampleRate(fmt.sampleRate()); }
bool OutputQtMultimedia::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format) { QAudioFormat qformat; qformat.setCodec("audio/pcm"); qformat.setFrequency(freq); qformat.setByteOrder(QAudioFormat::LittleEndian); qformat.setChannels(map.size()); qformat.setSampleType(QAudioFormat::SignedInt); //Size of sample representation in input data. For 24-bit is 4, high byte is ignored. qint64 bytes_per_sample = 0; switch (format) { case Qmmp::PCM_S8: qformat.setSampleSize(8); bytes_per_sample = 1; break; case Qmmp::PCM_S16LE: qformat.setSampleSize(16); bytes_per_sample = 2; break; case Qmmp::PCM_S24LE: qformat.setSampleSize(24); bytes_per_sample = 4; break; case Qmmp::PCM_S32LE: qformat.setSampleSize(32); bytes_per_sample = 4; break; default: break; } if (!qformat.isValid()) return false; m_bytes_per_second = bytes_per_sample * freq * qformat.channels(); const QSettings settings(Qmmp::configFile(), QSettings::IniFormat); const QString saved_device_name = settings.value("QTMULTIMEDIA/device").toString(); QAudioDeviceInfo device_info; if (!saved_device_name.isEmpty()) { const QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); foreach (const QAudioDeviceInfo &info, devices) { if (info.deviceName()==saved_device_name) { if (info.isFormatSupported(qformat)) { device_info = info; break; } else qDebug() << "OutputQtMultimedia: Output device: " << saved_device_name << " is not supported"; } } } if (device_info.isNull()) { device_info = QAudioDeviceInfo::defaultOutputDevice(); if (!device_info.isFormatSupported(qformat)) return false; } qDebug() << "OutputQtMultimedia: Using output device: " << device_info.deviceName(); m_output.reset(new QAudioOutput(device_info, qformat)); m_buffer = m_output->start(); configure(freq, map, format); return true; }
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; }
qint64 samplesToBytes(const QAudioFormat &format, qint64 samples) { return samples * (format.sampleSize() / 8) * format.channels(); }
qint64 bytesToSamples(const QAudioFormat &format, qint64 length) { return length / ((format.sampleSize() / 8) * format.channels()); }
qint64 audioDuration(const QAudioFormat &format, qint64 bytes) { return (bytes * 1000000) / (format.frequency() * format.channels() * (format.sampleSize() / 8)); }
void PlaybackHandler::PlayFile(QString &filename) { // TODO: different thread for module handling? // destroy old (if any) delete m_pFileBuffer; delete m_pModPlayer; delete m_pFile; // keep for debugging etc. //m_currentFilename = filename.right(filename.size() - filename.lastIndexOf('/')); m_currentFilename = filename; // open file and use memory-mapping // (leave buffering to OS) // m_pFile = new QFile(filename); qint64 nSize = m_pFile->size(); uchar *pView = m_pFile->map(0, nSize); CFileType type(pView, nSize); if (type.m_enFileCategory == HEADERCAT_ARCHIVE) { // need to know which file in archive to decompress for playback.. //m_pArchiveHandler->openArchive(filename); //m_pArchiveHandler->openArchive(m_pFile); } else if (type.m_enFileCategory == HEADERCAT_PACKER) { // single-file compression // -> just decrunch to buffer //m_pArchiveHandler->openArchive(filename); //m_pArchiveHandler->openArchive(pView, nSize); //m_pFileBuffer = m_pArchiveHandler->decrunchToBuffer(pView, nSize); } else { // module file without compression, just use as-is. // // use buffer as interface to accessing memory-mapped file: // OS will generate pagefaults as needed // m_pFileBuffer = new CReadBuffer(pView, nSize); } // format-specific handling, // fileformat, playback-to-buffer etc. m_pModPlayer = GetPlayer(m_pFileBuffer); if (m_pModPlayer == nullptr) { emit error("Failed to create player"); return; } if (m_pModPlayer->ParseFileInfo() == false) { emit error("File could not be handled"); return; } // get decoding context: // player should keep position/status information, // we want it to control position (if possible..) // // TODO: determine how we are able to output // (e.g. 256 tracker channels -> 2 channels in stereo, // 8/16-bit width?) // and check that device supports what is possible.. // m_pCtx = m_pModPlayer->PrepareDecoder(); // TODO: get info on what is suitable format for playing.. // (what is supported by player/format/module..) //QAudioFormat format = pModPlayer->GetOutputFormat(); // placeholder.. set output format // these will need changing later: // due to module-format support // and device-support we may need something or other.. QAudioFormat format; format.setByteOrder(QAudioFormat::LittleEndian); format.setCodec("audio/pcm"); format.setSampleRate(m_pCtx->sampleRate()); format.setChannels(m_pCtx->channelCount()); format.setSampleSize(m_pCtx->sampleSize()); format.setSampleType(QAudioFormat::SignedInt); QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); if (info.isNull() == true) { emit error("Failed to get default audio output"); return; } if (info.isFormatSupported(format) == false) { emit error("Output format not supported"); return; } // expect 2-channels and 8-bit samples at 44.1kHz, // get proper values later, expecting 1s buffer to be enough for now.. // size_t nBuffer = (format.sampleRate() * format.channels() * (format.sampleSize()/8)); m_pDecodeBuffer->PrepareBuffer(nBuffer, false); // get device for output m_pAudioOut = new QAudioOutput(format, this); connect(m_pAudioOut, SIGNAL(stateChanged(QAudio::State)), this, SLOT(onAudioState(QAudio::State))); connect(m_pAudioOut, SIGNAL(notify()), this, SLOT(onPlayNotify())); if (m_pAudioOut->bufferSize() < nBuffer) { m_pAudioOut->setBufferSize(nBuffer); } m_pAudioOut->setNotifyInterval(250); // 250ms // push-mode (we decode to buffer and push to device), // we might need different thread for no-gaps playback.. m_pDevOut = m_pAudioOut->start(); if (initialOutput() == false) { // failed, cleanup stopPlay(); // status message emit error("Failed on audiodevice write(): " + filename); } }
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds) { return (format.frequency() * format.channels() * (format.sampleSize() / 8)) * microSeconds / 1000000; }
void tst_QAudioFormat::checkChannels() { QAudioFormat audioFormat; audioFormat.setChannels(2); QVERIFY(audioFormat.channels() == 2); }