RT As shown in the figure, in the code shown in the figure, the frames print result is 100, but the code does not execute the loop body. Check carefully that there is no break in the loop body. Return and other statements, may I ask where the problem lies? (Uncommenting line 142 can print out 0 to 99 correctly)
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
struct WAV_Format {
uint32_t ChunkID; /* "RIFF" */
uint32_t ChunkSize; /* 36 + Subchunk2Size */
uint32_t Format; /* "WAVE" */
/* sub-chunk "fmt" */
uint32_t Subchunk1ID; /* "fmt " */
uint32_t Subchunk1Size; /* 16 for PCM */
uint16_t AudioFormat; /* PCM = 1*/
uint16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */
uint32_t SampleRate; /* 8000, 44100, etc. */
uint32_t ByteRate; /* = SampleRate * NumChannels * BitsPerSample/8 */
uint16_t BlockAlign; /* = NumChannels * BitsPerSample/8 */
uint16_t BitsPerSample; /* 8bits, 16bits, etc. */
/* sub-chunk "data" */
uint32_t Subchunk2ID; /* "data" */
uint32_t Subchunk2Size; /* data size */
};
//Data Chunk
// ==================================
// | |所占字节数| 具体内容 |
// ==================================
// | ID | 4 Bytes | 'data' |
// ----------------------------------
// | Size | 4 Bytes | |
// ----------------------------------
// | data | | |
// ----------------------------------
// 图5 Data Chunk
//
// Data Chunk是真正保存wav数据的地方,以'data'作为该Chunk的标示。然后是
//数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,
//wav数据的bit位置可以分成以下几种形式:
// ---------------------------------------------------------------------
// | 单声道 | 取样1 | 取样2 | 取样3 | 取样4 |
// |--------------------------------------------------------------------
// | 8bit量化 | 声道0 | 声道0 | 声道0 | 声道0 |
// ---------------------------------------------------------------------
// | 双声道 | 取样1 | 取样2 |
// |--------------------------------------------------------------------
// | 8bit量化 | 声道0(左) | 声道1(右) | 声道0(左) | 声道1(右) |
//
//
// ----------------------------------------------------------------------
//
// | 单声道 | 取样1 | 取样2 |
// |---------------------------------------------------------------------
// | 16bit量化 | 声道0 | 声道0 | 声道0 | 声道0 |
// | | (低位字节) | (高位字节) | (低位字节) | (高位字节)|
// -----------------------------------------------------------------------
//
// | 双声道 | 取样1 | 取样2 |
// |-------------------------------------------------------------------------------
// | 16bit量化 | 声道0(左) | 声道0(左) | 声道1(左) | 声道1(右)|
// | | (低位字节) | (高位字节) | (低位字节) | (高位字节) |
// ---------------------------------------------------------------------------------
struct BLOCK_16bit_2channel {
uint8_t channel_left_low;
uint8_t channel_left_high;
uint8_t channel_right_low;
uint8_t channel_right_high;
};
struct DATA_BLOCK {
char strData[4]; // 'd' 'a' 't' 'a'
uint32_t dwDataSize;
// BLOCK_16bit_2channel block
};
int main(void)
{
FILE *fp = NULL;
struct WAV_Format wav;
struct DATA_BLOCK data;
struct BLOCK_16bit_2channel block;
fp = fopen("test.wav", "rb");
if (!fp) {
printf("can't open audio file\n");
exit(1);
}
fread(&wav, 1, sizeof(struct WAV_Format), fp);
printf("length:%d(10),0x%x, \n\n", sizeof(struct WAV_Format), sizeof(struct WAV_Format)); // 44
printf("ChunkID \t%x\n", wav.ChunkID);
printf("ChunkSize \t%d\n", wav.ChunkSize);
printf("Format \t\t%x\n", wav.Format);
printf("Subchunk1ID \t%x\n", wav.Subchunk1ID);
printf("Subchunk1Size \t%d\n", wav.Subchunk1Size);
printf("AudioFormat \t%d\n", wav.AudioFormat);
printf("NumChannels \t%d\n", wav.NumChannels);
printf("SampleRate \t%d\n", wav.SampleRate);
printf("ByteRate \t%d\n", wav.ByteRate);
printf("BlockAlign \t%d\n", wav.BlockAlign);
printf("BitsPerSample \t%d\n", wav.BitsPerSample);
printf("Subchunk2ID \t%x\n", wav.Subchunk2ID);
printf("Subchunk2Size \t%d\n", wav.Subchunk2Size);
// fread(&data, 1, sizeof(struct DATA_BLOCK), fp);
// printf("dwDataSize \t%x\n", data.dwDataSize);
char data_block;
uint16_t lh;
uint16_t ll;
uint16_t rh;
uint16_t rl;
struct Spectrum {
unsigned int s1;
unsigned int s2;
unsigned int s3;
unsigned int s4;
unsigned int s5;
unsigned int s6;
unsigned int s7;
unsigned int s8;
};
// unsigned short sample;
if (wav.BitsPerSample == 16) {
if (wav.NumChannels == 2) {
int i;
long count = wav.Subchunk2Size / sizeof(struct BLOCK_16bit_2channel);
int duration = count / wav.SampleRate; // 采样数量除以每秒采样率等于持续秒数
short fps = 10; // frequency
int frames = duration * fps;
int readSamplePer = wav.SampleRate / fps; // 每秒读取采样数量
int readBytesPer = sizeof(struct BLOCK_16bit_2channel) * readSamplePer; // 每秒读取字节数
short width = 80;
int total = fps * wav.SampleRate / width;
int left, right;
// for (int s=0; s<frames; ++s)printf("\n%d\n", s);
printf("\nframe:%d\n", frames);
for (int s=0; s<frames; ++s) {
printf("\n%d\n", s);
struct Spectrum spectrum;
// fread(&sample, 1, readSamplePer, fp);
for (int r=0; r<readBytesPer; ++r) {
fread(&block, 1, readBytesPer, fp);
lh = block.channel_left_high;
ll = block.channel_left_low;
rh = block.channel_right_high;
rl = block.channel_right_low;
left = (lh << 4) | ll;
right = (rh << 4) | rl;
uint32_t sample = (left + right) / 2;
printf("\n%d\n", sample);
if (sample < 4096 * 1) {
++spectrum.s1;
}
if (sample < 4096 * 2) {
++spectrum.s2;
}
if (sample < 4096 * 3) {
++spectrum.s3;
}
if (sample < 4096 * 4) {
++spectrum.s4;
}
if (sample < 4096 * 5) {
++spectrum.s5;
}
if (sample < 4096 * 6) {
++spectrum.s6;
}
if (sample < 4096 * 7) {
++spectrum.s7;
}
if (sample < 4096 * 8) {
++spectrum.s8;
}
}
printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", spectrum.s1, spectrum.s2, spectrum.s3, spectrum.s4, spectrum.s5, spectrum.s6, spectrum.s7, spectrum.s8);
}
// for (i=0; i<count; i+=frequency) {
// fread(&block, 1, sizeof(struct BLOCK_16bit_2channel), fp);
// lh = block.channel_left_high;
// ll = block.channel_left_low;
// rh = block.channel_right_high;
// rl = block.channel_right_low;
// left = (lh << 4) | ll;
// right = (rh << 4) | rl;
//// printf("%d:\t%d\t%d\n", i, left, right);
// }
// printf("\ni:%d,count:%d\n", i, count);
// system("cls");
}
}
fclose(fp);
return 0;
}
巴扎黑2017-06-05 11:13:33
The loop body is executed. There is
0 on the
log, indicating that it entered the loop when s=0 for the first time.
It looks like it was not executed because the program crashed.
The last error messageprocess excited after ... with return value 3221225477
The problem should be line 149 fread(&block, 1, readBytesPer, fp);
As a buff block
, its length is only one struct BLOCK_16bit_2channel
but the read length readBytesPer = sizeof( struct BLOCK_16bit_2channel) * readSamplePer
, where the value of readSamplePer is 22050*10
. The read length far exceeds the buff, and the memory read and write exceeds the limit, causing the final program to crash.