# Audio über Mikrofon einlesen



## xysawq (19. Aug 2008)

Hallo, habe schon gründlich Google und das Forum abgesucht, einige Lösungsansätze gefunden und getestet, aber nichts ist wirklich zufriedenstellend:

Mein letzter Versuch:

```
import java.io.IOException;
import javax.sound.sampled.*;

import java.io.File;

public class Main
{
	public static void main(String[] args) throws IOException, InterruptedException
	{
		TargetDataLine line = null;
		DataLine.Info info = new DataLine.Info(TargetDataLine.class, getAudioFormat());
		
		try
		{
			line = (TargetDataLine) AudioSystem.getLine(info);
			line.open(getAudioFormat());
		}
		catch (LineUnavailableException e)
		{
			e.printStackTrace();
		}
		
		line.start();
		AudioInputStream stream = new AudioInputStream(line);
		
		Stopper stopper = new Stopper(line, stream);
		stopper.start();
		
		File file = new File("D:/soundfile.wav");
		AudioSystem.write(stream, AudioFileFormat.Type.WAVE, file);
		
		System.out.println("Stopped...");
		System.in.read();
	}
	
	private static AudioFormat getAudioFormat()
	{
		AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_UNSIGNED;
		
		float sampleRate = 8000.0F;
		int sampleSizeInBits = 8;
		int channels = 1;
		int frameSize = 1;
		int frameRate = 8000;
		boolean bigEndian = false;			
		
		return new AudioFormat(encoding,
							   sampleRate,
							   sampleSizeInBits,
							   channels,
							   frameSize,
							   frameRate,
							   bigEndian);
	}
}
```


```
import java.io.IOException;
import javax.sound.sampled.*;

public class Stopper extends Thread
{
	TargetDataLine line = null;
	AudioInputStream stream = null;
	
	public Stopper(TargetDataLine line, AudioInputStream stream)
	{
		this.line = line;
		this.stream = stream;
	}
	
	public void run()
	{
		System.out.println("Press [RETURN] to stop capturing...");
		
		try
		{
			System.in.read();
		}
		catch (IOException e)
		{}
		
		line.stop();
		try
		{
			stream.close();
		}
		catch (IOException e)
		{}
	}
}
```

Dieses kleine Programm soll über das Mikrofon Sound aufnehmen und in die Datei "soundfile.wav" speichern. (Ich möchte später meine Mikrofonaufnahme in ein RTP-Programm einbauen... also bitte keine tollen Tutorials wie: "Wie speichere ich Audio.").

Das Problem hierbei ist, dass ich jede Menge Störgeräusche in der WAV-Datei habe, ansonsten funktioniert es aber... wenn bei euch beim Testen keine Störgeräusche zu hören sind, sagt bescheid.


Eine andere Methode war noch statt:

```
line = (TargetDataLine) AudioSystem.getLine(info);
```
eher das zu nehmen:

```
line = (Port) AudioSystem.getLine(Port.Info.MICROPHONE);
//bzw.
line = (TargetDataLine) AudioSystem.getLine(Port.Info.MICROPHONE);
```

Nur leider kann man aus der Port-Variante keine Daten auslesen geschweige denn irgendetwas damit anfangen und das Casten nach TargetDataLine funktioniert nich (CastException).


Also was tun?


----------



## foobar (19. Aug 2008)

Hmm, das kann eigentlich nur am AudioFormat liegen. Man sollte in mit der Sampelrate nicht unter 16 oder 22 khz gehen, weil Java damit nicht klar kommt. 
Ich nehme immer in CD-Qualität auf und komprimiere dann mit Ulaw, Alaw oder JSpeex. JSpeex bringt dabei natürlich das beste Ergebnis ;-)


----------



## xysawq (19. Aug 2008)

Das Ändern der Samplerate bringt keine Verbesserung, es rauscht immernoch wie blöde...

Hab übrigens mal nen kleinen Test gemacht, der mich sehr verwundert hat:


```
Line.Info[] infos = AudioSystem.getTargetLineInfo(Port.Info.LINE_IN);
System.out.println(infos.length);

//und

Line.Info[] infos = AudioSystem.getTargetLineInfo(Port.Info.MICROPHONE);
System.out.println(infos.length);
```

geben beide 0 aus, aber:


```
Line.Info[] infos = AudioSystem.getSourceLineInfo(Port.Info.LINE_IN);
System.out.println(infos.length);

//und

Line.Info[] infos = AudioSystem.getSourceLineInfo(Port.Info.MICROPHONE);
System.out.println(infos.length);
```

geben beide 1 aus, soll heißen die SourceLines beschreiben Mikrofon und Line-In, was vom Namen her auch logisch ist.

Leider muss man das mit TargetLines machen und Ports gehen sowieso nicht, mit denen komme ich nicht klar, der Sinn ist mir fremd.


Schon irgendwie schade, dass es da nichts besseres gibt.


----------



## foobar (19. Aug 2008)

Hast du das ganze mal mit einer anderen Software wie Audacity verglichen? Vielleicht liegts ja am Mikro.

Also ich mache das so:


```
private void startRecording()
        {
            try
            {
                recordingLine                           = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, AUDIO_FORMAT,AudioSystem.NOT_SPECIFIED));
                AudioInputStream ais               = new AudioInputStream(recordingLine);
                AudioFormat targetFormat        = new AudioFormat(targetEncoding,AUDIO_FORMAT.getSampleRate() ,-1,AUDIO_FORMAT.getChannels(),  -1,  -1,  false);
                ais                                             = AudioSystem.getAudioInputStream(targetFormat,ais);
                recordingLine.open(AUDIO_FORMAT);
                recordingLine.start();
                timeStartRecording              = System.currentTimeMillis();
                AudioSystem.write(ais, targetType,out);
                
            }
            catch (LineUnavailableException e)
            {
                Starter.showErrorMessage( e );
            }
            catch (IOException e)
            {
                Starter.showErrorMessage( e );
            }
        }
```

BTW Java Sound API nervt :-(


----------



## xysawq (19. Aug 2008)

Danke für die Hilfe, bei Audacity klingt es besser, aber immernoch mit leichtem rauschen... hab mir jetzt aus nem anderen Büro ein besseres Mikro geliehen, mit dem klingt es einwandfrei :/.

Naja, danke für die Hilfe, auch wenns nicht an java lag... btw: java sound api nervt wirklich >:-(


----------

