簡體   English   中英

需要此流程的幫助(AudioInputStream->字節數組-> AudioOutputStream)

[英]Need Help for this flow (AudioInputStream -> byte Array -> AudioOutputStream)

我正在制作一個修改原始聲音的程序。

我程序的過程就在這里。

  1. AudioInputStream獲取聲音
  2. 將聲音數據更改為字節數組 。(我的AudioFormat的幀大小4。因此,我將使用長度為4的字節數組)
  3. 修改字節數組(類似於“將-1乘以每個元素”
  4. 將修改后的字節數組發送到AudioOutputStream
  5. 播放聲音。

我做了過程1和2和3。

這是我的過程1、2、3的代碼

try {
  byte[] packet = new byte[4];
  int result;

  while((result = audioInputStream.read(packet)) != -1)
    for(int i = 0;i < 4;i++)
      reflectedPacket[i] = (byte)(-1 * packet[i]);

      //I think I have to do something to send packet to AudioOutputStream in here
  }
catch(IOException ioe) {
  System.out.println(ioe.getMessage());
}

但是,我不知道該如何做4, 將修改后的字節數組發送到AudioOutputStream

我看到了一個使用ByteArrayInputStream的源。

但是,它是讀取文件的源,而不是AudioInput :(

如何處理第4和第5步?

我認為您沒有將audioInputStream正確讀取到byte數組中。 嘗試替換您的while和嵌套for循環:

int framesize = 4;
byte[] packet = new byte[framesize];
int numBytesRead = audioInputStream.read(packet, 0, framesize);
for(int i = 0; i < numBytesRead; i++)
  reflectedPacket[i] = (byte)(-1 * packet[i]);

順便說一句,我認為這是修改音頻流的非常不好的方法。 請查看Java Sound Info頁面和此文章,以獲取一些有用的鏈接,以修改音頻流。

無論如何....一旦修改了音頻流,就可以使用AudioSystem.getAudioInputStream(java.io.InputStream)來執行步驟4,如下所示:

AudioInputStream newStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(reflectedPacket));

最后,您將需要Clip界面播放聲音:

Clip clip = AudioSystem.getClip();
clip.open(newStream);

您要查找的“ AudioOutputStream”稱為SourceDataLine 可以從AudioSystem獲得, 這里有一個教程

但是,作為警告,

我的AudioFormat的幀大小是4。

除非您的音頻是具有4通道的8位音頻(我可以保證幾乎沒有),否則否定字節聽起來就像是失真。 這是因為幀中的字節是“打包的”,例如:

big-endian 16-bit stereo PCM frame

  b[0]     b[1]     b[2]     b[3]
00000000 00000000 00000000 00000000

where:
 - b[0] = left channel high byte
 - b[1] = left channel low byte
 - b[2] = right channel high byte
 - b[3] = right channel low byte

要打開此框架的包裝,您可以

int ch0 = (b[0] << 8) | (b[1] & 0xFF);
int ch1 = (b[2] << 8) | (b[3] & 0xFF);

要打包此框架,您可以

b[0] = (byte)((ch0 >>> 8) & 0xFF);
b[1] = (byte)( ch0        & 0xFF);
b[2] = (byte)((ch1 >>> 8) & 0xFF);
b[3] = (byte)( ch1        & 0xFF);

對於little-endian,高字節和低字節反轉。

另請參閱: JSR常見問題解答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM