问题描述
RT如图所示代码中frames打印出结果为100,但是代码却不执行循环体,仔细检查过循环体里面没有break。return等语句,请问一下问题出在哪啊?(取消142行注释能够正打印出0到99)
#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 filen'); exit(1); }fread(&wav, 1, sizeof(struct WAV_Format), fp);printf('length:%d(10),0x%x, nn', sizeof(struct WAV_Format), sizeof(struct WAV_Format)); // 44 printf('ChunkID t%xn', wav.ChunkID); printf('ChunkSize t%dn', wav.ChunkSize); printf('Format tt%xn', wav.Format); printf('Subchunk1ID t%xn', wav.Subchunk1ID); printf('Subchunk1Size t%dn', wav.Subchunk1Size); printf('AudioFormat t%dn', wav.AudioFormat); printf('NumChannels t%dn', wav.NumChannels); printf('SampleRate t%dn', wav.SampleRate); printf('ByteRate t%dn', wav.ByteRate); printf('BlockAlign t%dn', wav.BlockAlign); printf('BitsPerSample t%dn', wav.BitsPerSample); printf('Subchunk2ID t%xn', wav.Subchunk2ID); printf('Subchunk2Size t%dn', wav.Subchunk2Size); // fread(&data, 1, sizeof(struct DATA_BLOCK), fp); // printf('dwDataSize t%xn', 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%dn', s);printf('nframe:%dn', frames); for (int s=0; s<frames; ++s) {printf('n%dn', 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%dn', 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('%dt%dt%dt%dt%dt%dt%dt%dn', 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%dt%dn', i, left, right);// }// printf('ni:%d,count:%dn', i, count);// system('cls');} } fclose(fp);return 0; }
问题解答
回答1:首先循环体执行了。 log上有个0,说明第一次s=0的时候进入循环了。
然后看起来像是没有执行,是因为程序崩溃了。 最后的报错信息process excited after ... with return value 3221225477
崩溃的原因出问题的应该是第149行的fread(&block, 1, readBytesPer, fp);作为buff的block,其长度只有一个struct BLOCK_16bit_2channel但是读取的长度readBytesPer = sizeof(struct BLOCK_16bit_2channel) * readSamplePer,其中readSamplePer的值为22050*10读取长度远远超出buff,内存读写越界了,导致最后程序崩溃。