I am trying to convert PCM wav into mpeg later-3.
acmStreamOpen returns 512=ACMERR_NOTPOSSIBLE
Why? I have installed Fraunhofer codec from Windows XP:
+ szShortName "MPEG Layer-3 Codec "
+ szLongName "Fraunhofer IIS MPEG Layer-3 Codec (advanced)"
+ szCopyright "Copyright © 1996-1999 Fraunhofer Institut Integrierte
Schaltungen IIS"
+ szFeatures "bitrates up to 56kBit/s, mono and stereo codec (advanced)"
When I change places betwwen waveFormat and mp3format (to convert
mp3->pcm) it works (acmStreamOpen returns 0).
What I need to do to convert PCM -> mp3 ?
#define MP3_BLOCK_SIZE 417
DWORD maxFormatSize = 0;
mmr = acmMetrics( NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize );
LPWAVEFORMATEX waveFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR,
maxFormatSize );
waveFormat->wFormatTag = WAVE_FORMAT_PCM;
waveFormat->nChannels = 1;
waveFormat->nSamplesPerSec = 16000;
waveFormat->wBitsPerSample = 16;
waveFormat->nBlockAlign = 2;
waveFormat->nAvgBytesPerSec =
waveFormat->nBlockAlign*waveFormat->nSamplesPerSec;
waveFormat->cbSize = 0;
LPMPEGLAYER3WAVEFORMAT mp3format = (LPMPEGLAYER3WAVEFORMAT)
LocalAlloc(LPTR, maxFormatSize );
mp3format->wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
mp3format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
mp3format->wfx.nChannels = 1;
mp3format->wfx.nAvgBytesPerSec = 32 * (1024 / 8);
mp3format->wfx.wBitsPerSample = 0;
mp3format->wfx.nBlockAlign = 1;
mp3format->wfx.nSamplesPerSec = 16000;
mp3format->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
mp3format->nBlockSize = MP3_BLOCK_SIZE;
mp3format->nFramesPerBlock = 1;
mp3format->nCodecDelay = 1393;
mp3format->wID = MPEGLAYER3_ID_MPEG;
m_mp3stream = NULL;
mmr = acmStreamOpen( &m_mp3stream, /*driver*/NULL, waveFormat,
(LPWAVEFORMATEX) mp3format, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME );
I taken output format settings from acmFormatSuggest() and now it's works.
> #define MP3_BLOCK_SIZE 417
The block size depends on the channels, frequency and
bitrate: are you sure this is the right value? You should
let the codec tell you using acmFormatSugget() or
acmFormatEnum().
> mp3format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
> mp3format->wfx.nChannels = 1;
> mp3format->wfx.nAvgBytesPerSec = 32 * (1024 / 8);
1 Kbps = 1000 bps and not 1024: MPEG bitrates are decimal
and not binary.
> mp3format->wfx.wBitsPerSample = 0;
> mp3format->wfx.nBlockAlign = 1;
> mp3format->wfx.nSamplesPerSec = 16000;
I think the max bitrate for 16KHz/mono is 24Kbps and not
32Kbps.
If you use acmFormatEnum(), you can choose the pre-filled
MPEGLAYER3WAVEFORMAT that best suits you without risking an
unsupported settings combination.
--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// a dot angeli at psynet dot net
>> mp3format->wfx.wBitsPerSample = 0;
>> mp3format->wfx.nBlockAlign = 1;
>> mp3format->wfx.nSamplesPerSec = 16000;
>
> I think the max bitrate for 16KHz/mono is 24Kbps and not
> 32Kbps.
>
> If you use acmFormatEnum(), you can choose the pre-filled
> MPEGLAYER3WAVEFORMAT that best suits you without risking an
> unsupported settings combination.
>
I used acmFormatSuggest and it helped :)
>> mp3format->wfx.wBitsPerSample = 0;
>> mp3format->wfx.nBlockAlign = 1;
>> mp3format->wfx.nSamplesPerSec = 16000;
>
> I think the max bitrate for 16KHz/mono is 24Kbps and not
> 32Kbps.
Max bitrates are 32kbps for mono and 56kbps for stereo encoding (maybe
it depends from windows/ie/media player version installed in system).
I have another question - when I convert mono PCM to mono MP3, stereo
PCM to stereo MP3 and stereo PCM to mono MP3 everything works fine.
But when I try to convert mono PCM to stereo MP3 (to use higher bitrate)
acmFormatSuggest returns ACMERR_NOTPOSSIBLE.
I think I am doing something wrong, because sound recorder
(%SystemRoot%\System32\sndrec32.exe) can do such conversion without
problems.
LPWAVEFORMATEX waveFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR,
maxFormatSize );
waveFormat->wFormatTag = WAVE_FORMAT_PCM;
waveFormat->nChannels = 1;
waveFormat->nSamplesPerSec = 16000;
waveFormat->wBitsPerSample = 16;
waveFormat->nBlockAlign = 2;
waveFormat->nAvgBytesPerSec=waveFormat->nBlockAlign*waveFormat->nSamplesPerSec;
waveFormat->cbSize = 0;
LPMPEGLAYER3WAVEFORMAT mp3format =
(LPMPEGLAYER3WAVEFORMAT)LocalAlloc(LPTR, maxFormatSize );
mp3format->wfx.nChannels = 1;
mp3format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
MMRESULT ret=acmFormatSuggest( driver, waveFormat,
(LPWAVEFORMATEX)mp3format, maxFormatSize,
ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_WFORMATTAG);
Code above (mono->mono) works.
When I change mp3format->wfx.nChannels = 2; the ret will be 512 (not
possible).
When I change into:
waveFormat->nChannels = 2;
waveFormat->nBlockAlign = 4;
and
mp3format->wfx.nChannels = 2;
There will by everything ok (stereo->stereo).
It works also when mp3format->wfx.nChannels = 1 (stereo->mono).
What should I do to perform mono->stereo conversion? Sound recorder can
do this.
The only way is 3 step conversion mono PCM -> stereo PCM -> stereo MP3?