Java - enregistrement depuis le mélangeur
J'ai un problème lié à ma question précédente. Je veux enregistrer de l'audio de mélangeur (haut-parleurs), je suis en utilisant javax.son. Je audioFormat et je ne sais pas quoi taper :/en Utilisant la classe ListMixer (que j'ai trouvé ici -> http://forums.oracle.com/forums/thread.jspa?threadID=2198477&tstart=2), j'écris quelque chose comme ceci: http://forums.oracle.com/forums/thread.jspa?threadID=2198477&tstart=2 mais je n'ai pas d'info sur la fréquence d'échantillonnage (inconnu fréquence d'échantillonnage). Le programme est en train de lancer cette exception:
java.lang.IllegalArgumentException: Ligne non pris en charge: interface TargetDataLine appui format PCM_UNSIGNED 44100.0 Hz, 8 bits, mono, 4 octets/cadre,
Code:
package sound;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.sound.sampled.*;
public class AudioCapture02 extends JFrame{
boolean stopCapture = false;
ByteArrayOutputStream byteArrayOutputStream;
AudioFormat audioFormat;
TargetDataLine targetDataLine;
AudioInputStream audioInputStream;
SourceDataLine sourceDataLine;
public AudioCapture02(){//constructor
final JButton captureBtn =
new JButton("Capture");
final JButton stopBtn = new JButton("Stop");
final JButton playBtn =
new JButton("Playback");
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(false);
//Register anonymous listeners
captureBtn.addActionListener(
new ActionListener(){
public void actionPerformed(
ActionEvent e){
captureBtn.setEnabled(false);
stopBtn.setEnabled(true);
playBtn.setEnabled(false);
//Capture input data from the
//microphone until the Stop button is
//clicked.
captureAudio();
}//end actionPerformed
}//end ActionListener
);//end addActionListener()
getContentPane().add(captureBtn);
stopBtn.addActionListener(
new ActionListener(){
public void actionPerformed(
ActionEvent e){
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
//Terminate the capturing of input data
//from the microphone.
stopCapture = true;
}//end actionPerformed
}//end ActionListener
);//end addActionListener()
getContentPane().add(stopBtn);
playBtn.addActionListener(
new ActionListener(){
public void actionPerformed(
ActionEvent e){
//Play back all of the data that was
//saved during capture.
playAudio();
}//end actionPerformed
}//end ActionListener
);//end addActionListener()
getContentPane().add(playBtn);
getContentPane().setLayout(new FlowLayout());
setTitle("Capture/Playback Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(250,70);
setVisible(true);
}//end constructor
//This method captures audio input from a
//microphone and saves it in a
//ByteArrayOutputStream object.
private void captureAudio(){
try{
//Get and display a list of
//available mixers.
Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
System.out.println("Available mixers:");
for(int cnt = 0; cnt < mixerInfo.length;
cnt++){
System.out.println(mixerInfo[cnt].
getName());
}//end for loop
//Get everything set up for capture
audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED, 44100.0F, 8, 1, 4, 44100.0F,
false);
DataLine.Info dataLineInfo =
new DataLine.Info(
TargetDataLine.class,
audioFormat);
ListMixers lm = new ListMixers();
lm.listAll(new PrintWriter(System.out));
System.out.println(" AKTUALNY => "+mixerInfo[0].getName());
Mixer mixer = AudioSystem.getMixer(mixerInfo[0]);
//Get a TargetDataLine on the selected
//mixer.
targetDataLine = (TargetDataLine)
mixer.getLine(dataLineInfo);
//Prepare the line for use.
targetDataLine.open(audioFormat);
targetDataLine.start();
//Create a thread to capture the microphone
//data and start it running. It will run
//until the Stop button is clicked.
Thread captureThread = new CaptureThread();
captureThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}//end catch
}//end captureAudio method
//This method plays back the audio data that
//has been saved in the ByteArrayOutputStream
private void playAudio() {
try{
//Get everything set up for playback.
//Get the previously-saved data into a byte
//array object.
byte audioData[] = byteArrayOutputStream.
toByteArray();
//Get an input stream on the byte array
//containing the data
InputStream byteArrayInputStream =
new ByteArrayInputStream(audioData);
AudioFormat audioFormat = getAudioFormat();
audioInputStream = new AudioInputStream(
byteArrayInputStream,
audioFormat,
audioData.length/audioFormat.
getFrameSize());
DataLine.Info dataLineInfo =
new DataLine.Info(
SourceDataLine.class,
audioFormat);
sourceDataLine = (SourceDataLine)
AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
//Create a thread to play back the data and
//start it running. It will run until
//all the data has been played back.
Thread playThread = new PlayThread();
playThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}//end catch
}//end playAudio
//This method creates and returns an
//AudioFormat object for a given set of format
//parameters. If these parameters don't work
//well for you, try some of the other
//allowable parameter values, which are shown
//in comments following the declartions.
private AudioFormat getAudioFormat(){
float sampleRate = 8000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = false;
//true,false
return new AudioFormat(
sampleRate,
sampleSizeInBits,
channels,
signed,
bigEndian);
}//end getAudioFormat
//=============================================//
//Inner class to capture data from microphone
class CaptureThread extends Thread{
//An arbitrary-size temporary holding buffer
byte tempBuffer[] = new byte[10000];
public void run(){
byteArrayOutputStream =
new ByteArrayOutputStream();
stopCapture = false;
try{//Loop until stopCapture is set by
//another thread that services the Stop
//button.
while(!stopCapture){
//Read data from the internal buffer of
//the data line.
int cnt = targetDataLine.read(tempBuffer,
0,
tempBuffer.length);
if(cnt > 0){
//Save data in output stream object.
byteArrayOutputStream.write(tempBuffer,
0,
cnt);
}//end if
}//end while
byteArrayOutputStream.close();
}catch (Exception e) {
System.out.println(e);
System.exit(0);
}//end catch
}//end run
}//end inner class CaptureThread
//===================================//
//Inner class to play back the data
//that was saved.
class PlayThread extends Thread{
byte tempBuffer[] = new byte[10000];
public void run(){
try{
int cnt;
//Keep looping until the input read method
//returns -1 for empty stream.
while((cnt = audioInputStream.read(
tempBuffer, 0,
tempBuffer.length)) != -1){
if(cnt > 0){
//Write data to the internal buffer of
//the data line where it will be
//delivered to the speaker.
sourceDataLine.write(tempBuffer,0,cnt);
}//end if
}//end while
//Block and wait for internal buffer of the
//data line to empty.
sourceDataLine.drain();
sourceDataLine.close();
}catch (Exception e) {
System.out.println(e);
System.exit(0);
}//end catch
}//end run
}//end inner class PlayThread
//=============================================//
class ListMixers {
PrintWriter out;
void listAll(final PrintWriter out) {
this.out = out;
Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
for (int i = 0; i < aInfos.length; i++) {
try {
Mixer mixer = AudioSystem.getMixer(aInfos[i]);
out.println(""+i+": "+aInfos[i].getName()+", "
+aInfos[i].getVendor()+", "
+aInfos[i].getVersion()+", "
+aInfos[i].getDescription());
printLines(mixer, mixer.getSourceLineInfo());
printLines(mixer, mixer.getTargetLineInfo());
} catch (Exception e) {
out.println("Exception: "+e);
}
out.println();
}
if (aInfos.length == 0) {
out.println("[No mixers available]");
}
}
void printLines(Mixer mixer, Line.Info[] infos) {
for (int i = 0; i < infos.length; i++) {
try {
if (infos[i] instanceof Port.Info) {
Port.Info info = (Port.Info) infos[i];
out.println(" Port " + info);
}
if (infos[i] instanceof DataLine.Info) {
DataLine.Info info = (DataLine.Info) infos[i];
out.println(" Line " + info + " (max. " +
mixer.getMaxLines(info) + " simultaneously): ");
printFormats(info);
}
Line line = mixer.getLine(infos[i]);
if (!(line instanceof Clip)) {
try {
line.open();
}
catch (LineUnavailableException e) {
out.println("LineUnavailableException when trying to open this line");
}
}
try {
printControls(line.getControls());
}
finally {
if (!(line instanceof Clip)) {
line.close();
}
}
}
catch (Exception e) {
out.println("Exception: " + e);
}
out.println();
}
}
void printFormats(DataLine.Info info) {
AudioFormat[] formats = info.getFormats();
for (int i = 0; i < formats.length; i++) {
out.println(" "+i+": "+formats[i]
+" ("+formats[i].getChannels()+" channels, "
+"frameSize="+formats[i].getFrameSize()+", "
+(formats[i].isBigEndian()?"big endian":"little endian")
+")");
}
if (formats.length == 0) {
out.println(" [no formats]");
}
out.println();
}
void printControls(Control[] controls) {
for (int i = 0; i<controls.length; i++) {
printControl(" ", "Controls["+i+"]: ", controls[i]);
}
if (controls.length == 0) {
out.println(" [no controls]");
}
out.println();
}
void printControl(String indent, String id, Control control) {
if (control instanceof BooleanControl) {
BooleanControl ctrl = (BooleanControl) control;
out.println(indent+id+"BooleanControl: "+ctrl);
} else if (control instanceof CompoundControl) {
CompoundControl ctrl = (CompoundControl) control;
Control[] ctrls = ctrl.getMemberControls();
out.println(indent+id+"CompoundControl: "+control);
for (int i=0; i<ctrls.length; i++) {
printControl(indent+" ", "MemberControls["+i+"]: ", ctrls[i]);
}
} else if (control instanceof EnumControl) {
EnumControl ctrl = (EnumControl) control;
Object[] values = ctrl.getValues();
Object value = ctrl.getValue();
out.println(indent+id+"EnumControl: "+control);
for (int i=0; i<values.length; i++) {
if (values[i] instanceof Control) {
printControl(indent+" ", "Values["+i+"]: "+((values[i]==value)?"*":""), (Control) values[i]);
} else {
out.println(indent+" Values["+i+"]: "+((values[i]==value)?"*":"")+values[i]);
}
}
} else if (control instanceof FloatControl) {
FloatControl ctrl = (FloatControl) control;
out.println(indent+id+"FloatControl: "+ctrl);
} else {
out.println(indent+id+"Control: "+control);
}
}
}
}//end outer class AudioCapture02.java
source d'informationauteur Krzysztof Kaczor
Vous devez vous connecter pour publier un commentaire.
Vous êtes l'obtention d'un TargetDataLine à l'aide d'un AudioFormat vous avez créé. Ce n'est pas garanti de fonctionner. Vous devez d'abord interroger la table de Mixage pour vérifier s'il prend en charge votre choix AudioFormat à l'aide de la
AudioSystem.isLineSupported(Info info)
méthode.Personnellement, je trouve ça assez lourd. Vous avez besoin d'interroger les Mélangeurs sur le système afin de déterminer s'ils prennent en charge la AudioFormat vous le souhaitez.
La fonction ci-dessous permettra d'obtenir un Vecteur de formats pris en charge pour une ligne de données de la classe. Appel à l'aide
ou
Ce code pourrait avoir besoin d'un peu de débogage; j'ai dû supprimer certains de mes application spécifique des choses pour le rendre autonome...
Il est possible d'obtenir toutes les éditions
Lines
et leurAudioFormats
directement. Je l'ai fait pour leSourceDataLines
de la valeur par défautMixer
sur le système, et vous pouvez facilement modifier le code pour obtenir n'importe quel type deLines
etAudioFormats
pris en charge par touteMixer
.Je obtenir un résultat comme ceci: