LIBMAD解码播放器

简单的libmad封装类LibMP3:

// LibmadMP3.h: interface for the LibmadMP3 class.
//
//

#if !defined(AFX_LIBMADMP3_H__0363C03A_CE0B_45E2_BA2D_EB73AB15B66C__INCLUDED_)
#define AFX_LIBMADMP3_H__0363C03A_CE0B_45E2_BA2D_EB73AB15B66C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "mad.h"

class LibmadMP3  
{
public:
	LibmadMP3(const char* filename);
	virtual ~LibmadMP3();
        long  ReadFrame(unsigned char* pcm);

private:
	int   Setup();

private:
    struct mad_stream    stream;
    struct mad_frame     frame;
    struct mad_synth     synth;
    struct mad_header    header;
    mad_timer_t          timer;    

    FILE*                file;            
    long                 readsize; 

	long                 freq;
	long                 bitrate;
	int                  channel;

};

#endif // !defined(AFX_LIBMADMP3_H__0363C03A_CE0B_45E2_BA2D_EB73AB15B66C__INCLUDED_)
cpp文件:

// LibmadMP3.cpp: implementation of the LibmadMP3 class.
//
//
#include "LibmadMP3.h"

//
// Construction/Destruction
//

static unsigned char inputBuffer[4096 + MAD_BUFFER_GUARD];


signed short to_short(mad_fixed_t fixed)
{
    if(fixed >= MAD_F_ONE)
        return (SHRT_MAX);
    if(fixed <= -MAD_F_ONE)
        return (-SHRT_MAX);
    fixed = fixed>>(MAD_F_FRACBITS-15);
    return ((signed short)fixed);
}

LibmadMP3::LibmadMP3(const char* filename):
freq(0),
bitrate(0),
channel(2),
frameCount(0)
{
	file = fopen(filename,"rb");
    mad_stream_init(&stream);
    mad_frame_init(&frame);    
    mad_synth_init(&synth);
    mad_timer_reset(&timer);
}

LibmadMP3::~LibmadMP3()
{
	mad_synth_finish(&synth);
    mad_frame_finish(&frame);
    mad_stream_finish(&stream); 
    fclose(file); 
}

int LibmadMP3::Setup()
{
	size_t    remaining;
	unsigned char* read;

    if(stream.next_frame != NULL)
    {
		remaining = stream.bufend - stream.next_frame;
		memmove(inputBuffer, stream.next_frame, remaining);
        read = inputBuffer + remaining;
        readsize = 4096 - remaining;
	}
	else
	{
		readsize = 4096;
		read = inputBuffer;
		remaining=0;
	}

	readsize = fread(read,1,readsize,file);
	if(readsize <= 0)
    {
		return -1;
	}
        
	mad_stream_buffer(&stream, inputBuffer, readsize+remaining);
    //char dest[100];
    //mad_timer_string(timer, dest, "%02lu:%02u:%02u", MAD_UNITS_HOURS, MAD_UNITS_MILLISECONDS, 0);
    stream.error=(mad_error)0;
	return 0;        
}

long LibmadMP3::ReadFrame(unsigned char* pcm)
{
	if(stream.buffer == NULL)
	{
		if(Setup() == -1) 
			return -1;
	}

	mad_header_decode(&frame.header,&stream);
    
	while(mad_frame_decode(&frame,&stream) == -1)
    {
        if(MAD_RECOVERABLE(stream.error))
        {
            if(stream.error!=MAD_ERROR_LOSTSYNC)
            {
            }
            continue;
        }
        else
	{
            if(stream.error == MAD_ERROR_BUFLEN)
            { 
                if (Setup() == -1) 
					return -1;
                continue;
            }
            return -1;
	}
    }

    mad_synth_frame(&synth,&frame);

	if(bitrate < 128000)
	{
		//获取频率
		freq = synth.pcm.samplerate;           ///采样频率44100
		bitrate = frame.header.bitrate;        ///比特率128000
		channel = (frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 2;   ///声道2 立体声
	}
    
    mad_timer_add(&timer,frame.header.duration);
    
	int j = 0;
    for(int i=0; i<synth.pcm.length; i++)
    {
        signed short sample;
        sample=to_short(synth.pcm.samples[0][i]);

        pcm[j++] = sample & 0xff;
        pcm[j++] = sample >> 8;

        if(MAD_NCHANNELS(&frame.header)==2)
            sample=to_short(synth.pcm.samples[1][i]);

        pcm[j++] = sample & 0xff;
        pcm[j++] = sample >> 8;
    }

    //char dest[120];
    //mad_timer_string(timer,dest, "%lu:%02lu.%03u", MAD_UNITS_MINUTES, MAD_UNITS_MILLISECONDS, 0);
    return j;        
}

long LibmadMP3::GetPlayTime()
{
	return mad_timer_count(timer,MAD_UNITS_MILLISECONDS);
}
截图以及链接地址,百度盘:http://pan.baidu.com/s/1eQlPTmy

CSDN资源:http://download.csdn.net/detail/c_tianzi/8970807









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值