使用LibMad解码MP3,Windows上播放MP3,MP3转WAV实例代码

概述:

闲着也是闲着,就学习了下LibMad解码MP3(解码成PCM数据流),顺便把Windows上播放PCM,以及PCM文件转换成WAV文件学习了下。以前做过PCM转WAV,原理很简单,就是在PCM流前面加上一个WAV数据头。借鉴了网上的一些文章,感谢大家。

LIbMad解码部分:

在初始化LibMad前,我们需要定义回调函数

//读取mp3资源的函数
mad_flow input_fun(void *data, struct mad_stream *stream)
{
	MP3File* pMp3 = (MP3File*)data;
	if ( stream->buffer == NULL )
	{
		mad_stream_buffer(stream, pMp3->szBuffer, pMp3->nBufferUse);
		return MAD_FLOW_CONTINUE;
	}

	pMp3->nBufferPos = stream->next_frame - pMp3->szBuffer;
	int nRemain = pMp3->nBufferUse - pMp3->nBufferPos;
	memcpy(pMp3->szBuffer, pMp3->szBuffer+pMp3->nBufferPos, nRemain);
	size_t nRead = fread(pMp3->szBuffer+nRemain, 1, pMp3->nBufferPos, pMp3->fp);
	if ( nRead <= 0 )
	{
		return MAD_FLOW_STOP;
	}
	pMp3->nBufferPos = 0;
	pMp3->nBufferUse = nRemain + nRead;
	mad_stream_buffer(stream, pMp3->szBuffer, pMp3->nBufferUse);
	return MAD_FLOW_CONTINUE;
}

//处理mp3头部信息的函数
mad_flow header_fun(void *data, struct mad_header const *header)
{
	return MAD_FLOW_CONTINUE;
}

输出函数
mad_flow output_fun(void *data, struct mad_header const *header, struct mad_pcm *pcm)
{
	int *left_ch = pcm->samples[0], *right_ch = pcm->samples[1];
	int nLength = pcm->length;
	int nMalloc = nLength*2;
	if (pcm->channels == 2)//双声道,存储空间扩大4倍
		nMalloc = nLength * 4;
	if ( g_pBuffer == NULL )
		g_pBuffer = (unsigned char*)malloc(nMalloc);
	else
	{
		if ( g_nSize<nMalloc )
		{
			free(g_pBuffer);
			g_pBuffer = (unsigned char*)malloc(nMalloc);
		}
	}
	g_nSize = nMalloc;
	unsigned char* pBase = g_pBuffer;
	for (int i = 0; i < nLength; ++i)
	{
		signed int sample = scale(*left_ch++);
		*(pBase++) = sample >> 0;
		*(pBase++) = sample >> 8;
		if (pcm->channels == 2)
		{
			signed int sample = scale(*right_ch++);
			*(pBase++) = sample >> 0;
			*(pBase++) = sample >> 8;
		}
	}
	//播放
	g_pcmPlayer.Play(g_pBuffer, nMalloc);

// 	FILE* fp = fopen("mp3.dat", "ab+");
// 	if( fp )
// 	{
// 		fwrite(pBase, 1, nMalloc, fp);
// 		fclose(fp);
// 	}
	g_nFrames&#
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值