winemp3: Add support for WAVE_FORMAT_MPEG.

This commit is contained in:
Maarten Lankhorst 2011-09-26 17:36:49 +02:00 committed by Alexandre Julliard
parent 12e132e9be
commit 557deb0a19
1 changed files with 53 additions and 12 deletions

View File

@ -106,6 +106,7 @@ static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
hi = NUM_PCM_FORMATS; hi = NUM_PCM_FORMATS;
fmts = PCM_Formats; fmts = PCM_Formats;
break; break;
case WAVE_FORMAT_MPEG:
case WAVE_FORMAT_MPEGLAYER3: case WAVE_FORMAT_MPEGLAYER3:
hi = NUM_MPEG3_FORMATS; hi = NUM_MPEG3_FORMATS;
fmts = MPEG3_Formats; fmts = MPEG3_Formats;
@ -233,7 +234,8 @@ static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
{ {
goto theEnd; goto theEnd;
} }
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 && else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{ {
/* resampling or mono <=> stereo not available /* resampling or mono <=> stereo not available
@ -583,7 +585,8 @@ static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
adsi->dwDriver = (DWORD_PTR)aad; adsi->dwDriver = (DWORD_PTR)aad;
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 && if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{ {
OSStatus err; OSStatus err;
@ -660,7 +663,7 @@ static LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add)
add->vdwACM = 0x01000000; add->vdwACM = 0x01000000;
add->vdwDriver = 0x01000000; add->vdwDriver = 0x01000000;
add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
add->cFormatTags = 2; /* PCM, MPEG3 */ add->cFormatTags = 3; /* PCM, MPEG3 */
add->cFilterTags = 0; add->cFilterTags = 0;
add->hicon = NULL; add->hicon = NULL;
MultiByteToWideChar( CP_ACP, 0, "WINE-MPEG3", -1, MultiByteToWideChar( CP_ACP, 0, "WINE-MPEG3", -1,
@ -684,16 +687,17 @@ static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
{ {
static const WCHAR szPcm[]={'P','C','M',0}; static const WCHAR szPcm[]={'P','C','M',0};
static const WCHAR szMpeg3[]={'M','P','e','g','3',0}; static const WCHAR szMpeg3[]={'M','P','e','g','3',0};
static const WCHAR szMpeg[]={'M','P','e','g',0};
switch (dwQuery) switch (dwQuery)
{ {
case ACM_FORMATTAGDETAILSF_INDEX: case ACM_FORMATTAGDETAILSF_INDEX:
if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE; if (aftd->dwFormatTagIndex > 2) return ACMERR_NOTPOSSIBLE;
break; break;
case ACM_FORMATTAGDETAILSF_LARGESTSIZE: case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN) if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
{ {
aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_MPEGLAYER3 is bigger than PCM */ aftd->dwFormatTagIndex = 2; /* WAVE_FORMAT_MPEG is biggest */
break; break;
} }
/* fall thru */ /* fall thru */
@ -702,6 +706,7 @@ static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
{ {
case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break; case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
case WAVE_FORMAT_MPEGLAYER3: aftd->dwFormatTagIndex = 1; break; case WAVE_FORMAT_MPEGLAYER3: aftd->dwFormatTagIndex = 1; break;
case WAVE_FORMAT_MPEG: aftd->dwFormatTagIndex = 2; break;
default: return ACMERR_NOTPOSSIBLE; default: return ACMERR_NOTPOSSIBLE;
} }
break; break;
@ -725,11 +730,17 @@ static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
aftd->cStandardFormats = NUM_MPEG3_FORMATS; aftd->cStandardFormats = NUM_MPEG3_FORMATS;
lstrcpyW(aftd->szFormatTag, szMpeg3); lstrcpyW(aftd->szFormatTag, szMpeg3);
break; break;
case 2:
aftd->dwFormatTag = WAVE_FORMAT_MPEG;
aftd->cbFormatSize = sizeof(MPEG1WAVEFORMAT);
aftd->cStandardFormats = NUM_MPEG3_FORMATS;
lstrcpyW(aftd->szFormatTag, szMpeg);
break;
} }
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
static void fill_in_wfx(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate) static void fill_in_mp3(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate)
{ {
MPEGLAYER3WAVEFORMAT* mp3wfx = (MPEGLAYER3WAVEFORMAT*)wfx; MPEGLAYER3WAVEFORMAT* mp3wfx = (MPEGLAYER3WAVEFORMAT*)wfx;
@ -746,6 +757,24 @@ static void fill_in_wfx(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate)
} }
} }
static void fill_in_mpeg(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate)
{
MPEG1WAVEFORMAT* mp3wfx = (MPEG1WAVEFORMAT*)wfx;
wfx->nAvgBytesPerSec = bit_rate / 8;
if (cbwfx >= sizeof(WAVEFORMATEX))
wfx->cbSize = sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX);
if (cbwfx >= sizeof(MPEG1WAVEFORMAT))
{
mp3wfx->fwHeadLayer = ACM_MPEG_LAYER3;
mp3wfx->dwHeadBitrate = wfx->nAvgBytesPerSec * 8;
mp3wfx->fwHeadMode = ACM_MPEG_JOINTSTEREO;
mp3wfx->fwHeadModeExt = 0xf;
mp3wfx->wHeadEmphasis = 1;
mp3wfx->fwHeadFlags = ACM_MPEG_ID_MPEG1;
}
}
/*********************************************************************** /***********************************************************************
* MPEG3_FormatDetails * MPEG3_FormatDetails
* *
@ -775,12 +804,16 @@ static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign; afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
break; break;
case WAVE_FORMAT_MPEGLAYER3: case WAVE_FORMAT_MPEGLAYER3:
case WAVE_FORMAT_MPEG:
if (afd->dwFormatIndex >= NUM_MPEG3_FORMATS) return ACMERR_NOTPOSSIBLE; if (afd->dwFormatIndex >= NUM_MPEG3_FORMATS) return ACMERR_NOTPOSSIBLE;
afd->pwfx->nChannels = MPEG3_Formats[afd->dwFormatIndex].nChannels; afd->pwfx->nChannels = MPEG3_Formats[afd->dwFormatIndex].nChannels;
afd->pwfx->nSamplesPerSec = MPEG3_Formats[afd->dwFormatIndex].rate; afd->pwfx->nSamplesPerSec = MPEG3_Formats[afd->dwFormatIndex].rate;
afd->pwfx->wBitsPerSample = MPEG3_Formats[afd->dwFormatIndex].nBits; afd->pwfx->wBitsPerSample = MPEG3_Formats[afd->dwFormatIndex].nBits;
afd->pwfx->nBlockAlign = 1; afd->pwfx->nBlockAlign = 1;
fill_in_wfx(afd->cbwfx, afd->pwfx, 192000); if (afd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3)
fill_in_mp3(afd->cbwfx, afd->pwfx, 192000);
else
fill_in_mpeg(afd->cbwfx, afd->pwfx, 192000);
break; break;
default: default:
WARN("Unsupported tag %08x\n", afd->dwFormatTag); WARN("Unsupported tag %08x\n", afd->dwFormatTag);
@ -840,9 +873,13 @@ static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8; adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign; adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
break; break;
case WAVE_FORMAT_MPEG:
adfs->pwfxDst->nBlockAlign = 1;
fill_in_mpeg(adfs->cbwfxDst, adfs->pwfxDst, 192000);
break;
case WAVE_FORMAT_MPEGLAYER3: case WAVE_FORMAT_MPEGLAYER3:
adfs->pwfxDst->nBlockAlign = 1; adfs->pwfxDst->nBlockAlign = 1;
fill_in_wfx(adfs->cbwfxDst, adfs->pwfxDst, 192000); fill_in_mp3(adfs->cbwfxDst, adfs->pwfxDst, 192000);
break; break;
default: default:
FIXME("\n"); FIXME("\n");
@ -865,14 +902,16 @@ static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE ad
case ACM_STREAMSIZEF_DESTINATION: case ACM_STREAMSIZEF_DESTINATION:
/* cbDstLength => cbSrcLength */ /* cbDstLength => cbSrcLength */
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3) (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
{ {
nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5); nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
if (nblocks == 0) if (nblocks == 0)
return ACMERR_NOTPOSSIBLE; return ACMERR_NOTPOSSIBLE;
adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign; adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign;
} }
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 && else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{ {
nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152); nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152);
@ -888,7 +927,8 @@ static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE ad
case ACM_STREAMSIZEF_SOURCE: case ACM_STREAMSIZEF_SOURCE:
/* cbSrcLength => cbDstLength */ /* cbSrcLength => cbDstLength */
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3) (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
{ {
nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152); nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152);
if (nblocks == 0) if (nblocks == 0)
@ -898,7 +938,8 @@ static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE ad
nblocks++; nblocks++;
adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5); adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
} }
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 && else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{ {
nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec); nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);