AudioOutputSettings* AudioOutputNULL::GetOutputSettings(bool /*digital*/) { // Pretend that we support everything AudioFormat fmt; int rate; AudioOutputSettings *settings = new AudioOutputSettings(); while ((rate = settings->GetNextRate())) { settings->AddSupportedRate(rate); } while ((fmt = settings->GetNextFormat())) { settings->AddSupportedFormat(fmt); } for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++) { settings->AddSupportedChannels(channels); } settings->setPassthrough(-1); // no passthrough return settings; }
AudioOutputSettings* AudioOutputWin::GetOutputSettings(bool /*digital*/) { AudioOutputSettings *settings = new AudioOutputSettings(); // We use WAVE_MAPPER to find a compatible device, so just claim support // for all of the standard rates while (DWORD rate = (DWORD)settings->GetNextRate()) settings->AddSupportedRate(rate); // Support all standard formats settings->AddSupportedFormat(FORMAT_U8); settings->AddSupportedFormat(FORMAT_S16); #if 0 // 24-bit integer is not supported settings->AddSupportedFormat(FORMAT_S24); #endif #if 0 // 32-bit integer (OGG) is not supported on all platforms. settings->AddSupportedFormat(FORMAT_S32); #endif #if 0 // 32-bit floating point (AC3) is not supported on all platforms. settings->AddSupportedFormat(FORMAT_FLT); #endif // Guess that we can do up to 5.1 for (uint i = 2; i < 7; i++) settings->AddSupportedChannels(i); settings->setPassthrough(0); //Maybe passthrough return settings; }
/** * Returns capabilities supported by the audio device * amended to take into account the digital audio * options (AC3 and DTS) * Warning: do not call it twice in a row, will lead to invalid settings */ AudioOutputSettings* AudioOutputSettings::GetCleaned(bool newcopy) { AudioOutputSettings* aosettings; if (newcopy) { aosettings = new AudioOutputSettings; *aosettings = *this; } else aosettings = this; if (m_invalid) return aosettings; if (BestSupportedPCMChannelsELD() > 2) { aosettings->setFeature(FEATURE_LPCM); } if (IsSupportedFormat(FORMAT_S16)) { // E-AC3 is transferred as stereo PCM at 4 times the rates // assume all amplifier supporting E-AC3 also supports 7.1 LPCM // as it's mandatory under the bluray standard //#if LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 52, 83, 0 ) if (m_passthrough >= 0 && IsSupportedChannels(8) && IsSupportedRate(192000)) aosettings->setFeature(FEATURE_TRUEHD | FEATURE_DTSHD | FEATURE_EAC3); //#endif if (m_passthrough >= 0) { if (BestSupportedChannels() == 2) { LOG(VB_AUDIO, LOG_INFO, LOC + "may be AC3 or DTS capable"); aosettings->AddSupportedChannels(6); } aosettings->setFeature(FEATURE_AC3 | FEATURE_DTS); } } else { // Can't do digital passthrough without 16 bits audio aosettings->setPassthrough(-1); aosettings->setFeature(false, FEATURE_AC3 | FEATURE_DTS | FEATURE_EAC3 | FEATURE_TRUEHD | FEATURE_DTSHD); } return aosettings; }
AudioOutputSettings* AudioOutputDX::GetOutputSettings(bool passthrough) { AudioOutputSettings *settings = new AudioOutputSettings(); DSCAPS devcaps; devcaps.dwSize = sizeof(DSCAPS); m_priv->InitDirectSound(passthrough); if ((!m_priv->dsobject || !m_priv->dsound_dll) || FAILED(IDirectSound_GetCaps(m_priv->dsobject, &devcaps)) ) { delete settings; return nullptr; } VBAUDIO(QString("GetCaps sample rate min: %1 max: %2") .arg(devcaps.dwMinSecondarySampleRate) .arg(devcaps.dwMaxSecondarySampleRate)); /* We shouldn't assume we can do everything between min and max but there's no way to test individual rates, so we'll have to */ while (DWORD rate = (DWORD)settings->GetNextRate()) if((rate >= devcaps.dwMinSecondarySampleRate) || (rate <= devcaps.dwMaxSecondarySampleRate)) settings->AddSupportedRate(rate); /* We can only test for 8 and 16 bit support, DS uses float internally */ if (devcaps.dwFlags & DSCAPS_PRIMARY8BIT) settings->AddSupportedFormat(FORMAT_U8); if (devcaps.dwFlags & DSCAPS_PRIMARY16BIT) settings->AddSupportedFormat(FORMAT_S16); #if 0 // 24-bit integer is not supported settings->AddSupportedFormat(FORMAT_S24); #endif #if 0 // 32-bit integer (OGG) is not supported on all platforms. settings->AddSupportedFormat(FORMAT_S32); #endif #if 0 // 32-bit floating point (AC3) is not supported on all platforms. settings->AddSupportedFormat(FORMAT_FLT); #endif /* No way to test anything other than mono or stereo, guess that we can do up to 5.1 */ for (uint i = 2; i < 7; i++) settings->AddSupportedChannels(i); settings->setPassthrough(0); // Maybe passthrough return settings; }
AudioOutputSettings* AudioOutputCA::GetOutputSettings() { AudioOutputSettings *settings = new AudioOutputSettings(); // Seek hardware sample rate available int rate; int *rates = d->RatesList(d->mDeviceID); int *p_rates = rates; while (*p_rates > 0 && (rate = settings->GetNextRate())) { if (*p_rates == rate) { settings->AddSupportedRate(*p_rates); p_rates++; } } free(rates); // Supported format: 16 bits audio or float settings->AddSupportedFormat(FORMAT_S16); settings->AddSupportedFormat(FORMAT_FLT); bool *channels = d->ChannelsList(d->mDeviceID, passthru); if (channels == NULL) { // Error retrieving list of supported channels, assume stereo only settings->AddSupportedChannels(2); } else { for (int i = CHANNELS_MIN; i <= CHANNELS_MAX; i++) if (channels[i]) { Debug(QString("Support %1 channels").arg(i)); settings->AddSupportedChannels(i); } free(channels); } settings->setPassthrough(0); // Maybe passthrough return settings; }
AudioOutputSettings* AudioOutputWin::GetOutputSettings(void) { AudioOutputSettings *settings = new AudioOutputSettings(); // We use WAVE_MAPPER to find a compatible device, so just claim support // for all of the standard rates while (DWORD rate = (DWORD)settings->GetNextRate()) settings->AddSupportedRate(rate); // Support all standard formats settings->AddSupportedFormat(FORMAT_U8); settings->AddSupportedFormat(FORMAT_S16); settings->AddSupportedFormat(FORMAT_S24); settings->AddSupportedFormat(FORMAT_S32); settings->AddSupportedFormat(FORMAT_FLT); // Guess that we can do up to 5.1 for (uint i = 2; i < 7; i++) settings->AddSupportedChannels(i); settings->setPassthrough(0); //Maybe passthrough return settings; }
AudioOutputSettings* AudioOutputOSS::GetOutputSettings(bool /*digital*/) { AudioOutputSettings *settings = new AudioOutputSettings(); QByteArray device = main_device.toLatin1(); audiofd = open(device.constData(), O_WRONLY | O_NONBLOCK); AudioFormat fmt; int rate, formats = 0; if (audiofd < 0) { VBERRENO(QString("Error opening audio device (%1)").arg(main_device)); delete settings; return NULL; } while ((rate = settings->GetNextRate())) { int rate2 = rate; if(ioctl(audiofd, SNDCTL_DSP_SPEED, &rate2) >= 0 && rate2 == rate) settings->AddSupportedRate(rate); } if(ioctl(audiofd, SNDCTL_DSP_GETFMTS, &formats) < 0) VBERRENO("Error retrieving formats"); else { int ofmt; while ((fmt = settings->GetNextFormat())) { switch (fmt) { case FORMAT_U8: ofmt = AFMT_U8; break; case FORMAT_S16: ofmt = AFMT_S16_NE; break; default: continue; } if (formats & ofmt) settings->AddSupportedFormat(fmt); } } #if defined(AFMT_AC3) // Check if drivers supports AC3 settings->setPassthrough(((formats & AFMT_AC3) != 0) - 1); #endif for (int i = 1; i <= 2; i++) { int channel = i; if (ioctl(audiofd, SNDCTL_DSP_CHANNELS, &channel) >= 0 && channel == i) { settings->AddSupportedChannels(i); } } close(audiofd); audiofd = -1; return settings; }
AudioOutputSettings* AudioOutputALSA::GetOutputSettings(bool passthrough) { snd_pcm_hw_params_t *params; snd_pcm_format_t afmt = SND_PCM_FORMAT_UNKNOWN; AudioFormat fmt; int rate; int err; AudioOutputSettings *settings = new AudioOutputSettings(); if (pcm_handle) { snd_pcm_close(pcm_handle); pcm_handle = NULL; } if ((err = TryOpenDevice(OPEN_FLAGS, passthrough)) < 0) { AERROR(QString("snd_pcm_open(\"%1\")").arg(m_lastdevice)); delete settings; return NULL; } snd_pcm_hw_params_alloca(¶ms); if ((err = snd_pcm_hw_params_any(pcm_handle, params)) < 0) { snd_pcm_close(pcm_handle); if ((err = TryOpenDevice(OPEN_FLAGS&FILTER_FLAGS, passthrough)) < 0) { AERROR(QString("snd_pcm_open(\"%1\")").arg(m_lastdevice)); delete settings; return NULL; } if ((err = snd_pcm_hw_params_any(pcm_handle, params)) < 0) { AERROR("No playback configurations available"); snd_pcm_close(pcm_handle); pcm_handle = NULL; delete settings; return NULL; } Warn("Supported audio format detection will be inacurrate " "(using plugin?)"); } while ((rate = settings->GetNextRate())) if(snd_pcm_hw_params_test_rate(pcm_handle, params, rate, 0) >= 0) settings->AddSupportedRate(rate); while ((fmt = settings->GetNextFormat())) { switch (fmt) { case FORMAT_U8: afmt = SND_PCM_FORMAT_U8; break; case FORMAT_S16: afmt = SND_PCM_FORMAT_S16; break; case FORMAT_S24: afmt = SND_PCM_FORMAT_S24; break; case FORMAT_S32: afmt = SND_PCM_FORMAT_S32; break; case FORMAT_FLT: afmt = SND_PCM_FORMAT_FLOAT; break; default: continue; } if (snd_pcm_hw_params_test_format(pcm_handle, params, afmt) >= 0) settings->AddSupportedFormat(fmt); } for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++) if (snd_pcm_hw_params_test_channels(pcm_handle, params, channels) >= 0) settings->AddSupportedChannels(channels); snd_pcm_close(pcm_handle); pcm_handle = NULL; /* Check if name or description contains information to know if device can accept passthrough or not */ QMap<QString, QString> *alsadevs = GetALSADevices("pcm"); while(1) { QString real_device = (((passthru || enc) && m_discretedigital) ? passthru_device : main_device); QString desc = alsadevs->value(real_device); settings->setPassthrough(1); // yes passthrough if (real_device.contains("digital", Qt::CaseInsensitive) || desc.contains("digital", Qt::CaseInsensitive)) break; if (real_device.contains("iec958", Qt::CaseInsensitive)) break; if (real_device.contains("spdif", Qt::CaseInsensitive)) break; if (real_device.contains("hdmi", Qt::CaseInsensitive)) break; settings->setPassthrough(-1); // no passthrough // PulseAudio does not support passthrough if (real_device.contains("pulse", Qt::CaseInsensitive) || desc.contains("pulse", Qt::CaseInsensitive)) break; if (real_device.contains("analog", Qt::CaseInsensitive) || desc.contains("analog", Qt::CaseInsensitive)) break; if (real_device.contains("surround", Qt::CaseInsensitive) || desc.contains("surround", Qt::CaseInsensitive)) break; settings->setPassthrough(0); // maybe passthrough break; } delete alsadevs; return settings; }