Heim  >  Fragen und Antworten  >  Hauptteil

Die C-Sprache führt den Schleifenkörper nicht aus

RT Im im Bild gezeigten Code beträgt das Druckergebnis der Frames 100, aber der Code führt den Schleifenkörper nicht aus. Ich habe sorgfältig überprüft, ob der Schleifenkörper unterbrochen ist. Rückgabe und andere Aussagen, darf ich fragen, wo das Problem liegt? (Wenn Sie Zeile 142 auskommentieren, werden 0 bis 99 korrekt ausgegeben)

#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;  
}  
某草草某草草2715 Tage vor888

Antworte allen(1)Ich werde antworten

  • 巴扎黑

    巴扎黑2017-06-05 11:13:33

    首先

    循环体执行了。
    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,内存读写越界了,导致最后程序崩溃。

    Antwort
    0
  • StornierenAntwort