通過java采集PC麥克風音頻及播放wav音頻文件


AudioFormat對象

sampleRate 采樣率 每秒音頻采樣數量
sampleSizeInBits 采樣位數  每個采樣的位數
channels 聲道 1: Mono 單聲道,2:Stereo 立體
signed 有符號無符號
bigEndian 大端模式存儲 還是小端模式存儲

采集麥克風音頻

	AudioFormat audioFormat = new AudioFormat(16000.0F, 16, 1, true, false);
	DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
	TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine(info);
	targetDataLine.open(audioFormat);
	targetDataLine.start();
	System.out.println("You can speak now!");
	int nByte = 0;
	final int bufSize = 3200;
	byte[] buffer = new byte[bufSize];
	while ((nByte = targetDataLine.read(buffer, 0, bufSize)) > 0) {
		// 直接發送麥克風數據流
		System.out.println( new String(buffer) );
	}

播放wav音頻文件

	AudioInputStream audioInputStream;// 文件流
	AudioFormat audioFormat;// 文件格式
	SourceDataLine sourceDataLine;// 輸出設備
	File file = new File("D:\\a.wav");

	// 取得文件輸入流
	audioInputStream = AudioSystem.getAudioInputStream(file);
	audioFormat = audioInputStream.getFormat();

	// 轉換文件編碼
	if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
		audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, audioFormat.getSampleRate(), 16,
				audioFormat.getChannels(), audioFormat.getChannels() * 2, audioFormat.getSampleRate(), false);
		audioInputStream = AudioSystem.getAudioInputStream(audioFormat, audioInputStream);
	}

	// 打開輸出設備
	DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED);
	sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
	sourceDataLine.open(audioFormat); // 打開具有指定格式的行,這樣可以使行獲得所有所需的系統資源並變得可操作
	sourceDataLine.start(); // 允許某一數據行執行數據I/O

	byte tempBuffer[] = new byte[320];
	try {
		int cnt;
		// 讀取數據到緩存區
		// 從音頻流讀取指定的最大數量的數據字節,並將其放入給定的字節數組中。
		// return: 讀入緩沖區的總字節數;如果因為已經到達流末尾而不再有更多數據,則返回-1
		while ((cnt = audioInputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) {
			if (cnt > 0) {
				// 寫入緩存數據
				sourceDataLine.write(tempBuffer, 0, cnt); // 通過此源數據行將音頻數據寫入混頻器
			}
		}
		// Block等待臨時數據被輸出為空
		// 通過在清空數據行的內部緩沖區之前繼續數據I/O,排空數據行中的列隊數據
		sourceDataLine.drain();
		// 關閉行,指示可以釋放的該行使用的所有系統資源。如果此操作成功,則將行標記為 closed,並給行的偵聽器指派一個 CLOSE 事件。
		sourceDataLine.close();
	} catch (Exception e) {
		e.printStackTrace();
		System.exit(0);
	}     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM