I have written a little java aplication to handle this. The program basically have 4 buttons: record, play, stop and save. Record starts the recording, Stop stops it, Play plays it, and Save saves it to user specified location.
I can record audio using just arecord. So the hardware seems to be working fine.
The program runs correctly on windows, but when i run it on the pi it seems to start recording and stop the recording corectly, but then when I try to either play or save the program crashes with the following error:
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian not supported.
Now I do not really have a clue where to go from here, thus Im asking for help. here is the intresting part of the code.
Code: Select all
package audio;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.Flushable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Controller {
AudioFormat format;
TargetDataLine targLine = null;
ByteArrayOutputStream output = null;
AudioInputStream input;
SourceDataLine srcLine = null;
boolean stopCapture = false;
// Metoden fångar ljud ingång från mikrofonen och sparar den i ett
// ByteArrayOutPutStream object.
public void startRecord() {
try {
format = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
if(!AudioSystem.isLineSupported(dataLineInfo)){
JOptionPane.showMessageDialog(null,"Line is Not Supported");
}
// Lines är digital audio.
// targetdataline är en typ av datalinje som audio data kan läsas
// från.
targLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
targLine.open(format);
targLine.start();
// Skapar en tråd för att fånga data från mikrofonen och startar
// micken och avslutar tills man tryckt på stop knappen
Thread captureThread = new CaptureThread();
captureThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
// // En inre klass som fångar data från microfonen
// en data array som temporärt håller i data.
private class CaptureThread extends Thread {
byte data[] = new byte[100000];
public void run() {
output = new ByteArrayOutputStream();
stopCapture = false;
// Loopar till stop knappen är tryckt.
try {
while (!stopCapture) {
// Läser data från targetDataline.
int count = targLine.read(data, 0, data.length);
if (count > 0) {
// Sparar data i en output stream objekt.
output.write(data, 0, count);
}
}
output.close();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
}
// Metoden skapar och returnerar ett AudioFormat object.
public AudioFormat getAudioFormat() {
float sampleRate = 44100;
int sampleSizeInBits = 16;
int channels = 2;
boolean signed = true;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
bigEndian);
}
// Denna metod spelar tillbaka den ljud data som har lagrats i
// ByteArrayOutputStream,
public void startPlay() {
// Här så kommer vi att hämta den föregående data som sparats i en byte
// array objekt.
try {
byte audioData[] = output.toByteArray();
InputStream byteArrayInputStream = new ByteArrayInputStream(
audioData);
AudioFormat audioFormat = getAudioFormat();
input = new AudioInputStream(byteArrayInputStream, audioFormat,
audioData.length / audioFormat.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class, audioFormat);
// Sourcedataline är en data linje där man kan skriva in data.
srcLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
srcLine.open(audioFormat);
srcLine.start();
// Skapar en tråd som spelar upp datan och startar den och den körs
// till all data har spelats så vida du inte trycker
// på stop.
Thread playThread = new PlayThread();
playThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
private class PlayThread extends Thread {
byte buff[] = new byte[100000];
public void run() {
try {
int count;
while ((count = input.read(buff, 0, buff.length)) != -1) {
if (count > 0) {
srcLine.write(buff, 0, count);
}
}
srcLine.drain();
srcLine.close();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
}
public void save() {
try {
byte audioData[] = output.toByteArray();
InputStream byteArrayInputStream = new ByteArrayInputStream(
audioData);
AudioFormat audioFormat = getAudioFormat();
input = new AudioInputStream(byteArrayInputStream, audioFormat,
audioData.length / audioFormat.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class, audioFormat);
srcLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
srcLine.open(audioFormat);
srcLine.start();
Thread saveThread = new SaveThread();
saveThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
class SaveThread extends Thread {
public void run() {
AudioFileFormat.Type type = AudioFileFormat.Type.WAVE;
File file = new File("");
JFileChooser choose = new JFileChooser();
choose.setSelectedFile(new File(".mp3"));
int use = choose.showSaveDialog(choose);
if (use == JFileChooser.APPROVE_OPTION) {
file = choose.getSelectedFile();
JOptionPane.showMessageDialog(null,
"Congratulations You Have Just Saved Your File");
} else if (use == JFileChooser.CANCEL_OPTION) {
JOptionPane.showMessageDialog(null, "Srry");
}
try {
byte audio[] = output.toByteArray();
InputStream input = new ByteArrayInputStream(audio);
final AudioFormat format = getAudioFormat();
final AudioInputStream audioInputStream = new AudioInputStream(
input, format, audio.length / format.getFrameSize());
AudioSystem.write(audioInputStream, type, file);
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
}
public void stopPlay() {
try {
targLine.flush();
targLine.drain();
targLine.stop();
targLine.close();
if (srcLine != null) {
srcLine.flush();
srcLine.drain();
srcLine.stop();
srcLine.close();
}
byte audioData[] = output.toByteArray();
InputStream byteArrayInputStream = new ByteArrayInputStream(
audioData);
AudioFormat audioFormat = getAudioFormat();
input = new AudioInputStream(byteArrayInputStream, audioFormat,
audioData.length / audioFormat.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class, audioFormat);
srcLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
srcLine.open(audioFormat);
srcLine.start();
output.flush();
output.close();
byteArrayInputStream.close();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}
public void mixer(){
Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
for (int i = 0; i < mixerInfo.length; i++) {
System.out.println(mixerInfo[i].getName());
}// end for loop
}
}