logo资料库

基于C语言的录音播放程序--源代码.pdf

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 附件:测控 1602 DEV C ++ 环境下 控制台应用程序 源代码 E 组 善解人意 成员:王帅、赵永玻、侯雅茹 注意 ;程序运行环境 DEV C++ 5.8.3 创建 Console Application 选择 “工具”——“编译器选项” 在修改软件参数时,不要把原来的数据删除 用空格隔开 输入 -lwinmm 即可支持 vc++6.0 的运行库 如果运行不成功,可在安装 vc++6.0 后重试。 #include #include #include #include #include 1
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 #include #include "mmsystem.h" #pragma comment(lib, "winmm.lib") void WaveInitFormat(LPWAVEFORMATEX m_WaveFormat, WORD nCh, DWORD nSampleRate, WORD BitsPerSample); DWORD CALLBACK MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); void RecordWave(); int simplest_pcm16le_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath); void creat_file(); //输入设备句柄 HWAVEIN phwi; WAVEHDR pwh1; //缓冲区 1 WAVEHDR pwh2;//缓冲区 2 WAVEHDR pwh3;//缓冲区 3 int stop = 0; FILE *fp1; //设置停止标记 //指向存储音频数据的文件指针 typedef struct _WAVFORMAT_ { char ChunkID[4]; uint32_t ChunkSize; char Format[4]; char Subchunk1ID[4]; uint32_t Subchunk1Size; uint16_t AudioFormat; uint16_t NumChannels; uint32_t SampleRate; uint32_t ByteRate; uint16_t BlockAlign; uint16_t BitsPerSample; char Subchunk2ID[4]; uint32_t Subchunk2Size; } WAVFORMAT; int main() { //新建文件,原文件数据被删除 creat_file(); RecordWave(); simplest_pcm16le_to_wave("NocturneNo2inEflat_44.1k_s16le.pcm", //录音函数 "output_nocture.wav"); //将二进制录音信息从内存中提取,并生成 wav 文件 1, 44100, 2
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 return 0; } void RecordWave() { int count = waveInGetNumDevs(); printf("\n 音频输入数量:%d\n", count); //检测录音设备 WAVEINCAPS waveIncaps; MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps, sizeof(WAVEINCAPS)); printf("\n 音频输入设备:%s\n", waveIncaps.szPname); if (MMSYSERR_NOERROR == mmResult) { //HWAVEIN phwi; WAVEFORMATEX pwfx; WaveInitFormat (&pwfx, //录音格式指针 //波形声音的格式,单声道双声道使用 WAVE_FORMAT_PCM.当包含在 WAVEFORMATEXTENSIBLE 结构中时,使用 WAVE_FORMAT_EXTENSIBLE 1, 44100, 16 //声道数量 //采样率 // 采样位数 ); printf("\n 正在打开音频输入设备"); printf("\n 采样参数:声道 44.1kHz 16bit\n"); mmResult = waveInOpen( &phwi, WAVE_MAPPER, &pwfx, (DWORD)(MicCallback), NULL, CALLBACK_FUNCTION );//3 if (MMSYSERR_NOERROR == mmResult) { //WAVEHDR pwh1; char buffer1[10240]; pwh1.lpData = buffer1; pwh1.dwBufferLength = 10240; pwh1.dwUser = 1; pwh1.dwFlags = 0; 3
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 mmResult = waveInPrepareHeader(phwi, &pwh1, sizeof(WAVEHDR));// 为 波 形 输 入设备准备缓冲区 printf("\n 准备缓冲区 1"); //WAVEHDR pwh2; char buffer2[10240]; pwh2.lpData = buffer2; pwh2.dwBufferLength = 10240; pwh2.dwUser = 2; pwh2.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh2, sizeof(WAVEHDR));// 为 波 形 输 入设备准备缓冲区 printf("\n 准备缓冲区 2\n"); // WAVEHDR pwh3; char buffer3[10240]; pwh3.lpData = buffer3; pwh3.dwBufferLength = 10240; pwh3.dwUser = 3; pwh3.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh3, sizeof(WAVEHDR));// 为 波 形 输 入设备准备缓冲区 printf("准备缓冲区 3\n"); if (MMSYSERR_NOERROR == mmResult) { mmResult = waveInAddBuffer(phwi, &pwh1, sizeof(WAVEHDR));// 给 输 入 设 printf("\n 将缓冲区 1 加入音频输入设备"); mmResult = waveInAddBuffer(phwi, &pwh2, sizeof(WAVEHDR));// 给 输 入 设 printf("\n 将缓冲区 2 加入音频输入设备\n"); mmResult = waveInAddBuffer(phwi, &pwh3, sizeof(WAVEHDR));// 给 输 入 设 备增加一个缓存 备增加一个缓存 备增加一个缓存 printf("将缓冲区 3 加入音频输入设备\n"); if (MMSYSERR_NOERROR == mmResult) { mmResult = waveInStart(phwi);//开始录音 printf("\n 开始录音\n"); Sleep(3500); } 4
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 waveInStop(phwi);//停止录音 printf("录音结束\n"); stop = 1; // waveInReset(phwi);//复位 // waveInUnprepareHeader(phwi, &pwh1, sizeof(WAVEHDR));//清除缓存, 在准备缓冲区的时候会调用 waveInPrepareHeader 函数,这个函数调用后,为其分配的内存 就无法通过 delete 或者 free 来释放了,因为在该函数调用后这块内存区域被锁定了。此时 必须调用 waveInUnprepareHeader 函数才能解锁定,然后才能释放。 // // // waveInUnprepareHeader(phwi, &pwh2, sizeof(WAVEHDR)); free(&pwh1); free(&pwh2); waveInClose(phwi);//关闭录音设备 fclose(fp1); printf("关闭录音设备\n"); printf("\n 录音信息提取:\n"); get_message() ; } } } } void creat_file() { if ((fp1 = fopen("E:\\shuai_file.dat", "wb+")) == NULL) { //打开可读写的二进制文件 printf("shuai_file 打开失败!\a\n"); exit(0); } rewind(fp1); } //回调函数 DWORD CALLBACK MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { switch (uMsg) { case WIM_OPEN: //打开设备时消息,在此期间进行一些初始化工作 5
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 printf("\n 设备已经打开...\n"); break; case WIM_DATA: //当缓存已满或者停止录音时的消息,处理这个消息可以对缓存进行 重新分配,实现不限长度录音 printf("\n 正在读取缓冲区%d...\n", ((LPWAVEHDR)dwParam1)->dwUser); if (1 == ((LPWAVEHDR)dwParam1)->dwUser) { int iWlened = fwrite(pwh1.lpData, 1, pwh1.dwBytesRecorded, fp1); fflush(fp1); } if (2 == ((LPWAVEHDR)dwParam1)->dwUser) { int iWlened = fwrite(pwh2.lpData, 1, pwh2.dwBytesRecorded, fp1); fflush(fp1); } if (3 == ((LPWAVEHDR)dwParam1)->dwUser) { int iWlened = fwrite(pwh3.lpData, 1, pwh3.dwBytesRecorded, fp1); fflush(fp1); } waveInAddBuffer(hwavein, (LPWAVEHDR)dwParam1, sizeof(WAVEHDR)); //给输入设 备增加一个缓存 break; case WIM_CLOSE: //关闭录音设备时的消息。 printf("\n 设备已经关闭...\n"); break; default: break; } return 0; } void WaveInitFormat(LPWAVEFORMATEX m_WaveFormat, WORD nCh, DWORD nSampleRate, WORD BitsPerSample) { //录音文件初始化设置 m_WaveFormat->wFormatTag = WAVE_FORMAT_PCM; // 数 据 格 式 , 为 WAVE_FORMAT_PCM 即脉冲编码 6
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 m_WaveFormat->nChannels = nCh; m_WaveFormat->nSamplesPerSec = nSampleRate;// //采样频率 m_WaveFormat->nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample / 8; //声道数 //每秒采样 数据量 m_WaveFormat->nBlockAlign = nCh * BitsPerSample / 8; m_WaveFormat->wBitsPerSample = BitsPerSample; m_WaveFormat->cbSize = 0; //样本大小 } int simplest_pcm16le_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath) { typedef struct WAVE_HEADER { fccID[4]; char unsigned long dwSize; char fccType[4]; //内容为""RIFF //最后填写,WAVE 格式音频的大小 //内容为"WAVE" }WAVE_HEADER; typedef struct WAVE_FMT { //内容为"fmt " //内容为 WAVE_FMT 占的字节数,为 16 fccID[4]; char unsigned long dwSize; unsigned short wFormatTag; //如果为 PCM,改值为 1 unsigned short wChannels; unsigned long dwSamplesPerSec;//采用频率 unsigned //通道数,单通道=1,双通道=2 long dwAvgBytesPerSec;/* ==dwSamplesPerSec*wChannels*uiBitsPerSample/8 */ unsigned short wBlockAlign;//==wChannels*uiBitsPerSample/8 unsigned short uiBitsPerSample;//每个采样点的 bit 数,8bits=8, 16bits=16 }WAVE_FMT; typedef struct WAVE_DATA { fccID[4]; char unsigned long dwSize; //内容为"data" //==NumSamples*wChannels*uiBitsPerSample/8 }WAVE_DATA; if (channels != 1 || sample_rate != 44100) { channels = 1; sample_rate = 44100; } int bits = 16; 7
测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 WAVE_HEADER pcmHEADER; WAVE_FMT WAVE_DATA pcmFMT; pcmDATA; unsigned short m_pcmData; FILE *fp, *fpout; fp = fopen("E:\\shuai_file.dat", "rb"); if (fp == NULL) { printf("Open pcm file error.\n"); return -1; //以只读方式打开文件 } fpout = fopen("E:\\shuai_text.wav", "wb+"); if (fpout == NULL) { printf("Create wav file error.\n"); return -1; } //以读写方式打开 /* WAVE_HEADER */ memcpy(pcmHEADER.fccID, "RIFF", strlen("RIFF")); memcpy(pcmHEADER.fccType, "WAVE", strlen("WAVE")); fseek(fpout, sizeof(WAVE_HEADER), 1); //1=SEEK_CUR /* WAVE_FMT */ //进行 wav 文件初始化 memcpy(pcmFMT.fccID, "fmt ", strlen("fmt ")); pcmFMT.dwSize = 16; pcmFMT.wFormatTag = 1; pcmFMT.wChannels = 1; pcmFMT.dwSamplesPerSec = sample_rate; pcmFMT.uiBitsPerSample = bits; /* ==dwSamplesPerSec*wChannels*uiBitsPerSample/8 */ pcmFMT.dwAvgBytesPerSec pcmFMT.dwSamplesPerSec*pcmFMT.wChannels*pcmFMT.uiBitsPerSample / 8; /* ==wChannels*uiBitsPerSample/8 */ pcmFMT.wBlockAlign = pcmFMT.wChannels*pcmFMT.uiBitsPerSample / 8; fwrite(&pcmFMT, sizeof(WAVE_FMT), 1, fpout); = 8
分享到:
收藏