📄 acm.cpp
字号:
/*! Suggest an output format for the specified input format \param a_FormatSuggest will be filled with all the corresponding data*/inline DWORD ACM::OnFormatSuggest(LPACMDRVFORMATSUGGEST a_FormatSuggest){ DWORD Result = MMSYSERR_NOTSUPPORTED; DWORD fdwSuggest = (ACM_FORMATSUGGESTF_TYPEMASK & a_FormatSuggest->fdwSuggest);my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest %s%s%s%s (0x%08X)", (fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS) ? "channels, ":"", (fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC) ? "samples/sec, ":"", (fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE) ? "bits/sample, ":"", (fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) ? "format, ":"", fdwSuggest);my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for source format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d", a_FormatSuggest->pwfxSrc->wFormatTag, a_FormatSuggest->pwfxSrc->nChannels, a_FormatSuggest->pwfxSrc->nSamplesPerSec, a_FormatSuggest->pwfxSrc->nAvgBytesPerSec, a_FormatSuggest->pwfxSrc->nBlockAlign, a_FormatSuggest->pwfxSrc->wBitsPerSample);my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggested destination format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d", a_FormatSuggest->pwfxDst->wFormatTag, a_FormatSuggest->pwfxDst->nChannels, a_FormatSuggest->pwfxDst->nSamplesPerSec, a_FormatSuggest->pwfxDst->nAvgBytesPerSec, a_FormatSuggest->pwfxDst->nBlockAlign, a_FormatSuggest->pwfxDst->wBitsPerSample); switch (a_FormatSuggest->pwfxSrc->wFormatTag) { case WAVE_FORMAT_PCM: /// \todo handle here the decoding ? my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PCM source"); // // if the destination format tag is restricted, verify that // it is within our capabilities... // // this driver is able to decode to PCM // if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest) { if (PERSONAL_FORMAT != a_FormatSuggest->pwfxDst->wFormatTag) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->wFormatTag = PERSONAL_FORMAT; }my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed A"); // // if the destination channel count is restricted, verify that // it is within our capabilities... // // this driver is not able to change the number of channels // if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest) { if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels; } if (a_FormatSuggest->pwfxSrc->nChannels != 1 && a_FormatSuggest->pwfxSrc->nChannels != 2) return MMSYSERR_INVALPARAM;my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed B"); // // if the destination samples per second is restricted, verify // that it is within our capabilities... // // this driver is not able to change the sample rate // if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest) { if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec; }my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed C"); // // if the destination bits per sample is restricted, verify // that it is within our capabilities... // // We prefer decoding to 16-bit PCM. // if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest) { if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) ) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->wBitsPerSample = 16; } // a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN; a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nChannels * 64000 / 8; my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed"); Result = MMSYSERR_NOERROR; break; case PERSONAL_FORMAT: my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PERSONAL source"); // // if the destination format tag is restricted, verify that // it is within our capabilities... // // this driver is able to decode to PCM // if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest) { if (WAVE_FORMAT_PCM != a_FormatSuggest->pwfxDst->wFormatTag) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; } // // if the destination channel count is restricted, verify that // it is within our capabilities... // // this driver is not able to change the number of channels // if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest) { if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels; } // // if the destination samples per second is restricted, verify // that it is within our capabilities... // // this driver is not able to change the sample rate // if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest) { if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec; } // // if the destination bits per sample is restricted, verify // that it is within our capabilities... // // We prefer decoding to 16-bit PCM. // if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest) { if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) ) return (ACMERR_NOTPOSSIBLE); } else { a_FormatSuggest->pwfxDst->wBitsPerSample = 16; } // a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN; a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; /// \todo this value must be a correct one ! a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nSamplesPerSec * a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed"); Result = MMSYSERR_NOERROR; break; } my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggested destination format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d", a_FormatSuggest->pwfxDst->wFormatTag, a_FormatSuggest->pwfxDst->nChannels, a_FormatSuggest->pwfxDst->nSamplesPerSec, a_FormatSuggest->pwfxDst->nAvgBytesPerSec, a_FormatSuggest->pwfxDst->nBlockAlign, a_FormatSuggest->pwfxDst->wBitsPerSample); return Result;}/*! Create a stream instance for decoding/encoding \param a_StreamInstance contain information about the stream desired*/inline DWORD ACM::OnStreamOpen(LPACMDRVSTREAMINSTANCE a_StreamInstance){ DWORD Result = ACMERR_NOTPOSSIBLE; // // the most important condition to check before doing anything else // is that this ACM driver can actually perform the conversion we are // being opened for. this check should fail as quickly as possible // if the conversion is not possible by this driver. // // it is VERY important to fail quickly so the ACM can attempt to // find a driver that is suitable for the conversion. also note that // the ACM may call this driver several times with slightly different // format specifications before giving up. // // this driver first verifies that the source and destination formats // are acceptable... // switch (a_StreamInstance->pwfxSrc->wFormatTag) { case WAVE_FORMAT_PCM: my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PCM source (%05d samples %d channels %d bits/sample)",a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxSrc->nChannels,a_StreamInstance->pwfxSrc->wBitsPerSample); if (a_StreamInstance->pwfxDst->wFormatTag == PERSONAL_FORMAT) { unsigned int OutputFrequency; /// \todo Smart mode if (my_EncodingProperties.GetSmartOutputMode()) OutputFrequency = ACMStream::GetOutputSampleRate(a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxDst->nAvgBytesPerSec,a_StreamInstance->pwfxDst->nChannels); else OutputFrequency = a_StreamInstance->pwfxSrc->nSamplesPerSec; my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PERSONAL output (%05d samples %d channels %d bits/sample %d kbps)",a_StreamInstance->pwfxDst->nSamplesPerSec,a_StreamInstance->pwfxDst->nChannels,a_StreamInstance->pwfxDst->wBitsPerSample,8 * a_StreamInstance->pwfxDst->nAvgBytesPerSec); /// \todo add the possibility to have channel resampling (mono to stereo / stereo to mono) /// \todo support resampling ? /// \todo only do the test on OutputFrequency in "Smart Output" mode if (a_StreamInstance->pwfxDst->nSamplesPerSec != OutputFrequency ||// a_StreamInstance->pwfxSrc->nSamplesPerSec != a_StreamInstance->pwfxDst->nSamplesPerSec || a_StreamInstance->pwfxSrc->nChannels != a_StreamInstance->pwfxDst->nChannels || a_StreamInstance->pwfxSrc->wBitsPerSample != 16) { Result = ACMERR_NOTPOSSIBLE; } else { if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0) { ACMStream * the_stream = ACMStream::Create(); a_StreamInstance->dwInstance = (DWORD) the_stream; if (the_stream != NULL) { MPEGLAYER3WAVEFORMAT * casted = (MPEGLAYER3WAVEFORMAT *) a_StreamInstance->pwfxDst; vbr_mode a_mode = (casted->fdwFlags-2 == 0)?vbr_abr:vbr_off; if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec, OutputFrequency, a_StreamInstance->pwfxDst->nChannels, a_StreamInstance->pwfxDst->nAvgBytesPerSec, a_mode)) Result = MMSYSERR_NOERROR; else ACMStream::Erase( the_stream ); } } else { Result = MMSYSERR_NOERROR; } } } break; case PERSONAL_FORMAT: my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PERSONAL source (%05d samples %d channels %d bits/sample %d kbps)",a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxSrc->nChannels,a_StreamInstance->pwfxSrc->wBitsPerSample,8 * a_StreamInstance->pwfxSrc->nAvgBytesPerSec); if (a_StreamInstance->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) {#ifdef ENABLE_DECODING if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0) { /// \todo create the decoding stream my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PCM output (%05d samples %d channels %d bits/sample %d B/s)",a_StreamInstance->pwfxDst->nSamplesPerSec,a_StreamInstance->pwfxDst->nChannels,a_StreamInstance->pwfxDst->wBitsPerSample,a_StreamInstance->pwfxDst->nAvgBytesPerSec); DecodeStream * the_stream = DecodeStream::Create(); a_StreamInstance->dwInstance = (DWORD) the_stream; if (the_stream != NULL) { if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec, a_StreamInstance->pwfxDst->nChannels, a_StreamInstance->pwfxDst->nAvgBytesPerSec, a_StreamInstance->pwfxSrc->nAvgBytesPerSec)) Result = MMSYSERR_NOERROR; else DecodeStream::Erase( the_stream ); } } else { /// \todo decoding verification my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream is valid"); Result = MMSYSERR_NOERROR; }#endif // ENABLE_DECODING } break; } my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream Result = %d",Result); return Result;}inline DWORD ACM::OnStreamSize(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMDRVSTREAMSIZE the_StreamSize){ DWORD Result = ACMERR_NOTPOSSIBLE; switch (ACM_STREAMSIZEF_QUERYMASK & the_StreamSize->fdwSize) { case ACM_STREAMSIZEF_DESTINATION: my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get source buffer size for destination size = %d",the_StreamSize->cbDstLength); break; case ACM_STREAMSIZEF_SOURCE: my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get destination buffer size for source size = %d",the_StreamSize->cbSrcLength); if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) { ACMStream * the_stream = (ACMStream *) a_StreamInstance->dwInstance; if (the_stream != NULL) { the_StreamSize->cbDstLength = the_stream->GetOutputSizeForInput(the_StreamSize->cbSrcLength); Result = MMSYSERR_NOERROR; } } else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag) {#ifdef ENABLE_DECODING DecodeStream * the_stream = (DecodeStream *) a_StreamInstance->dwInstance; if (the_stream != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -