#include <stdio.h>
#include <string.h>
#include <ao/ao.h>
#include <libmad/mad.h>
#include <math.h>
#include <limits.h>
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);
}
unsigned char inputBuffer[4096 + MAD_BUFFER_GUARD];
class libMP3
{
public:
libMP3(const char* filename)
{
file = fopen(filename,"rb");
mad_stream_init(&stream);
mad_frame_init(&frame);
mad_synth_init(&synth);
mad_timer_reset(&timer);
}
~libMP3()
{
mad_synth_finish(&synth);
mad_frame_finish(&frame);
mad_stream_finish(&stream);
fclose(file);
}
int 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 readFrame(unsigned char* pcm)
{
if(stream.buffer == NULL)
{
if(setup() == -1)
return -1;
}
while(mad_frame_decode(&frame,&stream) != 0)
{
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;
}
else
{
return -1;
}
}
mad_synth_frame(&synth,&frame);
//! 获取频率
//freq = synth.pcm.samplerate;
//bitrate = frame.header.bitrate;
//channels = (frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 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;
}
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;
};
int main(int argc, char **argv)
{
int rate = 44100;
int channels = 2;
unsigned char data[4096];
ao_device *device;
ao_sample_format format;
int default_driver;
ao_initialize();
default_driver = ao_default_driver_id();
memset(&format,0,sizeof(format));
format.bits = 16;
format.channels = channels;
format.rate = rate;
format.byte_format = AO_FMT_LITTLE;
libMP3 mp3("我只在乎你.mp3");
device = ao_open_live(default_driver,&format,NULL);
if(device == NULL)
{
fprintf(stderr,"error opening device.\n");
return 1;
}
long len = 0;
unsigned char buffer[4096*2];
while(len = mp3.readFrame(buffer))
{
ao_play(device,(char*)buffer,len);
}
ao_close(device);
ao_shutdown();
return (0);
}