c语言播放wav音频文件

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <linux/soundcard.h>
#define BUFSIZE 8192
struct RIFF_Header{
char RIFF_ID[4];
uint32_t RIFF_Size;
char RIFF_Format[4];
};
struct Chunk_Header{
char Chunk_ID[4];
uint32_t Chunk_Size;
};
struct Wave_Format{
uint16_t AudioFormat;
uint16_t NumChannels;
uint32_t SampleRate;
uint32_t AvgBytesPerSec;
uint16_t BlockAlign;
uint16_t BitsPerSample;
};
int main(int argc, char *argv[])
{
struct RIFF_Header riff_header;
struct Chunk_Header fmt_chunk, data_chunk;
struct Wave_Format wavfmt;
char buf[BUFSIZE];
FILE * fwave;
int sndfd; 
int status;
int arg;
int readbytes;
int writebytes;
int writed;

if( argc < 2 ){
fprintf(stderr, "Usage: wavplay <filename>\n");
exit(-1);
}

fwave = fopen( argv[1], "r");
if( fwave == NULL ){
fprintf(stderr, "Can't open file %s\n", argv[1]);
exit(-1);
}

fread(&riff_header, 1, sizeof(struct RIFF_Header), fwave);
if( strncmp(riff_header.RIFF_ID, "RIFF", 4) || strncmp(riff_header.RIFF_Format, "WAVE",4)){
fprintf(stderr, "Unknown file format.\n");
exit(-1);
}
sndfd = open("/dev/dsp", O_RDWR);
if (sndfd < 0) {
perror("open of /dev/dsp failed");
exit(-1);
}
fread(&fmt_chunk, 1, sizeof(struct Chunk_Header), fwave);
if( !strncmp(fmt_chunk.Chunk_ID, "fmt ", 4) ){
/* this is a fmt chunk */
fread(&wavfmt, 1, sizeof(struct Wave_Format), fwave);

arg = wavfmt.BitsPerSample;
status = ioctl(sndfd, SOUND_PCM_WRITE_BITS, &arg);
if (status == -1)
perror("SOUND_PCM_WRITE_BITS ioctl failed");
if (arg != wavfmt.BitsPerSample)
perror("unable to set sample size");

arg = wavfmt.NumChannels; 
status = ioctl(sndfd, SOUND_PCM_WRITE_CHANNELS, &arg);
if (status == -1)
perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
if (arg != wavfmt.NumChannels)
perror("unable to set number of channels");
arg = wavfmt.SampleRate;
status = ioctl(sndfd, SOUND_PCM_WRITE_RATE, &arg);
if (status == -1)
perror("SOUND_PCM_WRITE_WRITE ioctl failed");
/* skip extra bytes */
fseek(fwave, fmt_chunk.Chunk_Size - 16 + fmt_chunk.Chunk_Size%2, SEEK_CUR);
}else{
fprintf(stderr, "Can't find fmt chunk.\n");
exit(-1);
}

while( fread(&data_chunk, 1, sizeof(struct Chunk_Header), fwave) != 0 )
if( !strncmp(data_chunk.Chunk_ID, "data", 4) ){
printf("Begin Play\n");
/* this is a data chunk */
writed = 0;
while(writed < data_chunk.Chunk_Size){
readbytes = fread(buf, 1, BUFSIZE, fwave);
writebytes = write(sndfd, buf, readbytes);
if( writebytes != readbytes )
perror("wrote wrong number of bytes");
writed += readbytes;
}
}else{
/* skip unknown chunks */
fseek(fwave, data_chunk.Chunk_Size + fmt_chunk.Chunk_Size%2, SEEK_CUR);
}

fclose(fwave);
close(sndfd);

return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值