Java - Audio Levels

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • xchris
    New Member
    • Dec 2013
    • 4

    Java - Audio Levels

    Hello

    I'm new to programming and I'm trying to make a java application that will "hear" (not record necessarily) the sound and display how loud is.I'm thinking of converting the sound recordings to numbers,so I can see the difference on the sound levels.I got this code and I added the "getLevel() " method,which returns the amplitude of the current recording,but it's returning -1 everytime.I guess I'm not using it properly.Any ideas how I must call this method?I have to deliver my project in a week,so any help will be much appreciated!

    Code:
    public class Capture extends JFrame {
    
    	  protected boolean running;
    	  ByteArrayOutputStream out;
    
    	  public Capture() {
    	    super("Capture Sound Demo");
    	    setDefaultCloseOperation(EXIT_ON_CLOSE);
    	    Container content = getContentPane();
    
    	    final JButton capture = new JButton("Capture");
    	    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);
    	               
    	                System.out.println(line.getLevel());  // |-this is what i added-|
    	              }
    	            }
    	            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);
    	  }
    	  
    	  @SuppressWarnings("deprecation")
    	public static void main(String args[]) {
    	    JFrame frame = new Capture();
    	    frame.pack();
    	    frame.show();
    	  }	  
    }
  • xchris
    New Member
    • Dec 2013
    • 4

    #2
    Ok,I managed to make it capture audio and print on a xls file the timestamp and the value of the current sample,but there is a problem : even I've put some spaces between the time and the value and it seems that they are in different columns,they are actualy on the same column of the xls,it's just expanded and covers the next column (I can put a print screen if you don't understand).How can I make it print the data of time and amplitude in two different columns?Here's my code of the class which creates the file and saves the data on xls :

    Code:
    package soundRecording;
    
    import java.io.File;
    import java.util.Formatter;
    
    
    public class Save {
    	
    	static Formatter y;
    
    	public static void createFile() {
    	
    		Date thedate = new Date();
    		final String folder = thedate.curDate();
    		final String fileName = thedate.curTime();
    	
    	try {
    		String name = "Time_"+fileName+".csv";
    		y = new Formatter(name);
    		File nof = new File(name);
    		nof.createNewFile();
    		System.out.println("A new file was created.");
    	}
    	catch(Exception e) {
    		System.out.println("There was an error.");
    		}
    	}
    	
    	public void addValues(byte audio) {
    		Date d = new Date();
    		y.format("%s    " + "  %s%n",d.curTime(), audio);
    	}
    	
    	public void closeFile() {
    		y.close();
    	}
    }

    Comment

    • chaarmann
      Recognized Expert Contributor
      • Nov 2007
      • 785

      #3
      If you use CSV, you need to separate the columns by comma.
      Spaces are not working. if you have data that contains comma, then you also need to use quotation marks surrounding the columns. An example with 2 columns:
      Code:
      "This is, and it really is, column 1", "Spaces and     tabs do not disturb me"
      By the way, why do you use "thedate" and not "theDate", "aDate", "myDate" or "ourDate"? You just started programming, so don't get used to bad habits. Simply name it "date".
      And what is "nof"? Is it that what the fox says? No? Then why didn't you name it "batman" instead? Just kidding!
      But please, no kidding, use meaningful names!

      Comment

      • xchris
        New Member
        • Dec 2013
        • 4

        #4
        Thanks for your help and your example,I understood how to use it.

        About the variable names,you are right about "thedate",I should name it "theDate".I didn't want to use just "date",beca use "Date" is the name of my class (I know that "date" and "Date" are different),but I wanted to make clear that this reffers to a specific day,so I named it "thedate".
        "nof" stands for "name of file".Although "batman" would be cool,I'll propably use it in my next java project!

        Comment

        • chaarmann
          Recognized Expert Contributor
          • Nov 2007
          • 785

          #5
          If you name a variable "date", because it is an instance of class Date, then that is a good thing. Every programmer then can easily remember what it is. Prefixes like "the" "a" "our" or "my" do not add anything to understand the meaning of the variable. They are just typing clutter and makes it longer and harder (explanation see below) to read. If you want to make clear that this variable refers to a specific day, then just name that day and what is so specific on it. For example you could name the variable "today", "yesterday" , "christmasE ve". In a more general form, you could name it "oldDate" if there also exists a "newDate". That means, if you use many dates, don't call them "date1", "date2" etc., but put the difference in a meaningful name, like "birthdayOfCat" , "birthdayOfDog" .

          Explanation: Usually you know the name of a variable without reading all letters, you just read the first 2 letters (and maybe the last 2 letters and your brain already delivers the meaning) But it cannot do that if all your local variables start with "the" and ends with "String". Just test yourself: can you figure out the odd one out faster in the first or second line?

          First line:
          theframestring theframestring theframestring theframestring theframestring theframestring theframestring thegreenstring theframestring theframestring theframestring theframestring

          Second line:
          frame frame frame frame frame green frame frame frame frame frame frame frame frame

          P.s: If your variable is only used temporary (for example a loop counter), that means within the surrounding 5 lines of code, then just give it a single letter.

          Comment

          • xchris
            New Member
            • Dec 2013
            • 4

            #6
            Thanks,I'll try to do that on my future codes!

            Comment

            Working...