| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3015 人关注过本帖
标题:关于标准C播放WAV音乐
只看楼主 加入收藏
暗留香
Rank: 2
等 级:论坛游民
帖 子:49
专家分:75
注 册:2009-9-4
结帖率:100%
收藏
 问题点数:0 回复次数:4 
关于标准C播放WAV音乐
看到论坛有人用C些的程序,我看后也写了个。
#include <stdio.h>
#include <dos.h>
typedef struct Header       /* wav头信息结构 */
{
long           riff;    /*RIFF类资源文件头部*/
unsigned long   file_len; /*文件长度*/
char           ni1[12]; /*"WAVE"标志*/
unsigned short format_type;/*格式类别(10H为PCM形式的声音数据)*/
unsigned short Channels; /*Channels 1 = 单声道; 2 = 立体声*/
long           frequency;   /*采样频率*/
long           trans_speed;/*音频数据传送速率*/
char           NI2 [2]; /*过渡字节*/
short       sample_bits;/*样本的数据位数(8/16)*/
char           data[4]; /*数据标记符"data"*/
unsigned long   wav_len; /*语音数据的长度*/
char           NI3 [4]; /*过渡字节*/
} HEAD_WAV;
main()
{
Play_wav("win.wav"); /* 播放文件 */
getch();
}
Play_wav(char *name1)
{ FILE *fp;
HEAD_WAV Wav_file_head;
long       LinAdd;
unsigned short offset;
char           *sample;   /*保存声音文件*/
float n;
fp = fopen(name1, "rb");
fread(&Wav_file_head, sizeof(HEAD_WAV), 1, fp);
sample = (char *)malloc(0xBB80);
fread(sample,0xBB80, 1, fp);
LinAdd = (FP_SEG(sample) << 4) + FP_OFF(sample);   /* 将音频流指针转换成线性地址 */
offset=LinAdd & 0xFFFF; /*计算页偏移*/
outportb (0x0A , 5);             /*Mask 锁DMA通道一*/
outportb (0x0C , 0);             /*清除DMA内部翻转标志*/
outportb (0x0B , 0x49); /*设置成回(播)放模式*/
outportb (0x0A , 1 ); /*激活DMA通道一*/
while(!feof(fp))
{
       outportb (0x83 , LinAdd>>16);   /*将页面写入DMA控制器- -!感觉是把段地址写进去*/
      /*将偏移量低位写入DMA控制器(帖子上写着的是与上0x100,是你错了,
      还是我理解有问题- -!*/
       outportb (0x02 ,offset&0xFF);
       outportb (0x02 ,offset >> 8);   /*偏移高位.................*/
       outportb (0x03 , 0xBB80&0xFF); /*播放块大小低位)*/
       outportb (0x03 , 0xBB80>>8);
       outportb (0x22C,0x40);/* DSP第40h号命令 :设置采样频率*/
       outportb (0x22C, 236); /*真实频率计算公式: 256 - (1000000L / (采样频率 *声道 )).....没搞懂*/
       outportb (0x22C,0x14); /*DSP第14h号命令 :单一周期回放*/
       outportb (0x22C,0xBB80&0xFF); /*传送数据大小,先低后高*/
       outportb (0x22C,0xBB80   >> 8);
       fread(sample,0xBB80, 1, fp);
       sleep(1);
}
fclose(fp);
free(&Wav_file_head);
free(sample);
}


因为只是我的机子使用,所以我忽略了很多步骤。唯一的好处是 播放的时候“啪”的声音小了很多,但是音调还是不对。
声音:8位,采样率25000,2声道。不想转换的话,我也有声音,下载地址:
http://www.
那篇帖子在我帖子用sleep(1);挂起的地方用了重启DSP的函数,我实验的时候使用outportb(1);outportb(0);代替,我所不知道的是,为什么这也能起到“挂起延时”的作用。

现在我也有个想法。采用实时中断,没中断一次执行我循环中的内容一次,然后执行被中断的函数(类似多线程)中断频率应该是1S,遗憾的是,我找不到相关的资料。找到的都是先 outportb(0x1c,hanshu),然后判断外部函数自增来定时的,这缺点让我无法忍受,CPU都是100%运行。

还有,有没多一点的资料大家啊~拜托......
                                                                   纯C的爱好者
                                                                  411713645a@
搜索更多相关主题的帖子: 音乐 播放 WAV 
2009-09-18 09:31
jig
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
可以到本论坛的,C图形专区去搜索一下,有类似的文章和实例

个人网站 -  http://.h001.
2009-09-18 09:36
暗留香
Rank: 2
等 级:论坛游民
帖 子:49
专家分:75
注 册:2009-9-4
收藏
得分:0 
文章和实例我貌似都看了... ...
关于这中断方面的都只是略略提到了那么一点点~~
2009-09-18 09:47
jig
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
你再仔细找找,其实你要解决的问题,C图形专区中早已解决。

而且还将其做成了一套套件,不仅解决了“啪”的那个连接点杂音,还做成了后台式可以播放任意长度并可做循环播放的模块。

个人网站 -  http://.h001.
2009-09-18 11:32
暗留香
Rank: 2
等 级:论坛游民
帖 子:49
专家分:75
注 册:2009-9-4
收藏
得分:0 
恩,我在去看看= =!
2009-09-18 17:34
快速回复:关于标准C播放WAV音乐
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.050951 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved