正在加载波形文件,但数据末尾有随机废话,而不是预期的样本
Loading Wave File but there is random nonsense at the end of the data rather than the expected samples
我有一个简单的 wav header reader 我很久以前在网上找到的,我已经开始使用它但它似乎在最后取代了大约 1200 个样本具有单个随机重复数字的数据块,例如 -126800。示例结束时预计会静音,因此数字应为零。
这是简单的程序:
void main() {
WAV_HEADER* wav = loadWav(".\audio\test.wav");
double sample_count = wav->SubChunk2Size * 8 / wav->BitsPerSample;
printf("Sample count: %i\n", (int)sample_count);
vector<int16_t> samples = vector<int16_t>();
for (int i = 0; i < wav->SubChunk2Size; i++)
{
int val = ((wav->data[i] & 0xff) << 8) | (wav->data[i + 1] & 0xff);
samples.push_back(val);
}
printf("done\n");
}
这是 Wav reader:
typedef struct
{
//riff
uint32_t Chunk_ID;
uint32_t ChunkSize;
uint32_t Format;
//fmt
uint32_t SubChunk1ID;
uint32_t SubChunk1Size;
uint16_t AudioFormat;
uint16_t NumberOfChanels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlignment;
uint16_t BitsPerSample;
//data
uint32_t SubChunk2ID;
uint32_t SubChunk2Size;
//Everything else is data. We note it's offset
char data[];
} WAV_HEADER;
#pragma pack()
inline WAV_HEADER* loadWav(const char* filePath)
{
long size;
WAV_HEADER* header;
void* buffer;
FILE* file;
fopen_s(&file,filePath, "r");
assert(file);
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);
std::cout << "Size of file: " << size << std::endl;
buffer = malloc(sizeof(char) * size);
fread(buffer, 1, size, file);
header = (WAV_HEADER*)buffer;
//Assert that data is in correct memory location
assert((header->data - (char*)header) == sizeof(WAV_HEADER));
//Extra assert to make sure that the size of our header is actually 44 bytes
assert((header->data - (char*)header) == 44);
fclose(file);
return header;
}
我不确定问题出在哪里,我已经确认没有元数据,从文件 header 读取的数字与实际文件之间也没有不匹配。我假设它在我这边有 size/offset 错位,但我看不到它。
欢迎任何帮助。
闷闷不乐
WAV 只是不同音频样本格式的容器。
您正在对 Windows 3.11 上的 wav 文件做出假设 :) 这些在 2021 年不成立。
无需滚动您自己的 Wav 文件 reader,只需使用可用的库之一即可。我个人在使用 libsndfile
方面有很好的经验,它几乎一直存在,非常纤薄,可以处理所有流行的 WAV 文件格式,也可以处理许多其他文件格式,除非你禁用它。
这看起来像一个 windows 程序(注意到您使用的是非常 WIN32API 风格的大写结构名称——这有点老套);因此,您可以从 github releases 下载 libsndfile 的安装程序并直接在您的 visual studio 中使用它(另一个盲目猜测)。
Apple(macOS 和 iOS)软件通常不会创建 WAVE/RIFF 开头仅包含规范的 Microsoft 44 字节 header 的文件。这些 Wave 文件可以使用更长的 header 后跟一个填充块。
因此您需要使用完整的 WAVE RIFF 格式解析规范,而不是仅仅从固定大小的 44 字节结构中读取。
我有一个简单的 wav header reader 我很久以前在网上找到的,我已经开始使用它但它似乎在最后取代了大约 1200 个样本具有单个随机重复数字的数据块,例如 -126800。示例结束时预计会静音,因此数字应为零。
这是简单的程序:
void main() {
WAV_HEADER* wav = loadWav(".\audio\test.wav");
double sample_count = wav->SubChunk2Size * 8 / wav->BitsPerSample;
printf("Sample count: %i\n", (int)sample_count);
vector<int16_t> samples = vector<int16_t>();
for (int i = 0; i < wav->SubChunk2Size; i++)
{
int val = ((wav->data[i] & 0xff) << 8) | (wav->data[i + 1] & 0xff);
samples.push_back(val);
}
printf("done\n");
}
这是 Wav reader:
typedef struct
{
//riff
uint32_t Chunk_ID;
uint32_t ChunkSize;
uint32_t Format;
//fmt
uint32_t SubChunk1ID;
uint32_t SubChunk1Size;
uint16_t AudioFormat;
uint16_t NumberOfChanels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlignment;
uint16_t BitsPerSample;
//data
uint32_t SubChunk2ID;
uint32_t SubChunk2Size;
//Everything else is data. We note it's offset
char data[];
} WAV_HEADER;
#pragma pack()
inline WAV_HEADER* loadWav(const char* filePath)
{
long size;
WAV_HEADER* header;
void* buffer;
FILE* file;
fopen_s(&file,filePath, "r");
assert(file);
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);
std::cout << "Size of file: " << size << std::endl;
buffer = malloc(sizeof(char) * size);
fread(buffer, 1, size, file);
header = (WAV_HEADER*)buffer;
//Assert that data is in correct memory location
assert((header->data - (char*)header) == sizeof(WAV_HEADER));
//Extra assert to make sure that the size of our header is actually 44 bytes
assert((header->data - (char*)header) == 44);
fclose(file);
return header;
}
我不确定问题出在哪里,我已经确认没有元数据,从文件 header 读取的数字与实际文件之间也没有不匹配。我假设它在我这边有 size/offset 错位,但我看不到它。 欢迎任何帮助。 闷闷不乐
WAV 只是不同音频样本格式的容器。
您正在对 Windows 3.11 上的 wav 文件做出假设 :) 这些在 2021 年不成立。
无需滚动您自己的 Wav 文件 reader,只需使用可用的库之一即可。我个人在使用 libsndfile
方面有很好的经验,它几乎一直存在,非常纤薄,可以处理所有流行的 WAV 文件格式,也可以处理许多其他文件格式,除非你禁用它。
这看起来像一个 windows 程序(注意到您使用的是非常 WIN32API 风格的大写结构名称——这有点老套);因此,您可以从 github releases 下载 libsndfile 的安装程序并直接在您的 visual studio 中使用它(另一个盲目猜测)。
Apple(macOS 和 iOS)软件通常不会创建 WAVE/RIFF 开头仅包含规范的 Microsoft 44 字节 header 的文件。这些 Wave 文件可以使用更长的 header 后跟一个填充块。
因此您需要使用完整的 WAVE RIFF 格式解析规范,而不是仅仅从固定大小的 44 字节结构中读取。