In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces how C++ reads PCM data in wav files. It is very detailed and has certain reference value. Friends who are interested must finish reading it.
Preface
Wav files usually use PCM format data to store audio, and the data in this format can be played directly. In order to read the data in wav files, we first need to obtain header information. The file structure of wav is divided into multiple chunk. What we need to do is to identify these chunk information and obtain the audio format and data.
First, how to achieve it?
First of all, we need to construct the wav header, and all the audio information of the wav file is stored in the header. All we need to do is read the wav header information and record the relevant parameters of PCM.
1. Define the header structure
Only define the wav header in PCM format, and only the following three structures are needed for data in PCM format.
Struct WaveRIFF;struct WaveFormat;struct WaveData
two。 Read header information
You need to read the header information after opening the file, and you need to get the format of the sound and the length of the data.
WaveRIFF riff;WaveFormat format;WaveData data;int userDataSize;f= fopen (fileName.c_str (), "rb+"); / / read header information fread (& riff, 1, sizeof (riff), f); fread (& format, 1, sizeof (format), f); / / check whether the header information is correct / / slightly / / find the starting position of data chunk// / record data
3. Read data
After getting the header information, you will know the location and length of the data, and you only need to read the file directly.
/ / Jump to data start position seek (f, _ dataOffset, SEEK_SET); / / read data fread (buf, 1, bufLength, f); 2. Complete code
The complete code always has three parts, header structure, WavFileReader.h, WavFileReader.cpp.
1. Head structure
# pragma pack (push,1) struct WaveRIFF {const char id [4] = {'Renewal,' Flying,'F'}; uint32_t fileLength; const char waveFlag [4] = {'Waring,' Vince,'E'};} Struct WaveFormat {const char id [4] = {'fame,' tween,'}; uint32_t blockSize = 16; uint16_t formatTag; uint16_t channels; uint32_t samplesPerSec; uint32_t avgBytesPerSec; uint16_t blockAlign; uint16_t bitsPerSample;} Struct WaveData {const char id [4] = {'daddy,' tween,'a'}; uint32_t dataLength;}; # pragma pack (pop)
2.WavFileReader.h
# pragma once#include/**** @ Project: AC.WavFileWriter* @ Decription: wav file reading tool * this release only supports pcm reading and does not deal with byte order. Riff files are small-end, which is usually fine on intel devices and needs to be processed on java virtual machines. * @ Verision: v1.0.0.0* @ Author: Xin Nie* @ Create: 2019-4-10 11 Xin Nie* 17 * @ LastUpdate: 2019-4-16 10 14 15 45 00 bicycle * * Copyright @ 2019. All rights reserved.****/namespace AC {/ wav file read object / class WavFileReader {public: / / Construction method / WavFileReader () / destructor / ~ WavFileReader (); / Open wav file / File name / whether the bool OpenWavFile (const std::string& fileName) has been opened successfully / / close file / void CloseFlie (); / read audio data / external cache / cache length / read length int ReadData (unsigned char* buf, int bufLength) / set the read position / read position void SetPosition (int position); / get the read position / read position int GetPosition () / get file length / File length int GetFileLength (); / get audio data length / Audio data length int GetDataLength () / get the number of channels / the number of channels int GetChannels (); / get the sampling rate / sampling rate, in hz int GetSampleRate () / get bit depth / bit depth in bits int GetBitsPerSample (); private: void* _ file = nullptr; uint32_t _ fileLength = 0; uint32_t _ dataLength = 0; int _ channels = 0; int _ sampleRate = 0; int _ bitsPerSample = 0 Int _ dataOffset = 0;};}
3.WavFileReader.cpp
# include "WavFileReader.h" namespace AC {WavFileReader::WavFileReader () {} WavFileReader::~WavFileReader () {CloseFlie ();} bool WavFileReader::OpenWavFile (const std::string& fileName) {if (_ file) {printf ("File already opened!\ n"); return false;} WaveRIFF riff; WaveFormat format WaveData data; int userDataSize; _ file = fopen (fileName.c_str (), "rb+"); if (! _ file) {printf ("failed to open file!\ n"); return false } / / read header information if (fread (& riff, 1, sizeof (riff), static_cast (_ file))! = sizeof (riff)) {printf ("File read error, failed to read riff!\ n"); goto error } if (std::string (riff.id, 4)! = "RIFF" | | std::string (riff.waveFlag, 4)! = "WAVE") {printf ("incorrect header information, not wav file!\ n"); goto error } if (fread (& format, 1, sizeof (format), static_cast (_ file))! = sizeof (format)) {printf ("file read error, failed to read format!\ n"); goto error } if (std::string (format.id, 4)! = "fmt") {printf ("incorrect header information, missing fmt!\ n"); goto error;} if (format.formatTag! = 1) {printf ("Program does not support, data format is not pcm, only supports data in pcm format!\ n") Goto error;} userDataSize = format.blockSize-sizeof (format) + 8; if (userDataSize
< 0) { printf("头部信息不正确,blockSize大小异常!\n"); goto error; } else if (userDataSize >0) {if (fseek (static_cast (_ file), userDataSize, SEEK_CUR)! = 0) {printf ("File read error!\ n"); goto error }} while (1) {if (fread (& data, 1, sizeof (data), static_cast (_ file))! = sizeof (data)) {printf ("File read error!\ n"); goto error;} If (std::string (data.id, 4)! = "data") {if (fseek (static_cast (_ file), data.dataLength, SEEK_CUR)! = 0) {printf ("File read error!\ n"); goto error;} continue } break;} _ dataOffset = ftell (static_cast (_ file)); _ fileLength = riff.fileLength+8; _ dataLength = data.dataLength; _ channels = format.channels; _ sampleRate = format.samplesPerSec; _ bitsPerSample = format.bitsPerSample; return true Error: if (fclose (static_cast (_ file)) = = EOF) {printf ("File closure failed!\ n");} _ file = nullptr; return false } void WavFileReader::CloseFlie () {if (_ file) {if (fclose (static_cast (_ file)) = = EOF) {printf ("File closure failed!\ n");} _ file = nullptr }} int WavFileReader::ReadData (unsigned char* buf, int bufLength) {if (ftell (static_cast (_ file)) > = _ dataOffset + _ dataLength) return 0; return fread (buf, 1, bufLength, static_cast (_ file)) } void WavFileReader::SetPosition (int postion) {if (fseek (static_cast (_ file), _ dataOffset + postion, SEEK_SET)! = 0) {printf ("location failed!\ n");}} int WavFileReader::GetPosition () {return ftell (static_cast (_ file))-_ dataOffset } int WavFileReader::GetFileLength () {return _ fileLength;} int WavFileReader::GetDataLength () {return _ dataLength;} int WavFileReader::GetChannels () {return _ channels;} int WavFileReader::GetSampleRate () {return _ sampleRate;} int WavFileReader::GetBitsPerSample () {return _ bitsPerSample;}} III. Use example
1. Play
# include "WavFileReader.h" int main (int argc, char** argv) {AC::WavFileReader read; unsigned char buf [1024]; if (read.OpenWavFile ("test_music.wav")) {int channels, sampleRate, bitsPerSample; / / get the sound format channels = read.GetChannels (); sampleRate = read.GetSampleRate (); bitsPerSample = read.GetBitsPerSample () / / Open sound device (channels,sampleRate,bitsPerSample) int size; do {/ / read audio data size = read.ReadData (buf,1024); if (size > 0) {/ / play (buf,1024)}} while (size) Read.CloseFlie ();} return 0;}
2. Play in a loop
# include "WavFileReader.h" int main (int argc, char** argv) {AC::WavFileReader read; unsigned char buf [1024]; bool exitFlag = false; if (read.OpenWavFile ("test_music.wav")) {int channels, sampleRate, bitsPerSample; / / get the sound format channels = read.GetChannels (); sampleRate = read.GetSampleRate (); bitsPerSample = read.GetBitsPerSample () / / Open sound device (channels,sampleRate,bitsPerSample) int size; while (! exitFlag) {/ / read audio data size = read.ReadData (buf, 1024) If (size > 0) {/ / play (buf,1024)} else {/ / return to data start position read.SetPosition (0);}} read.CloseFlie ();} return 0 } these are all the contents of the article "how C++ reads PCM data in wav files". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.