⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpegl3.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * MPEG Layer 3 handling * *      Copyright (C) 2002		Eric Pouech * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <assert.h>#include <stdarg.h>#include <string.h>#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "winuser.h"#include "winnls.h"#include "mmsystem.h"#include "mmreg.h"#include "msacm.h"#include "../msacmdrv.h"#include "mpg123.h"#include "mpglib.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);/*********************************************************************** *           MPEG3_drvOpen */static	DWORD	MPEG3_drvOpen(LPCSTR str){    return 1;}/*********************************************************************** *           MPEG3_drvClose */static	DWORD	MPEG3_drvClose(DWORD dwDevID){    return 1;}typedef struct tagAcmMpeg3Data{    void (*convert)(PACMDRVSTREAMINSTANCE adsi,		    const unsigned char*, LPDWORD, unsigned char*, LPDWORD);    struct mpstr mp;} AcmMpeg3Data;/* table to list all supported formats... those are the basic ones. this * also helps given a unique index to each of the supported formats */typedef	struct{    int		nChannels;    int		nBits;    int		rate;} Format;static Format PCM_Formats[] ={    {1,  8,  8000}, {2,  8,  8000}, {1, 16,  8000}, {2, 16,  8000},    {1,  8, 11025}, {2,  8, 11025}, {1, 16, 11025}, {2, 16, 11025},    {1,  8, 22050}, {2,  8, 22050}, {1, 16, 22050}, {2, 16, 22050},    {1,  8, 44100}, {2,  8, 44100}, {1, 16, 44100}, {2, 16, 44100},};static Format MPEG3_Formats[] ={    {1,  0,  8000}, {2,	0,  8000},  {1,  0, 11025}, {2,	 0, 11025},    {1,  0, 22050}, {2,	0, 22050},  {1,  0, 44100}, {2,	 0, 44100},};#define	NUM_PCM_FORMATS		(sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))#define	NUM_MPEG3_FORMATS	(sizeof(MPEG3_Formats) / sizeof(MPEG3_Formats[0]))/*********************************************************************** *           MPEG3_GetFormatIndex */static	DWORD	MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx){    int 	i, hi;    Format*	fmts;    switch (wfx->wFormatTag)    {    case WAVE_FORMAT_PCM:	hi = NUM_PCM_FORMATS;	fmts = PCM_Formats;	break;    case WAVE_FORMAT_MPEGLAYER3:	hi = NUM_MPEG3_FORMATS;	fmts = MPEG3_Formats;	break;    default:	return 0xFFFFFFFF;    }    for (i = 0; i < hi; i++)    {	if (wfx->nChannels == fmts[i].nChannels &&	    wfx->nSamplesPerSec == fmts[i].rate &&	    wfx->wBitsPerSample == fmts[i].nBits)	    return i;    }    return 0xFFFFFFFF;}/*********************************************************************** *           R16 * * Read a 16 bit sample (correctly handles endianess) */static inline short  R16(const unsigned char* src){    return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));}/*********************************************************************** *           W16 * * Write a 16 bit sample (correctly handles endianess) */static inline void  W16(unsigned char* dst, short s){    dst[0] = LOBYTE(s);    dst[1] = HIBYTE(s);}static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,                      const unsigned char* src, LPDWORD nsrc,                      unsigned char* dst, LPDWORD ndst){    AcmMpeg3Data*       amd = (AcmMpeg3Data*)adsi->dwDriver;    int                 size, ret;    DWORD               dpos = 0;    ret = decodeMP3(&amd->mp, (unsigned char*)src, *nsrc, dst, *ndst, &size);    if (ret != MP3_OK)    {        *ndst = *nsrc = 0;        return;    }    do {        dpos += size;        if (*ndst - dpos < 4608) break;        ret = decodeMP3(&amd->mp, NULL, 0,                        dst + dpos, *ndst - dpos, &size);    } while (ret == MP3_OK);    *ndst = dpos;}/*********************************************************************** *           MPEG3_DriverDetails * */static	LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add){    add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;    add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;    add->wMid = 0xFF;    add->wPid = 0x00;    add->vdwACM = 0x01000000;    add->vdwDriver = 0x01000000;    add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;    add->cFormatTags = 2; /* PCM, MPEG3 */    add->cFilterTags = 0;    add->hicon = NULL;    MultiByteToWideChar( CP_ACP, 0, "WINE-MPEG3", -1,                         add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );    MultiByteToWideChar( CP_ACP, 0, "Wine MPEG3 decoder", -1,                         add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );    MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team (based on mpglib by Michael Hipp)...", -1,                         add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );    MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,                         add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );    add->szFeatures[0] = 0;    return MMSYSERR_NOERROR;}/*********************************************************************** *           MPEG3_FormatTagDetails * */static	LRESULT	MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery){    static WCHAR szPcm[]={'P','C','M',0};    static WCHAR szMpeg3[]={'M','P','e','g','3',0};    switch (dwQuery)    {    case ACM_FORMATTAGDETAILSF_INDEX:	if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE;	break;    case ACM_FORMATTAGDETAILSF_LARGESTSIZE:	if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)        {            aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_MPEGLAYER3 is bigger than PCM */	    break;	}	/* fall thru */    case ACM_FORMATTAGDETAILSF_FORMATTAG:	switch (aftd->dwFormatTag)        {	case WAVE_FORMAT_PCM:		aftd->dwFormatTagIndex = 0; break;	case WAVE_FORMAT_MPEGLAYER3:    aftd->dwFormatTagIndex = 1; break;	default:			return ACMERR_NOTPOSSIBLE;	}	break;    default:	WARN("Unsupported query %08lx\n", dwQuery);	return MMSYSERR_NOTSUPPORTED;    }    aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;    switch (aftd->dwFormatTagIndex)    {    case 0:	aftd->dwFormatTag = WAVE_FORMAT_PCM;	aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);	aftd->cStandardFormats = NUM_PCM_FORMATS;        lstrcpyW(aftd->szFormatTag, szPcm);        break;    case 1:	aftd->dwFormatTag = WAVE_FORMAT_MPEGLAYER3;	aftd->cbFormatSize = sizeof(MPEGLAYER3WAVEFORMAT);	aftd->cStandardFormats = NUM_MPEG3_FORMATS;        lstrcpyW(aftd->szFormatTag, szMpeg3);	break;    }    return MMSYSERR_NOERROR;}static void fill_in_wfx(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate){    MPEGLAYER3WAVEFORMAT*   mp3wfx = (MPEGLAYER3WAVEFORMAT*)wfx;    wfx->nAvgBytesPerSec = bit_rate / 8;    if (cbwfx >= sizeof(WAVEFORMATEX))        wfx->cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);    if (cbwfx >= sizeof(MPEGLAYER3WAVEFORMAT))    {        mp3wfx->wID = MPEGLAYER3_ID_MPEG;        mp3wfx->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;        mp3wfx->nBlockSize = (bit_rate * 144) / wfx->nSamplesPerSec;        mp3wfx->nFramesPerBlock = 1;        mp3wfx->nCodecDelay = 0x0571;    }}/*********************************************************************** *           MPEG3_FormatDetails * */static	LRESULT	MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery){    switch (dwQuery)    {    case ACM_FORMATDETAILSF_FORMAT:	if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;	break;    case ACM_FORMATDETAILSF_INDEX:	afd->pwfx->wFormatTag = afd->dwFormatTag;	switch (afd->dwFormatTag)        {	case WAVE_FORMAT_PCM:	    if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;	    afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;	    afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;	    afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;	    /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible	     * afd->pwfx->cbSize = 0;	     */	    afd->pwfx->nBlockAlign =		(afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;	    afd->pwfx->nAvgBytesPerSec =		afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;	    break;	case WAVE_FORMAT_MPEGLAYER3:	    if (afd->dwFormatIndex >= NUM_MPEG3_FORMATS) return ACMERR_NOTPOSSIBLE;	    afd->pwfx->nChannels = MPEG3_Formats[afd->dwFormatIndex].nChannels;	    afd->pwfx->nSamplesPerSec = MPEG3_Formats[afd->dwFormatIndex].rate;	    afd->pwfx->wBitsPerSample = MPEG3_Formats[afd->dwFormatIndex].nBits;	    afd->pwfx->nBlockAlign = 1;            fill_in_wfx(afd->cbwfx, afd->pwfx, 192000);	    break;	default:	    WARN("Unsupported tag %08lx\n", afd->dwFormatTag);	    return MMSYSERR_INVALPARAM;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -