本文小編為大家詳細介紹“C++怎么實現將s16le的音頻流轉換為float類型”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C++怎么實現將s16le的音頻流轉換為float類型”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
以下是代碼的講解:
定義WavHeader結構體,用于存儲WAV文件頭中的信息。
從命令行參數中獲取輸入和輸出文件名(第一個參數代表程序自身,因此輸入文件名為第二個參數,輸出文件名為第三個參數)。
打開輸入文件和輸出文件,如果打開失敗則返回錯誤碼。
讀取WAV文件頭并檢查其格式是否正確,如果不正確則返回錯誤碼。
計算音頻數據中的采樣點數和每個采樣點占用的字節數。
分配內存空間來存儲音頻數據,如果分配失敗則返回錯誤碼。
讀取輸入文件中的音頻數據,并將每個采樣點的值轉換為float類型。
輸出一些關于音頻數據的基本信息。
將轉換后的音頻數據寫入輸出文件。
釋放內存空間,關閉輸入和輸出文件,程序結束。
需要注意的是,在寫入輸出文件時,我們使用了fwrite函數,將整個音頻數據數組寫入文件。
示例代碼
#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 -
讀到這里,這篇“C++怎么實現將s16le的音頻流轉換為float類型”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。