2012-08-24 30 views
0

我使用一个线程绘制波形,另一个线程播放音频。唯一的问题是,我在播放音频时出现口吃,它来自decodeAudio过程: audioCoder.decodeAudio(samples,packet,offset);使用两个音频线程时的音频毛刺

这里是我的波形拉丝级:

public class DrawWaveform extends Thread{ 
    String f; 
    int n; 
    DrawWaveform(final String file, final int nstream) 
    { 
     this.setPriority(10); 
     f = file; 
     n = nstream; 
    } 
    public void run() { 

     stopThread = false; 
     { 
      IContainer container = IContainer.make(); 

      container.open(f, IContainer.Type.READ, null); 

      // query how many streams the call to open found 
      int numStreams = container.getNumStreams(); 
      int count = 0; 
      IStreamCoder audioCoder = null; 
      int audioStreamId = -1; 

      for (int i = 0; i < numStreams; i++) 
      { 
        // Find the stream object 
        IStream stream = container.getStream(i); 
        // Get the pre-configured decoder that can decode this stream; 
        IStreamCoder coder = stream.getStreamCoder(); 

        //si le premier élément est audio alors t = true sinon t = false 
        if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) 
        { 
         if (count == n) 
         { 
          //on commence la lecture an plein milieu du son 
          //container.seekKeyFrame(i, dur/2, container.SEEK_FLAG_BYTE); 
          format = coder.getSampleFormat(); 

          audioCoder = coder; 
          audioStreamId = i; 

          break; 
         } 
         count += 1; 
        } 
      } 
      if (audioCoder.open() < 0) 
       throw new RuntimeException("could not open audio decoder for container: "+f); 

      int sr = container.getStream(audioStreamId).getStreamCoder().getSampleRate(); 
      zoomFactor = (int) Math.round(220.*sr/11630.); 

      long dur = container.getDuration();//en microsecondes 
      samples = new int[(int)(dur*sr/(1000*1000))]; 
      //openJavaSound(audioCoder); 


      /* 
      * Now, we start walking through the container looking at each packet. 
      */ 
      IPacket packet = IPacket.make(); 
      //on parcours tout le fichier f 
      while(container.readNextPacket(packet) >= 0 && !stopThread) 
      { 

         /* 
         * Now we have a packet, let's see if it belongs to our audio stream 
         */ 
         //on s'assure que le packet lu correspond au bon stream 
         if (packet.getStreamIndex() == audioStreamId) 
         { 
         /* 
         * We allocate a set of samples with the same number of channels as the 
         * coder tells us is in this buffer. 
         * 
         * We also pass in a buffer size (1024 in our example), although Xuggler 
         * will probably allocate more space than just the 1024 (it's not important why). 
         */ 
         IAudioSamples samples = IAudioSamples.make(1024, audioCoder.getChannels()); 

         /* 
         * A packet can actually contain multiple sets of samples (or frames of samples 
         * in audio-decoding speak). So, we may need to call decode audio multiple 
         * times at different offsets in the packet's data. We capture that here. 
         */ 
         int offset = 0; 

         /* 
         * Keep going until we've processed all data 
         */ 
         while(offset < packet.getSize()) 
         { 
          //if i remove this line, no more audio glitches 
          int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset); 
          if (bytesDecoded < 0) 
          throw new RuntimeException("got error decoding audio in: " + f); 
          offset += bytesDecoded; 

          /* 
          * Some decoder will consume data in a packet, but will not be able to construct 
          * a full set of samples yet. Therefore you should always check if you 
          * got a complete set of samples from the decoder 
          */ 
          if (!stopThread) 
          if(samples.isComplete()) 
          { 
          makeWaveform(samples); 

          currentPlayTime += samples.getNumSamples(); 
          //System.out.println("max = "+48000*container.getDuration()/1000000 + " current = "+currentPlayTime); 
          } 
         } 
         } 
         else 
         { 
         /* 
         * This packet isn't part of our audio stream, so we just silently drop it. 
         */ 

         } 
        } 

     } 
     } 
    } 

如果我删除所需要的decodeAudio行,我也去掉毛刺。

我试图改变线程的优先顺序没有运气。我也试图改变缓冲区大小,一样。

那么,有没有办法避免这种情况?

多谢

回答

0

只是为了检查:你确定decodeAudio是(使用分析,或东西)惹的祸?如果不是,如果您解码音频会发生什么,但不绘制波形?