C++實現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類型
這是一個將s16le格式音頻文件轉(zhuǎn)換為float類型并寫入新文件的示例代碼。
以下是代碼的講解:
定義WavHeader結(jié)構(gòu)體,用于存儲WAV文件頭中的信息。
從命令行參數(shù)中獲取輸入和輸出文件名(第一個參數(shù)代表程序自身,因此輸入文件名為第二個參數(shù),輸出文件名為第三個參數(shù))。
打開輸入文件和輸出文件,如果打開失敗則返回錯誤碼。
讀取WAV文件頭并檢查其格式是否正確,如果不正確則返回錯誤碼。
計算音頻數(shù)據(jù)中的采樣點數(shù)和每個采樣點占用的字節(jié)數(shù)。
分配內(nèi)存空間來存儲音頻數(shù)據(jù),如果分配失敗則返回錯誤碼。
讀取輸入文件中的音頻數(shù)據(jù),并將每個采樣點的值轉(zhuǎn)換為float類型。
輸出一些關(guān)于音頻數(shù)據(jù)的基本信息。
將轉(zhuǎn)換后的音頻數(shù)據(jù)寫入輸出文件。
釋放內(nèi)存空間,關(guān)閉輸入和輸出文件,程序結(jié)束。
需要注意的是,在寫入輸出文件時,我們使用了fwrite函數(shù),將整個音頻數(shù)據(jù)數(shù)組寫入文件。
示例代碼
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char chunkId[4];
int chunkSize;
char format[4];
char subchunk1Id[4];
int subchunk1Size;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bitsPerSample;
char subchunk2Id[4];
int subchunk2Size;
} WavHeader;
int main(int argc, char**argv) {
const char* infile = argv[1];
FILE* infp = fopen(infile, "rb");
if (!infp) {
printf("Failed to open input file %s.\n", infile);
return 1;
}
const char* outfile = argv[2];
FILE* outfp = fopen(outfile, "wb");
if (!outfp) {
printf("Failed to open input file %s.\n", infile);
return 1;
}
// Read WAV file header
WavHeader wavHeader;
fread(&wavHeader, sizeof(WavHeader), 1, infp);
if (strncmp(wavHeader.chunkId, "RIFF", 4) != 0 ||
strncmp(wavHeader.format, "WAVE", 4) != 0 ||
strncmp(wavHeader.subchunk1Id, "fmt ", 4) != 0 ||
wavHeader.audioFormat != 1) {
printf("Invalid WAV file.\n");
fclose(infp);
return 1;
}
// Calculate number of samples and bytes per sample
int numSamples = wavHeader.subchunk2Size / (wavHeader.numChannels * (wavHeader.bitsPerSample / 8));
int bytesPerSample = wavHeader.bitsPerSample / 8;
// Allocate memory for audio data
float* buffer = (float*) malloc(numSamples * wavHeader.numChannels * sizeof(float));
if (!buffer) {
printf("Failed to allocate memory.\n");
fclose(infp);
return 1;
}
// Read audio data and convert to float
int i, j;
short sampleValue;
for (i = 0; i < numSamples; i++) {
for (j = 0; j < wavHeader.numChannels; j++) {
fread(&sampleValue, bytesPerSample, 1, infp);
buffer[i * wavHeader.numChannels + j] = (float) sampleValue / 32768.0f;
}
}
// Print some information about the audio data
printf("Input file: %s\n", infile);
printf("Format: %d-channel s16le, %d Hz\n", wavHeader.numChannels, wavHeader.sampleRate);
printf("Duration: %.3f seconds\n", (float) numSamples / wavHeader.sampleRate);
// write to output file.
fwrite(buffer, numSamples * wavHeader.numChannels * sizeof(float), 1, outfp);
// Clean up
free(buffer);
fclose(infp);
fclose(outfp);
return 0;
}
編譯后測試
./s16letofloat chendu-96k.wav chendu-96kflt.pcm
ffmpeg 播放
ffmpeg -ar 96000 -ac 2 -f f32le -i chendu-96kflt.pcm -f wav pipe:1 | ffplay -
到此這篇關(guān)于C++實現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類型的文章就介紹到這了,更多相關(guān)C++音頻流轉(zhuǎn)float類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?構(gòu)造函數(shù)和析構(gòu)函數(shù)(Constructors?&?Destructors)詳解
由于global?object的誕生比程序進(jìn)入更早點,所以global?object的constructor執(zhí)行的時間更早于程序的進(jìn)入點,所謂的default?constructor就是沒有指定任何的參數(shù)的constructor,這篇文章主要介紹了C++?構(gòu)造函數(shù)和析構(gòu)函數(shù)的相關(guān)知識,需要的朋友可以參考下2024-05-05

