您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“C++怎么實(shí)現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類(lèi)型”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“C++怎么實(shí)現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類(lèi)型”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
以下是代碼的講解:
定義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 -
讀到這里,這篇“C++怎么實(shí)現(xiàn)將s16le的音頻流轉(zhuǎn)換為float類(lèi)型”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。