#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 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;
}
首先
循環體執行了。
log上有個
0
,表示第一次s=0的時候進入循環了。然後
看起來像是沒有執行,是因為程式崩潰了。
最後的報錯訊息
process excited after ... with return value 3221225477
崩潰的原因
出問題的應該是第149行的
struct BLOCK_16bit_2channel) * readSamplePer🎜,其中readSamplePer的值為22050*10🎜讀取長度遠遠超出buff,記憶體讀寫越界了,導致最後程式崩潰。 🎜fread(&block, 1, readBytesPer, fp);
作為buff的
block
,其長度只有一個struct BLOCK_16bit_2chanchanblock
,其長度只有一個struct BLOCK_16bit_2chanchanblock
,其長度只有一個
struct BLOCK_16bit_2chanchanx,其長度只有一個