Bestimmen Sie die Amplitude des Tons vom Mikrofon

  • Ich versuche, die Amplitude eines Instruments (Trompete, Gitarre usw.), das mit der Java Sound API aufgenommen wird, zu ermitteln und einen Amplituden-Zeit-Graphen anzuzeigen. Ich habe noch nicht viel Erfahrung mit dieser API und bin nicht ganz sicher, wie ein RMS oder eine FFT für eine Schallwelleneingabe berechnet wird. Wie kann ich das erreichen?

     import javax.swing.*; 
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.sound.sampled.*;
    
    public class FrequencyAmplitude extends JFrame {
    /**
         * 
         */
        private static final long serialVersionUID = 1173050310536562125L;
    //CAPTURE AUDIO TEST #1
      protected boolean running;
      ByteArrayOutputStream out;
    
      public FrequencyAmplitude() {
        super("Recording Demo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Container content = getContentPane();
    
        final JButton capture = new JButton("Record");
        final JButton stop = new JButton("Stop");
        final JButton play = new JButton("Play");
    
        capture.setEnabled(true);
        stop.setEnabled(false);
        play.setEnabled(false);
    
        ActionListener captureListener = 
            new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            capture.setEnabled(false);
            stop.setEnabled(true);
            play.setEnabled(false);
            captureAudio();
          }
        };
        capture.addActionListener(captureListener);
        content.add(capture, BorderLayout.NORTH);
    
        ActionListener stopListener = 
            new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            capture.setEnabled(true);
            stop.setEnabled(false);
            play.setEnabled(true);
            running = false;
          }
        };
        stop.addActionListener(stopListener);
        content.add(stop, BorderLayout.CENTER);
    
        ActionListener playListener = 
            new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            playAudio();
          }
        };
        play.addActionListener(playListener);
        content.add(play, BorderLayout.SOUTH);
      }
    
      private void captureAudio() {
        try {
          final AudioFormat format = getFormat();
          DataLine.Info info = new DataLine.Info(
            TargetDataLine.class, format);
          final TargetDataLine line = (TargetDataLine)
            AudioSystem.getLine(info);
          line.open(format);
          line.start();
          Runnable runner = new Runnable() {
            int bufferSize = (int)format.getSampleRate() 
              * format.getFrameSize();
            byte buffer[] = new byte[bufferSize];
    
            public void run() {
              out = new ByteArrayOutputStream();
              running = true;
              try {
                while (running) {
                  int count = 
                    line.read(buffer, 0, buffer.length);
                  if (count > 0) {
                    out.write(buffer, 0, count);
                  }
                }
                out.close();
              } catch (IOException e) {
                System.err.println("I/O problems: " + e);
                System.exit(-1);
              }
            }
          };
          Thread captureThread = new Thread(runner);
          captureThread.start();
        } catch (LineUnavailableException e) {
          System.err.println("Line unavailable: " + e);
          System.exit(-2);
        }
      }
    
      private void playAudio() {
        try {
          byte audio[] = out.toByteArray();
          InputStream input = 
            new ByteArrayInputStream(audio);
          final AudioFormat format = getFormat();
          final AudioInputStream ais = 
            new AudioInputStream(input, format, 
            audio.length / format.getFrameSize());
          DataLine.Info info = new DataLine.Info(
            SourceDataLine.class, format);
          final SourceDataLine line = (SourceDataLine)
            AudioSystem.getLine(info);
          line.open(format);
          line.start();
    
          Runnable runner = new Runnable() {
            int bufferSize = (int) format.getSampleRate() 
              * format.getFrameSize();
            byte buffer[] = new byte[bufferSize];
    
            public void run() {
              try {
                int count;
                while ((count = ais.read(
                    buffer, 0, buffer.length)) != -1) {
                  if (count > 0) {
                    line.write(buffer, 0, count);
                  }
                }
                line.drain();
                line.close();
              } catch (IOException e) {
                System.err.println("I/O problems: " + e);
                System.exit(-3);
              }
            }
          };
          Thread playThread = new Thread(runner);
          playThread.start();
        } catch (LineUnavailableException e) {
          System.err.println("Line unavailable: " + e);
          System.exit(-4);
        } 
      }
    
      private AudioFormat getFormat() {
        float sampleRate = 8000;
        int sampleSizeInBits = 8;
        int channels = 1;
        boolean signed = true;
        boolean bigEndian = true;
        return new AudioFormat(sampleRate, 
          sampleSizeInBits, channels, signed, bigEndian);
      }
      public static void main(String args[]) {
        JFrame frame = new FrequencyAmplitude();
        frame.pack();
        frame.setVisible(true);
      }
    }
    
        enter code here
     
    22 November 2011
    Matt Ball
1 answer
  • Konvertieren Sie ein Byte-Array in ein Float-Array. Das ist es im Grunde. Die Länge des Float-Arrays beträgt 1/8 der Länge des Bytearrays.

    , wenn Sie die Ausgabe des Codes in Excel oder Libre Office Calc einfügen ( ubuntu) sehen Sie die Wellenform

         ByteBuffer buf = ByteBuffer.wrap(bytes);
        long[] longs = new long[bytes.length / 8];
        for (int i = 0; i < longs.length; i++)
         {
            longs[i] = buf.getLong(i*8);
            System.out.println(longs[]i);
    
         }
     

    DIES IST NICHT IDEAL ZU TUN, sondern der Einfachheit halber Fügen Sie den Code in den while-Block von CaptureAudio ein. Rufen Sie nicht mehr als zwei Sekunden ab und kopieren Sie dann die Ausgabe, um ein Diagramm eines Liniendiagramms hervorzuheben. Sie sehen die Wellenform.

    29 May 2013
    FutureSci