2012-02-02 4 views
1

У меня есть часть программного обеспечения, которое записывает интервал времени в 5 секунд, а затем отправляет его для обработки. Она работает в бесконечном цикле, и выглядит следующим образом:java аудиозапись

while (true) { 
    System.out.println("recording.."); 
    recorder.start(); 
    Thread.sleep(5000); 
    recorder.stop(); 
    Thread.sleep(300); 
    System.out.println("recording finished"); 

    data = toolkit.readInputStream(recorder.getInputStream()); 

    pkt = create(data); 

    outport.send(pkt); 
} 

В приведенном выше коде, я должен был добавить строку Thread.sleep(300); после окончания записи, так как в противном случае recorder.getInputStream() возвращает нулевое значение. Почему это происходит? Есть ли способ изменить его, чтобы не было необходимости в задержке?

Код записывающее:

public class SoundRecorder implements Runnable{ 


     final int bufSize = 16384; 

     AudioInputStream audioInputStream; 
     String errStr; 
     double duration, seconds; 
     File file; 

    public void start() { 
       errStr = null; 
       thread = new Thread(this); 
       thread.setName("Capture"); 
       thread.start(); 
      } 

      public void stop() { 
       thread = null; 
      } 

private void shutDown(String message) { 
      if ((errStr = message) != null && thread != null) { 
       thread = null; 
       System.err.println(errStr); 

      } 
     } 


     public void run() { 

       duration = 0; 
       audioInputStream = null; 


       // define the required attributes for our line, 
       // and make sure a compatible line is supported. 

       AudioFormat format = getFormat(); 
       DataLine.Info info = new DataLine.Info(TargetDataLine.class, 
         format); 

       if (!AudioSystem.isLineSupported(info)) { 
        shutDown("Line matching " + info + " not supported."); 
        return; 
       } 

       // get and open the target data line for capture. 

       try { 
        line = (TargetDataLine) AudioSystem.getLine(info); 
        line.open(format, line.getBufferSize()); 
       } catch (LineUnavailableException ex) { 
        shutDown("Unable to open the line: " + ex); 
        return; 
       } catch (SecurityException ex) { 
        shutDown(ex.toString()); 

        return; 
       } catch (Exception ex) { 
        shutDown(ex.toString()); 
        return; 
       } 

       // play back the captured audio data 
       ByteArrayOutputStream out = new ByteArrayOutputStream(); 
       int frameSizeInBytes = format.getFrameSize(); 
       int bufferLengthInFrames = line.getBufferSize()/8; 
       int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes; 
       byte[] data = new byte[bufferLengthInBytes]; 
       int numBytesRead; 

       line.start(); 

       while (thread != null) { 
        if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) { 
         break; 
        } 
        out.write(data, 0, numBytesRead); 
       } 

       // we reached the end of the stream. stop and close the line. 
       line.stop(); 
       line.close(); 
       line = null; 

       // stop and close the output stream 
       try { 
        out.flush(); 
        out.close(); 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 

       // load bytes into the audio input stream for playback 

       byte audioBytes[] = out.toByteArray(); 
       ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes); 
       audioInputStream = new AudioInputStream(bais, format, audioBytes.length/frameSizeInBytes); 

       long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000)/format.getFrameRate()); 
       duration = milliseconds/1000.0; 



       try { 
        audioInputStream.reset(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
        return; 
       } 


      } 

    public AudioInputStream getInputStream() { 
      return audioInputStream; 
     } 

    public AudioFormat getFormat() { 

      AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED; 
      float rate = 44100.0F; 
      int sampleSize = 16; 
      boolean bigEndian = true; 
      int channels = 2; 

      return new AudioFormat(encoding, rate, sampleSize, 
        channels, (sampleSize/8) * channels, rate, bigEndian); 

     } 
    } 

ответ

2

Вы хотите сказать, ваш поток работает в фоновом режиме, чтобы остановить, и код, как это написано, имеет некоторые очистить работу, чтобы сделать на выходе. Поэтому вам нужно дождаться окончания потока, прежде чем использовать некоторые функции.

Что вы можете сделать, это изменить функцию остановки на что-то вроде:

public void stop() { 
    Thread t = thread; 
    thread = null;// this will cause your thread to exit 
    t.join();//this will wait for the thread to exit before returning. 
} 
Смежные вопросы