C++實(shí)現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類(lèi)型
這是一個(gè)將s16le格式音頻文件轉(zhuǎn)換為float類(lèi)型并寫(xiě)入新文件的示例代碼。
以下是代碼的講解:
定義WavHeader結(jié)構(gòu)體,用于存儲(chǔ)WAV文件頭中的信息。
從命令行參數(shù)中獲取輸入和輸出文件名(第一個(gè)參數(shù)代表程序自身,因此輸入文件名為第二個(gè)參數(shù),輸出文件名為第三個(gè)參數(shù))。
打開(kāi)輸入文件和輸出文件,如果打開(kāi)失敗則返回錯(cuò)誤碼。
讀取WAV文件頭并檢查其格式是否正確,如果不正確則返回錯(cuò)誤碼。
計(jì)算音頻數(shù)據(jù)中的采樣點(diǎn)數(shù)和每個(gè)采樣點(diǎn)占用的字節(jié)數(shù)。
分配內(nèi)存空間來(lái)存儲(chǔ)音頻數(shù)據(jù),如果分配失敗則返回錯(cuò)誤碼。
讀取輸入文件中的音頻數(shù)據(jù),并將每個(gè)采樣點(diǎn)的值轉(zhuǎn)換為float類(lèi)型。
輸出一些關(guān)于音頻數(shù)據(jù)的基本信息。
將轉(zhuǎn)換后的音頻數(shù)據(jù)寫(xiě)入輸出文件。
釋放內(nèi)存空間,關(guān)閉輸入和輸出文件,程序結(jié)束。
需要注意的是,在寫(xiě)入輸出文件時(shí),我們使用了fwrite函數(shù),將整個(gè)音頻數(shù)據(jù)數(shù)組寫(xiě)入文件。
示例代碼
#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; }
編譯后測(cè)試
./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++實(shí)現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類(lèi)型的文章就介紹到這了,更多相關(guān)C++音頻流轉(zhuǎn)float類(lèi)型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
linux下C語(yǔ)言中的mkdir函數(shù)與rmdir函數(shù)
以下是對(duì)C語(yǔ)言中的mkdir函數(shù)與rmdir函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08VScode搭建OpenCV環(huán)境的詳細(xì)步驟
用vscode來(lái)寫(xiě)opencv代碼需要自己編譯OpenCV,主要用到MinGW-w64和CMake工具。接下來(lái)通過(guò)本文給大家介紹VScode搭建OpenCV環(huán)境的相關(guān)知識(shí),需要的朋友可以參考下2021-11-11C語(yǔ)言實(shí)現(xiàn)紙牌計(jì)算24點(diǎn)小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)紙牌計(jì)算24點(diǎn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10Visual Studio Code 從簡(jiǎn)介、安裝到配置所需插件詳細(xì)介紹
這篇文章給大家介紹到vs與vs code的區(qū)別,并且會(huì)詳細(xì)介紹vscode的安裝步驟,和我所了解過(guò)的插件配置,感興趣的朋友跟隨小編一起看看吧2020-03-03C++中實(shí)現(xiàn)矩陣的加法和乘法實(shí)例
這篇文章主要介紹了C++中實(shí)現(xiàn)矩陣的加法和乘法實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03C++使用文件實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++使用文件實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01