| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 8444 人关注过本帖
标题:C语言怎么播放音乐
只看楼主 加入收藏
weichaogood
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2009-5-11
收藏
得分:0 
对啊,好神秘啊!
2009-11-10 22:29
小J
Rank: 8Rank: 8
等 级:等待验证会员
威 望:1
帖 子:282
专家分:704
注 册:2009-6-18
收藏
得分:0 
高手们指导一下啊,怎么给程序添加背景音乐啊
2009-11-10 22:50
fuqingjun
Rank: 2
来 自:山东
等 级:论坛游民
帖 子:48
专家分:80
注 册:2009-11-2
收藏
得分:0 
恩,好吧,我给你个代码:不过你看到代码以后要弄懂它,并给我回帖说你学到的东西。监督你一下哈。我正在找朋友呢

我是猪猪,我很想进步,寻志同道合者革命途中并肩行路!
2009-11-12 22:55
fuqingjun
Rank: 2
来 自:山东
等 级:论坛游民
帖 子:48
专家分:80
注 册:2009-11-2
收藏
得分:15 
PLAYWAV.rar (11.01 KB)

这是这断代码用turboc3.0 编译后的成品。

强烈建议你学习一下声卡知识和文件结构知识,以便能做个多功能的音乐播放器。

这个代码只能播放 8位的wav格式文件,你下个录音程序自己录一段8位的wav音乐更名为win.wav 并把它放在和playwav.exe同样的目录下。只要双击playwav.exe便会播放音乐,你要是认真研究一下代码就知道该怎么做了。
#include<stdio.h>
#include<fcntl.h>
#include<dos.h>
/* wav文件结构 */
typedef struct WaveData
{
unsigned long sample_lenth;
unsigned short rate;
unsigned short channels;
unsigned char time_constant;
char bit_res;
char *name_wav;

char *sample;
} WAV;
/* wav头信息结构 */
typedef struct HeaderType
{
long riff; /*RIFF类资源文件头部*/
unsigned long file_len; /*文件长度*/
char wave[4]; /*"WAVE"标志*/
char fmt [4]; /*"fmt"标志*/
char NI1 [4]; /*过渡字节*/
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;
int G_base; /* 记录DSP芯片的基址 */
int G_port; /* 端口的基址 */



int install_DSP()
{
int i, g_address[14] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260,0x270,0x280,0x290,0x300,0x310,0x320,0x330,0x340};
for (i = 0; i < 14; i++)
{
if (RestDSP(g_address[i]))
{
G_port = g_address[i]; /* 记录端口基地址 */
return 1;
}
}

return 0;
}

int RestDSP(int Test)
{
/* 重置DSP */
outportb(Test + 0x6, 1);
delay(50); /* 延时是必须的 */
outportb(Test + 0x6, 0);
delay(50);
/* 如果重置成功则检查 */
if ((inportb(Test + 0xE) & 0x80 == 0x80)
&& (inportb(Test + 0xA) == 0xAA))
{
G_base = Test;
return 1;
}
else
{
return 0;
}
}
WAV *Load_wav(char *name_wav)
{
FILE *fp;
HEAD_WAV Wav_file_head;
WAV *Wav_file;

/* 打开声音文件 */
if ((fp = fopen(name_wav, "rb")) == NULL)
{
printf("can’t open wav file!");
return NULL;
}
/* 开辟空间 */
if ((Wav_file = (WAV *)malloc(sizeof(WAV))) == NULL)
{
printf("have’t mem!");
fclose(fp);
return NULL;
}

/* 读取文件头信息 */
fread(&Wav_file_head, sizeof(HEAD_WAV), 1, fp);
/* 检查RIFF头 0x46464952 其实就是字符串 "RIFF"
这样好处理一些,毕竟比较数字比比较字符串要省事的多 */
if (Wav_file_head.riff != 0x46464952)
{
printf("isn’t wav file!");
fclose(fp);
return NULL;
}
/* 获取文件名 */
Wav_file->name_wav = name_wav;
Wav_file->rate = Wav_file_head.frequency; /* 采样频率 */
Wav_file->channels = Wav_file_head.Channels; /* 声道 */
/* 计算真实采样率 */
Wav_file->time_constant = 256 - (1000000L / (Wav_file->rate * Wav_file->channels));

/* 获取声音数据长度 */
Wav_file->sample_lenth = Wav_file_head.file_len - 50;

/* 分配内存,以存放声音数据 */
if ((Wav_file->sample = (char *)malloc(Wav_file->sample_lenth)) == NULL)
{
printf("have’t mem!");
fclose(fp);
return NULL;
}

/* 若文件过长 */
if (Wav_file_head.file_len - 50 > 0xC7FF)
{
/* 读取声音数据 */
fread(Wav_file->sample, 0xC7FF, 1, fp);
}
else
{
/* 读取声音数据 */
fread(Wav_file->sample, Wav_file->sample_lenth, 1, fp);
}
fclose(fp);

return Wav_file;
}
void Play_wav(WAV *Wav_file)
{
FILE *fp;
long LinearAddress;
unsigned short page, offset;
int i;
unsigned int count; /* 记录共分为几块播放 */
unsigned int romd; /* 记录不满一块的数据段长度,以便最后依次播放 */
/* 获取块数,和余数 */
count = (int)(Wav_file->sample_lenth / 51199);
romd = (int)(Wav_file->sample_lenth % 51199);

if (romd != 0)
{
count++;
}

/* 将音频流指针转换成线性地址 */
LinearAddress = FP_SEG(Wav_file->sample);
LinearAddress = (LinearAddress << 4) + FP_OFF(Wav_file->sample);
page = LinearAddress >> 16; /*计算页*/
offset = LinearAddress & 0xFFFF; /*计算页偏移*/

/*注意 :这个操作只能工作于DMA的第一通道*/
outportb (0x0A, 5); /*Mask 锁DMA通道一*/
outportb (0x0C, 0); /*清除DMA内部翻转标志*/
outportb (0x0B, 0x49); /*设置成回(播)放模式*/



outportb ( 0x83, page); /*将页面写入DMA控制器*/
outportb ( 0x03, 0xC7FF & 0x100);
outportb ( 0x03, 0xC7FF >> 8);
/* 开启声卡 */
WriteDSP(0xD1);
if (count == 1) /* 文件长度 <= 51199bit */
{
WriteDSP(0x40); /* DSP第40h号命令 :设置采样频率 */
WriteDSP(Wav_file->time_constant ); /* Write time constant */

outportb ( 0x02, offset & 0x100); /*将偏移量写入DMA控制器*/
outportb ( 0x02, offset >> 8);

outportb ( 0x0A, 1 ); /*激活DMA通道一*/
WriteDSP( 0x14 ); /*DSP第14h号命令 :单一周期回放*/
WriteDSP( Wav_file->sample_lenth & 0xFF );
WriteDSP( Wav_file->sample_lenth >> 8);
}
else /* 文件长度 > 51199bit */
{
fp = fopen(Wav_file->name_wav, "rb");
fseek(fp, (long)(sizeof(HEAD_WAV) + 0xC7FF), SEEK_SET);
for (i = 0; i < count; i++)
{
WriteDSP(0x40); /* DSP第40h号命令 :设置采样频率 */
WriteDSP(Wav_file->time_constant ); /* Write time constant */

outportb ( 0x02, offset & 0x100); /*将偏移量写入DMA控制器*/
outportb ( 0x02, offset >> 8);

outportb ( 0x0A, 1 ); /*激活DMA通道一*/
WriteDSP( 0x14 ); /*DSP第14h号命令 :单一周期回放*/

if (i != (count - 1))
{
WriteDSP( 0xC7FF & 0xFF );
WriteDSP( 0xC7FF >> 8);

/*重置DSP*/
RestDSP(G_port);
fread(Wav_file->sample, 0xC7FF, 1, fp);
}
else
{
WriteDSP( romd & 0xFF );
WriteDSP( romd >> 8);

/*重置DSP*/
RestDSP(G_port);
fread(Wav_file->sample, romd, 1, fp);
}
}
fclose(fp);
}

/*关闭声卡*/
WriteDSP(0xD3);
/*重置DSP*/
RestDSP(G_port);
}
int WriteDSP(int value)
{
/*等待DSP接收一个字节*/
while ((inportb(G_base + 0xC) & 0x80) == 0x80);
/*发送字节*/
outportb (G_base + 0xC, value);
}


void Destroy_wav(WAV *Wav_file)
{
if (Wav_file)
{
free(Wav_file->sample);
Wav_file->sample = NULL;
free(Wav_file);
Wav_file = NULL;
}
}

void main(void)
{
WAV *Wav_file; /* 申请音乐文件 */
if (!install_DSP()) /* 初始化DSP */
{
printf("can’t install DSP!");
getch();
return(0);
}
/* 加载声音文件 */
if ((Wav_file = Load_wav("win.wav")) == NULL)
{
printf("can’t load wav!");
getch();
return(0);
}
Play_wav(Wav_file); /* 播放文件 */
getch();
Destroy_wav(Wav_file); /* 销毁文件 */
}

我是猪猪,我很想进步,寻志同道合者革命途中并肩行路!
2009-11-12 23:05
fuqingjun
Rank: 2
来 自:山东
等 级:论坛游民
帖 子:48
专家分:80
注 册:2009-11-2
收藏
得分:0 
还有你说要添加背景音乐用我上面的代码可实现不了。不过你学习一下 “中断” 知识后将上面的程序稍作改动就会了。

我是猪猪,我很想进步,寻志同道合者革命途中并肩行路!
2009-11-12 23:08
小J
Rank: 8Rank: 8
等 级:等待验证会员
威 望:1
帖 子:282
专家分:704
注 册:2009-6-18
收藏
得分:0 
首先谢谢一下LS的指导。不过我用的软件是vc6.0的啊。不能运行你的程序啊。不过还是十分感谢你指导。希望我们可以做朋友啊!你的代码我会好好的研究的,到时候要是有哪里不懂的话希望指教一下啊!!
2009-11-12 23:21
fuqingjun
Rank: 2
来 自:山东
等 级:论坛游民
帖 子:48
专家分:80
注 册:2009-11-2
收藏
得分:0 
回复 15楼 fuqingjun
所以我说,你研究一下上面的代码的意思, 学会方法, 稍微改动就可用在vc6.0上。c语言学的是方法。是思想。别用别人的成品,自己动手

我是猪猪,我很想进步,寻志同道合者革命途中并肩行路!
2009-11-14 21:08
soky
Rank: 4
等 级:业余侠客
帖 子:126
专家分:228
注 册:2009-7-13
收藏
得分:0 
以下是引用viky2003在2009-11-10 21:46:51的发言:

#include <stdlib.h>

int main(int argc, char* argv[])
{
    system("\"C:\\Program Files\\Tencent\\QQ\\Bin\\QQ.exe\"");
    return 0;
}
这个是C中运行QQ.exe。
你可以运行播放器程序,后面传参数比如:
syst ...
后边再加xx.mp3无法播放的,那是什么原因呢,谢谢

2009-11-14 23:20
coam8899
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2009-11-15
收藏
得分:0 
fuqingjun同志,看到乐于助人的你,我给你发了一个消息里面有我的联系方式,但是却出现了以外。如果你不介意的话请加我的QQ或邮件联系,希望我们能成为好朋友。QQ:22112338    mail:5r1@
2009-11-15 05:51
快速回复:C语言怎么播放音乐
数据加载中...
 
   



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

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