win32 - 将原始音频样本转换为wav文件
需要先从麦克风中采样,代码样本可以参考官方示例: WASAPI Capture Shared Event Driven
官方示例采样10s, 我们需要在WriteWaveFile函数下添加生成原始音频的代码。
// Write the contents of a WAV file. We take as input the data to write and the format of that data.
//
bool WriteWaveFile(HANDLE FileHandle, const BYTE *Buffer, const size_t BufferSize, const WAVEFORMATEX *WaveFormat)
{
FILE* _file;
int16_t* _data;
_data = (int16_t*)Buffer;
_file = fopen("utterance.raw", "wb +");
fwrite(_data, 1, BufferSize, _file);
fclose(_file); ...
得到utterance.raw原始音频样本之后,我们需要对其添加wav的头结构来重新生成wav文件
#include <Windows.h>
#include <stdio.h>
#include <MMDeviceAPI.h>
#include <AudioClient.h>
#include <assert.h>
#include <avrt.h>
#include <strsafe.h>
#include <fstream> using namespace std; #pragma warning(disable:4996) struct WAVEHEADER
{
DWORD dwRiff; // "RIFF"
DWORD dwSize; // Size
DWORD dwWave; // "WAVE"
DWORD dwFmt; // "fmt "
DWORD dwFmtSize; // Wave Format Size
}; const BYTE WaveHeader[] =
{
'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', 0x00, 0x00, 0x00, 0x00
}; const BYTE WaveData[] = { 'd', 'a', 't', 'a' }; bool WriteWaveFile(HANDLE FileHandle, const BYTE* Buffer, const size_t BufferSize, WAVEFORMATEX* WaveFormat)
{
DWORD waveFileSize = sizeof(WAVEHEADER) + sizeof(WAVEFORMATEX) + WaveFormat->cbSize + sizeof(WaveData) + sizeof(DWORD) + static_cast<DWORD>(BufferSize);
BYTE* waveFileData = new (std::nothrow) BYTE[waveFileSize];
BYTE* waveFilePointer = waveFileData;
WAVEHEADER* waveHeader = reinterpret_cast<WAVEHEADER*>(waveFileData); if (waveFileData == NULL)
{
printf("Unable to allocate %d bytes to hold output wave data\n", waveFileSize);
return false;
} //
// Copy in the wave header - we'll fix up the lengths later.
//
CopyMemory(waveFilePointer, WaveHeader, sizeof(WaveHeader));
waveFilePointer += sizeof(WaveHeader); //
// Update the sizes in the header.
//
waveHeader->dwSize = waveFileSize - (2 * sizeof(DWORD));
waveHeader->dwFmtSize = sizeof(WAVEFORMATEX) + WaveFormat->cbSize; //
// Next copy in the WaveFormatex structure.
//
CopyMemory(waveFilePointer, WaveFormat, sizeof(WAVEFORMATEX) + WaveFormat->cbSize);
waveFilePointer += sizeof(WAVEFORMATEX) + WaveFormat->cbSize; //
// Then the data header.
//
CopyMemory(waveFilePointer, WaveData, sizeof(WaveData));
waveFilePointer += sizeof(WaveData);
*(reinterpret_cast<DWORD*>(waveFilePointer)) = static_cast<DWORD>(BufferSize);
waveFilePointer += sizeof(DWORD); //
// And finally copy in the audio data.
// CopyMemory(waveFilePointer, Buffer, BufferSize);
//
// Last but not least, write the data to the file.
//
DWORD bytesWritten;
if (!WriteFile(FileHandle, waveFileData, waveFileSize, &bytesWritten, NULL))
{
printf("Unable to write wave file: %d\n", GetLastError());
delete[]waveFileData;
return false;
} if (bytesWritten != waveFileSize)
{
printf("Failed to write entire wave file\n");
delete[]waveFileData;
return false;
}
delete[]waveFileData;
return true;
} //
// Write the captured wave data to an output file so that it can be examined later.
//
void SaveWaveData(BYTE* CaptureBuffer, size_t BufferSize, WAVEFORMATEX* WaveFormat)
{
wchar_t waveFileName[MAX_PATH];
HRESULT hr = StringCbCopy(waveFileName, sizeof(waveFileName), L"WASAPICaptureEventDriven-");
if (SUCCEEDED(hr))
{
GUID testGuid;
if (SUCCEEDED(CoCreateGuid(&testGuid)))
{
wchar_t* guidString;
if (SUCCEEDED(StringFromCLSID(testGuid, &guidString)))
{
hr = StringCbCat(waveFileName, sizeof(waveFileName), guidString);
if (SUCCEEDED(hr))
{
hr = StringCbCat(waveFileName, sizeof(waveFileName), L".WAV");
if (SUCCEEDED(hr))
{
HANDLE waveHandle = CreateFile(waveFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (waveHandle != INVALID_HANDLE_VALUE)
{
if (WriteWaveFile(waveHandle, CaptureBuffer, BufferSize, WaveFormat))
{
printf("Successfully wrote WAVE data to %S\n", waveFileName);
}
else
{
printf("Unable to write wave file\n");
}
CloseHandle(waveHandle);
}
else
{
printf("Unable to open output WAV file %S: %d\n", waveFileName, GetLastError());
}
}
}
CoTaskMemFree(guidString);
}
}
}
} int main()
{
long buffersize = 3528000;// For 10s audio sample, we can set the value of buffersize to 3528000
BYTE* captureBuffer = new (std::nothrow) BYTE[buffersize]; FILE* _file;
_file = fopen("utterance.raw", "rb"); //raw audio path
fread(captureBuffer, 1, buffersize, _file);
fclose(_file); WAVEFORMATEX wavformat;
wavformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
wavformat.nChannels = 2;
wavformat.nSamplesPerSec = 44100;
wavformat.nAvgBytesPerSec = 352800;
wavformat.nBlockAlign = 8;
wavformat.wBitsPerSample = 32;
wavformat.cbSize = 22;
SaveWaveData(captureBuffer, buffersize, &wavformat); return 0;
}
通过将样本的路径添加给fopen,经过一些处理就可以得到了。
补充:
我们也可以使用ofstream来采样,代码见下:
// Write the contents of a WAV file. We take as input the data to write and the format of that data.
//
bool WriteWaveFile(HANDLE FileHandle, const BYTE *Buffer, const size_t BufferSize, const WAVEFORMATEX *WaveFormat)
{
ofstream binaryFile("file.raw", ios::out | ios::binary);
binaryFile.write((char*)Buffer, BufferSize);
binaryFile.close();
...
再使用ifstream获取样本,添加wav的头结构来重新编码。
ifstream infile("file.raw", std::ifstream::binary);
// get size of file
infile.seekg(0, infile.end);
long size = infile.tellg();
infile.seekg(0);
BYTE* captureBuffer = new (std::nothrow) BYTE[size];
infile.read((char*)captureBuffer, size);
infile.close();
WAVEFORMATEX wavformat;
wavformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
wavformat.nChannels = 2;
wavformat.nSamplesPerSec = 44100;
wavformat.nAvgBytesPerSec = 352800;
wavformat.nBlockAlign = 8;
wavformat.wBitsPerSample = 32;
wavformat.cbSize = 22;
SaveWaveData(captureBuffer, size, &wavformat);
win32 - 将原始音频样本转换为wav文件的更多相关文章
- 基于Linux ALSA音频驱动的wav文件解析及播放程序 2012
本设计思路:先打开一个普通wav音频文件,从定义的文件头前面的44个字节中,取出文件头的定义消息,置于一个文件头的结构体中.然后打开alsa音频驱动,从文件头结构体取出采样精度,声道数,采样频率三个重 ...
- HTML5操作麦克风获取音频数据(WAV)的一些基础技能
基于HTML5的新特性,操作其实思路很简单. 首先通过navigator获取设备,然后通过设备监听语音数据,进行原始数据采集. 相关的案例比较多,最典型的就是链接:https://developer. ...
- Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)
本篇项目地址,名字是AudioRecord录音(能暂停,将pch转换为wav),求starhttps://github.com/979451341/Audio-and-video-learning-m ...
- PC-1500的代码存入WAV文件
目录 第1章保存 1 1.1 操作 1 1.2 波形说明 4 1.3 波形整形 5 1.4 压缩 8 第2章载入 9 2.1 操作 9 2.2 音量 9 ...
- 音视频学习系列第(三)篇---wav文件的存储和解析
音视频系列 什么是wav wav是一种无损的音频文件格式,wav文件有两部分,第一部分是文件头,记录一些重要的参数信息,如音频的采样率,通道数,数据位宽,第二部分是数据部分,数据部分可以是PCM,也可 ...
- 将任意音频格式文件转换成16K采样率16bit的wav文件
此转换需要使用ffmpeg 假设有目录 d:\录音 目录有 张三.m4a, 李四.m4a xxx.m4a(其他任意格式音频触类旁通可以把 *.m4a改成*.*).批量转换成采样率16K,有符号,16b ...
- linux下alsa架构音频驱动播放wav格式文件
#include<stdio.h> #include<stdlib.h> #include <string.h> #include <alsa/asoundl ...
- Linux音频编程--使用ALSA库播放wav文件
在UBUNTU系统上使用alsa库完成了对外播放的wav文件的案例. 案例代码: /** *test.c * *注意:这个例子在Ubuntu 12.04.1环境下编译运行成功. * */ #inclu ...
- Windwos平台上ffmpeg解码音频并且保存到wav文件中
先附上代码,测试通过 #include <stdio.h> #include <math.h> #include "libavutil/avstring.h" ...
- Beginning SDL 2.0(6) 音频渲染及wav播放
前面几篇关于SDL的文章介绍的是以画面为主,这里介绍下SDL中针对音频播放提供的机制,以及如何应用. 对于音频而言,有几个概念需要事先了解下,采样率.声道数.量化位数,如果你不清楚的话,麻烦先了解下这 ...
随机推荐
- [转帖]docker build 中的 -f 选项
https://www.jianshu.com/p/06c35fd299b7 需要注意的是,在 docker build 命令接收的参数中,提供给 docker build 命令的 -f 选项应该 D ...
- [转帖]sudo 命令_su、sudo、sudo su、sudo -i的用法和区别
sudo 命令 1.sudo 简介 sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等.这样不仅减少了root用户 ...
- [转帖]tar、gzip、zip、jar是什么,怎么查看?
https://www.cnblogs.com/codelogs/p/16702759.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 如果你是后 ...
- 定位解析一个因脚本劫持导致webpack动态加载异常的问题
问题描述 项目现场的前端项目在点击顶部的导航栏切换不同的模块时,会有小概率出现模块加载报错的情况: 我们的前端项目里是有基于react-loadable做的懒加载的,上图的12.be789340.ch ...
- 你不知道的Linux shell操作
Linux Shell 脚本入门教程 Linux Shell 脚本是一种强大的工具,它允许您自动化日常任务和复杂操作.在本教程中,我们将逐步介绍几个实用的 Shell 脚本示例.每个示例都将详细说明, ...
- dump分析器winbdg
工具: winbdg WinDBG不是专门用于调试.Net程序的工具,它更偏向于底层,可用于内核和驱动调试.进行普通的.Net程序调试还是使用微软专为.Net开发的调试工具MDBG更方便一些.但是Wi ...
- 4.3 Windows驱动开发:监控进程与线程对象操作
在内核中,可以使用ObRegisterCallbacks这个内核回调函数来实现监控进程和线程对象操作.通过注册一个OB_CALLBACK_REGISTRATION回调结构体,可以指定所需的回调函数和回 ...
- Pdfium.Net.Free 一个免费的Pdfium的 .net包装器--打开大文件处理
项目地址: Pdfium.Net:https://github.com/1000374/Pdfium.Net PdfiumViewer:https://github.com/1000374/Pdfiu ...
- CentOS7设置防火墙
①查看防火状态 systemctl status firewalld service iptables status ②暂时关闭防火墙 systemctl stop firewalld service ...
- .net 工具箱不可用/怎样初始化vs环境 解决方案
在开始菜单里面执行的.开始菜单->Microsoft Visual Studio 2005->Visual Studio Tools->Visual Studio 2005 命令提示 ...