优化代码使保存的音频文件能在QQ音乐正常播放
时间: 2024-04-12 11:32:29 浏览: 13
要使保存的音频文件能在 QQ 音乐等播放器中正常播放,您可以进行以下优化:
1. 修改音频文件的扩展名为 `.wav`:QQ 音乐等播放器通常支持播放 WAV 格式的音频文件。在保存音频文件时,将文件名的扩展名修改为 `.wav`。
2. 设置正确的音频格式参数:确保 `WAVEFORMATEX` 结构体中的音频格式参数与实际录制的音频数据一致。例如,如果录制的音频采样率为 44100 Hz、位深度为 16 位、单声道,则需要将 `wfx.nSamplesPerSec` 设置为 44100,`wfx.wBitsPerSample` 设置为 16,`wfx.nChannels` 设置为 1。
3. 在录制结束后写入 WAV 文件的文件头信息:WAV 文件有特定的文件头格式,其中包含了音频数据的相关信息。您可以在录制结束后,在保存音频数据之前,先写入 WAV 文件的文件头信息。可以通过查阅 WAV 文件格式规范来了解如何正确构造和写入 WAV 文件头。
以下是一个示例代码,演示了如何优化以保存能在 QQ 音乐等播放器中正常播放的音频文件:
```c
#include <Windows.h>
#include <mmsystem.h>
#include <stdio.h>
#define NUM_BUFFERS 3
#define BUFFER_SIZE 4096
HWAVEIN hWaveIn;
WAVEHDR waveHeaders[NUM_BUFFERS];
FILE* file;
void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
if (uMsg == WIM_DATA) {
LPWAVEHDR pWaveHdr = (LPWAVEHDR)dwParam1;
fwrite(pWaveHdr->lpData, pWaveHdr->dwBytesRecorded, 1, file);
waveInAddBuffer(hwi, pWaveHdr, sizeof(WAVEHDR));
}
}
int main() {
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 1;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0;
file = fopen("recorded_audio.wav", "wb");
if (file == NULL) {
printf("Failed to create file!\n");
return 1;
}
// 写入 WAV 文件头
WAVEFORMATEXTENSIBLE wfxe;
memset(&wfxe, 0, sizeof(WAVEFORMATEXTENSIBLE));
memcpy(&wfxe.Format, &wfx, sizeof(WAVEFORMATEX));
wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfxe.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample;
wfxe.dwChannelMask = SPEAKER_FRONT_CENTER;
DWORD headerSize = sizeof(WAVELIST) + sizeof(WAVEFORMATEXTENSIBLE);
DWORD dataSize = 0; // 需要在录制结束后计算实际的音频数据大小
DWORD fileSize = headerSize + dataSize - 8;
fwrite("RIFF", 1, 4, file);
fwrite(&fileSize, sizeof(DWORD), 1, file);
fwrite("WAVE", 1, 4, file);
fwrite("JUNK", 1, 4, file);
fwrite(&headerSize, sizeof(DWORD), 1, file);
fwrite("wavl", 1, 4, file);
fwrite(&headerSize, sizeof(DWORD), 1, file);
fwrite(&wfxe, sizeof(WAVEFORMATEXTENSIBLE), 1, file);
fseek(file, headerSize, SEEK_SET);
waveInOpen(&hWaveIn, WAVE_MAPPER, &wfx, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);
for (int i = 0; i < NUM_BUFFERS; i++) {
waveHeaders[i].lpData = new char[BUFFER_SIZE];
waveHeaders[i].dwBufferLength = BUFFER_SIZE;
waveHeaders[i].dwBytesRecorded = 0;
waveHeaders[i].dwUser = 0;
waveHeaders[i].dwFlags = 0;
waveHeaders[i].dwLoops = 0;
waveInPrepareHeader(hWaveIn, &waveHeaders[i], sizeof(WAVEHDR));
waveInAddBuffer(hWaveIn, &waveHeaders[i], sizeof(WAVEHDR));
}
waveInStart(hWaveIn);
printf("Recording audio... Press Enter to stop.\n");
getchar();
waveInClose(hWaveIn);
fclose(file);
// 更新 WAV 文件头中的实际数据大小
fileSize = headerSize + dataSize - 8;
file = fopen("recorded_audio.wav", "r+b");
fseek(file, 4, SEEK_SET);
fwrite(&fileSize, sizeof(DWORD), 1, file);
fclose(file);
for (int i = 0; i < NUM_BUFFERS; i++) {
delete[] waveHeaders[i].lpData;
waveInUnprepareHeader(hWaveIn, &waveHeaders[i], sizeof(WAVEHDR));
}
return 0;
}
```
请根据实际需求对代码进行适当修改,并确保正确设置音频数据的大小和文件头信息。