int DVDGraph::check_spdif_passthrough(Speakers _spk) const { // SPDIF-1 check (passthrough) if (!use_spdif) return SPDIF_MODE_DISABLED; // check format if ((spdif_pt & FORMAT_MASK(_spk.format)) == 0) return SPDIF_ERR_FORMAT; // check sample rate if (spdif_check_sr && _spk.sample_rate) if ((!spdif_allow_48 || _spk.sample_rate != 48000) && (!spdif_allow_44 || _spk.sample_rate != 44100) && (!spdif_allow_32 || _spk.sample_rate != 32000)) return SPDIF_ERR_SAMPLE_RATE; // check sink if (sink && query_sink && !spdif_as_pcm) if (!sink->query_input(Speakers(FORMAT_SPDIF, _spk.mask, _spk.sample_rate))) return SPDIF_ERR_SINK; return SPDIF_MODE_PASSTHROUGH; }
bool spk2mt(Speakers spk, CMediaType &mt, int i) { if (spk.format == FORMAT_SPDIF) { // SPDIF media types if (i < 0 || i >= 2) return false; std::auto_ptr<WAVEFORMATEX> wfe(spk2wfe(spk, 0)); if (!wfe.get()) return false; mt.SetType(&MEDIATYPE_Audio); mt.SetSubtype(i == 0? &MEDIASUBTYPE_DOLBY_AC3_SPDIF: &MEDIASUBTYPE_PCM); mt.SetFormatType(&FORMAT_WaveFormatEx); mt.SetFormat((BYTE*)wfe.get(), sizeof(WAVEFORMATEX) + wfe->cbSize); return true; } else if (FORMAT_MASK(spk.format) & FORMAT_CLASS_PCM) { // PCM media types std::auto_ptr<WAVEFORMATEX> wfe(spk2wfe(spk, i)); if (!wfe.get()) return false; mt.SetType(&MEDIATYPE_Audio); mt.SetSubtype(&MEDIASUBTYPE_PCM); mt.SetFormatType(&FORMAT_WaveFormatEx); mt.SetFormat((BYTE*)wfe.get(), sizeof(WAVEFORMATEX) + wfe->cbSize); return true; } else return false; }
bool Converter::set_format(int _format) { if ((FORMAT_MASK(_format) & converter_formats) == 0) return false; format = _format; if (is_open()) return open(spk); return true; }
bool Converter::can_open(Speakers new_spk) const { if ((FORMAT_MASK(new_spk.format) & converter_formats) == 0) return false; if (new_spk.format == format) return true; if (new_spk.nch() == 0) return false; if (find_conversion(format, new_spk) == 0) return false; return true; }
bool wfx2spk(WAVEFORMATEX *wfx, Speakers &spk) { int format; int mask; WAVEFORMATEXTENSIBLE *wfex = 0; if ( ! wfx ) return false; if ( wfx->wFormatTag == WAVE_FORMAT_DOLBY_AC3_SPDIF ) { spk = Speakers(FORMAT_SPDIF, 0, wfx->nSamplesPerSec); return true; } if ( wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) { // extensible if ( wfx->cbSize < 22 ) return false; wfex = (WAVEFORMATEXTENSIBLE *)wfx; // determine sample format if ( wfex->SubFormat == GUID_SUBTYPE_IEEE_FLOAT ) { switch (wfx->wBitsPerSample) { case 32: format = FORMAT_PCMFLOAT; break; case 64: format = FORMAT_PCMDOUBLE; break; default: return false; } } else if ( wfex->SubFormat == GUID_SUBTYPE_PCM ) { switch ( wfx->wBitsPerSample ) { case 16: format = FORMAT_PCM16; break; case 24: format = FORMAT_PCM24; break; case 32: format = FORMAT_PCM32; break; default: return false; } } else if ( wfex->SubFormat == GUID_DOLBY_AC3_SPDIF ) format = FORMAT_SPDIF; else return false; // determine audio mode for ( mask = 0; mask < ((int)(sizeof(ds_channels_tbl) / sizeof(ds_channels_tbl[0]))); ++mask ) { if ( ds_channels_tbl[mask] == wfex->dwChannelMask ) break; } if ( mask == sizeof(ds_channels_tbl) / sizeof(ds_channels_tbl[0]) ) return false; } else { // determine sample format switch ( wfx->wFormatTag ) { case WAVE_FORMAT_IEEE_FLOAT: switch ( wfx->wBitsPerSample ) { case 32: format = FORMAT_PCMFLOAT; break; case 64: format = FORMAT_PCMDOUBLE; break; default: return false; } break; case WAVE_FORMAT_PCM: switch ( wfx->wBitsPerSample ) { case 16: format = FORMAT_PCM16; break; case 24: format = FORMAT_PCM24; break; case 32: format = FORMAT_PCM32; break; default: return false; } break; case WAVE_FORMAT_AVI_AC3: format = FORMAT_AC3; break; case WAVE_FORMAT_AVI_DTS: format = FORMAT_DTS; break; case WAVE_FORMAT_MPEG: format = FORMAT_MPA; break; default: return false; } // determine audio mode mask = 0; if ( FORMAT_MASK(format) & FORMAT_CLASS_PCM ) switch ( wfx->nChannels ) { case 1: mask = MODE_MONO; break; case 2: mask = MODE_STEREO; break; case 3: mask = MODE_3_0; break; case 4: mask = MODE_QUADRO; break; case 5: mask = MODE_3_2; break; case 6: mask = MODE_5_1; break; default: return false; } } spk = Speakers(format, mask, wfx->nSamplesPerSec); return true; }
bool AudioProcessor::can_open(Speakers new_spk) const { return (FORMAT_MASK(new_spk.format) & format_mask) && new_spk.sample_rate && new_spk.mask; }
bool AudioProcessor::query_user(Speakers new_user_spk) const { return new_user_spk.is_unknown() || (FORMAT_MASK(new_user_spk.format) & format_mask) != 0; }