1

我正在尝试创建一个 .ogg 文件,但即使提供的示例代码在调用vorbis_analysis().

我正在使用此编码示例的简化版本。我已经按原样尝试了完整的示例,但我在同一个地方遇到了同样的错误。

下面的代码是通过用常量而不是 wav 文件填充编码缓冲区的简化示例。hFile是在别处创建的实例TStreamFile

vorbis_info      vi;
vorbis_dsp_state vd;
vorbis_comment   vc;
vorbis_block     vb;

ogg_stream_state os;
ogg_page         og;
ogg_packet       op;

ogg_packet header;
ogg_packet header_comm;
ogg_packet header_code;

int res;
int len  = 0;
int eos  = 0;
int loop = 0;

vorbis_info_init(&vi);
res = vorbis_encode_init_vbr(&vi,2,44100,0.4f);
res = vorbis_encode_setup_init(&vi);

vorbis_comment_init(&vc);
vorbis_comment_add_tag(&vc,"TITLE","Silent noise");
res = vorbis_analysis_init(&vd,&vi);
res = vorbis_block_init(&vd,&vb);

srand(time(NULL));
res = ogg_stream_init(&os,rand());
res = vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
res = ogg_stream_packetin(&os,&header);
res = ogg_stream_packetin(&os,&header_comm);
res = ogg_stream_packetin(&os,&header_code);

/* This ensures the actual
 * audio data will start on a new page, as per spec
 */
while(ogg_stream_flush(&os,&og)) {
  hFile->Write(og.header,og.header_len);
  hFile->Write(og.body,  og.body_len  );
}

while(!eos) {
  float **Buffer = vorbis_analysis_buffer(&vd,1024);

  if(loop<10) {
    for(int n=0; n<1024; n++) {
      Buffer[0][n] = 1.0f;
      Buffer[1][n] = 1.0f;
    }
    res = vorbis_analysis_wrote(&vd,1024);
    loop++;
  } else {
    res = vorbis_analysis_wrote(&vd,0);
    eos = true;
  }

  // Enough data?
  while(vorbis_analysis_blockout(&vd,&vb) == 1) {
    res = vorbis_analysis(&vb,&op);  // <---- Access Violation
    res = vorbis_bitrate_addblock(&vb);

    while(vorbis_bitrate_flushpacket(&vd,&op)) {

      /* weld the packet into the bitstream */
      res = ogg_stream_packetin(&os,&op);

      /* write out pages (if any) */
      while(!eos){
        if(ogg_stream_pageout(&os,&og) == 0) {
          break;
        }
        hFile->Write(og.header,og.header_len);
        hFile->Write(og.body,  og.body_len  );

        /* this could be set above, but for illustrative purposes, I do
           it here (to show that vorbis does know where the stream ends) */
        if(ogg_page_eos(&og)) {
          eos=1;
        }
      }
    }
  }
}

res = ogg_stream_clear(&os);
res = vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
vorbis_comment_clear(&vc);
vorbis_info_clear(&vi);

第一部分运行良好,创建了标头并将其保存到流中。然后我只是用 1.0 浮点数填充缓冲区以进行测试。

当有足够的数据可用时,调用vorbis_analysis总是生成Access Violation at x write of address x

该变量res始终指示成功,一直到访问冲突。

我正在使用静态链接的 libogg v1.3.2 和 libvorbis 1.3.5

4

0 回答 0