#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/soundcard.h>
#include <sys/ioctl.h>
#include <string.h>
#include "mad.h"
#include "main.h"
int soundfd;
int mp3_fd[2][3];
struct buffer
{
unsigned char const *start;
unsigned long length;
};
/*int decode(unsigned char const *, unsigned long);
void set_dsp(void);
int play_control(int next, int pro);
int play(int flag);
int creat_soundfd(void);
int writedsp(int c);*/
/*int main(int argc, const char *argv[])
{
//creat_soundfd();
set_dsp();
play(1);
play_control(0, 1);
return 0;
}*/
int play(int flag)
{
struct stat file;
void *address;
switch(flag)
{
case 0:
if((mp3_fd[0][0] = open("1.mp3", O_RDONLY)) < 0)
{
perror("open 1");
exit(1);
}
fstat(mp3_fd[0][0], &file);
address = mmap(0, file.st_size, PROT_READ, MAP_SHARED,mp3_fd[0][0], 0);
mp3_fd[1][0] = 1;
decode(address, file.st_size);
if(munmap(address, file.st_size) == -1)
perror("mumap");
close(mp3_fd[0][0]);
mp3_fd[1][0] = 0;
case 1:
if((mp3_fd[0][1] = open("2.mp3", O_RDONLY)) < 0)
{
perror("open 1");
exit(1);
}
fstat(mp3_fd[0][1], &file);
address = mmap(0, file.st_size, PROT_READ, MAP_SHARED,mp3_fd[0][1], 0);
mp3_fd[1][1] = 1;
decode(address, file.st_size);
if(munmap(address, file.st_size) == -1)
perror("mumap");
close(mp3_fd[0][1]);
mp3_fd[1][1] = 0;
case 2:
if((mp3_fd[0][2] = open("3.mp3", O_RDONLY)) < 0)
{
perror("open 1");
exit(1);
}
fstat(mp3_fd[0][2], &file);
address = mmap(0, file.st_size, PROT_READ, MAP_SHARED,mp3_fd[0][2], 0);
mp3_fd[1][2] = 1;
decode(address, file.st_size);
if(munmap(address, file.st_size) == -1)
perror("mumap");
close(mp3_fd[0][2]);
mp3_fd[1][2] = 0;
}
return 0;
}
int play_control(int next, int pro)
{
int i = 0;
while(i<3)
{
if(i == 2)
{
if(mp3_fd[1][2] == 1 && mp3_fd[1][0] == 0)
break;
}
else
{
if(mp3_fd[1][i] == 1 && mp3_fd[1][i+1] == 0)
break;
}
i++;
}
if(next >= 0)
{
if(i == 2)
play(0);
else
play(i+1);
}
if(pro >= 0)
{
if(i == 0)
play(2);
else
play(i - 1);
}
return 0;
}
int creat_soundfd(void)
{
if((mp3_fd[0][0] = open("1.mp3", O_RDONLY)) < 0)
{
perror("open 1");
exit(1);
}
if((mp3_fd[0][1] = open("2.mp3", O_RDONLY)) < 0)
{
perror("open 2");
exit(1);
}
if((mp3_fd[0][2] = open("3.mp3", O_RDONLY)) < 0)
{
perror("open 3");
exit(1);
}
return 0;
}
int writedsp(int c)
{
return write(soundfd, (char *)&c, 1);
}
void set_dsp(void)
{
int format = AFMT_S16_LE;
int channels = 2;
unsigned int rate = 44100;
if((soundfd = open("/dev/dsp", O_RDWR)) < 0)
{
printf("don't open the dsp\n");
exit(1);
}
ioctl(soundfd, SNDCTL_DSP_SETFMT, &format);
ioctl(soundfd, SNDCTL_DSP_SYNC, 0);
ioctl(soundfd, SNDCTL_DSP_CHANNELS, &channels);
ioctl(soundfd, SNDCTL_DSP_SPEED, &rate);
}
/*
* This is the input callback. The purpose of this callback is to (re)fill
* the stream buffer which is to be decoded. In this example, an entire file
* has been mapped into memory, so we just call mad_stream_buffer() with the
* address and length of the mapping. When this callback is called a second
* time, we are finished decoding.
*/
static enum mad_flow input(void *data, struct mad_stream *stream)
{
struct buffer *buffer = data;
if (!buffer->length)
return MAD_FLOW_STOP;
mad_stream_buffer(stream, buffer->start, buffer->length);
buffer->length = 0;
return MAD_FLOW_CONTINUE;
}
/*
* The following utility routine performs simple rounding, clipping, and
* scaling of MAD's high-resolution samples down to 16 bits. It does not
* perform any dithering or noise shaping, which would be recommended to
* obtain any exceptional audio quality. It is therefore not recommended to
* use this routine if high-quality output is desired.
*/
static inline signed int scale(mad_fixed_t sample)
{
/* round */
sample += (1L << (MAD_F_FRACBITS - 16));
/* clip */
if (sample >= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE)
sample = -MAD_F_ONE;
/* quantize */
return sample >> (MAD_F_FRACBITS + 1 - 16);
}
/*
* This is the output callback function. It is called after each frame of
* MPEG audio data has been completely decoded. The purpose of this callback
* is to output (or play) the decoded PCM audio.
*/
static enum mad_flow output(void *data, struct mad_header const *header, struct mad_pcm *pcm)
{
unsigned int nchannels, nsamples;
mad_fixed_t const *left_ch, *right_ch;
//unsigned int rate = 44100;
/* pcm->samplerate contains the sampling frequency */
//rate = pcm->samplerate;
nchannels = pcm->channels;
nsamples = pcm->length;
left_ch = pcm->samples[0];
right_ch = pcm->samples[1];
//if(rate != prerate)
//{
//ioctl(soundfd, SNDCTL_DSP_SPEED, &rate);
//prerate = rate;
//}
while (nsamples--)
{
signed int sample;
/* output sample(s) in 16-bit signed little-endian PCM */
sample = scale(*left_ch++);
writedsp((sample >> 0) & 0xff);
writedsp((sample >> 8) & 0xff);
if (nchannels == 2) {
sample = scale(*right_ch++);
writedsp((sample >> 0) & 0xff);
writedsp((sample >> 8) & 0xff);
}
}
return MAD_FLOW_CONTINUE;
}
static enum mad_flow error(void *data, struct mad_stream *stream, struct mad_frame *frame)
{
struct buffer *buffer = data;
fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
stream->error, mad_stream_errorstr(stream),
stream->this_frame - buffer->start);
/* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */
return MAD_FLOW_CONTINUE;
}
/*
* This is the function called by main() above to perform all the
* decoding. It instantiates a decoder object and configures it with the
* input, output, and error callback functions above. A single call to
* mad_decoder_run() continues until a callback function returns
* MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and
* signal an error).
*/
int decode(unsigned char const *start, unsigned long length)
{
struct buffer buffer;
struct mad_decoder decoder;
int result;
/* initialize our private message structure */
buffer.start = start;
buffer.length = length;
/* configure input, output, and error functions */
mad_decoder_init(&decoder, &buffer, input, 0 /* header */, 0 /* filter */, output, error, 0 /* message */);
/* start decoding */
result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
/* release the decoder */
mad_decoder_finish(&decoder);
return result;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
mp3.tar.gz (6个子文件)
mp3
mad.h 26KB
main.h 823B
main.c 328B
music.c 7KB
tags 19KB
Makefile 503B
共 6 条
- 1
资源评论
- 骑墙头等红杏2012-12-19很不错。。之前我也用Qt来实现过音乐播放器。。不过都是用Qt里面的PHONON。。都不到考虑MP3解码的。。学习了。。谢谢楼主。。
- hwwr2014-04-28效果还不错,分数太高了。。。
- daphant2013-05-28效果还不错,就是太贵了
- aqu_40682013-10-08可以播 放,直接借鉴,谢谢
zzs625005
- 粉丝: 2
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功