這是一個(gè)將s16le格式音頻文件轉(zhuǎn)換為float類型并寫(xiě)入新文件的示例代碼。
以下是代碼的講解:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-409393.html
- 定義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類型。
- 輸出一些關(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 播放文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-409393.html
ffmpeg -ar 96000 -ac 2 -f f32le -i chendu-96kflt.pcm -f wav pipe:1 | ffplay -
到了這里,關(guān)于將s16le的音頻流轉(zhuǎn)換為float類型的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!