簡體   English   中英

實時java音量調節

[英]Real-time java sound volume adjustment

我使用 Java 的 SourceDataLine 播放聲音,但是每當我嘗試調整音量(增益)時,動作和揚聲器的響應之間都會有 0.2-0.5 秒的延遲。 音頻數據以 4k-16k 塊(16 位單聲道,22kHz ~ 44k/s)寫入。

我怎樣才能使這個音量調整更實時?

write(byte[], int, int)鎖定了 FloatControl 的增益調整?

我是否需要恢復到 DSP 方式同時調整聲音緩沖區數據量或提交較小的塊?

JDK7,體面的Windows PC

聲音系統從 SourceDataLine 以幾(數百...)千字節的塊獲取數據並緩沖它們。 如果你修改它的參數,它會在系統播放緩沖區為空並且從 SDL 讀取新數據后才會生效。

您需要做的是改變系統播放音量(立即生效)而不是修改您提供給它的數據。

在調用 SourceDataLine.open() 時,您是否嘗試過使用自定義(較低)緩沖區大小?

SourceDataLine.open( AudioFormat format, int bufferSize )

這應該會減少延遲。 盡管如此,主播放音量解決方案仍然可能會更快。

如果您可以以某種方式影響/創建您的 Mixer 為您的Line包含的Line.Info類,您可以更改其最小和最大緩沖區。 然后,您可以將緩沖區設置為您提供給它的塊的大小,然后您的延遲將減少到無(據說)

關於 Java SoundOracle 教程在其結束部分提供了使用 Float.Control 的替代答案:“直接操作音頻數據”。 通過直接操作數據,具有單幀粒度潛力的實時能力的可能性出現了。 不幸的是,他們沒有給出具體的例子。

基本方法是首先訪問各個 PCM 幀。 Clip不會對它存儲在內存中的數據提供任何掛鈎。 一種解決方案是在通過AudioInputStream加載文件時將字節處理為 PCM 。 PCM 值可以乘以音量因子以達到所需的音量。 然后,在 PCM 轉換回字節后,它可以由SourceDataLine播放。

對於實時響應,這里的關鍵是音量因子的處理。 AudioCue 中,我計划讓播放代碼公開一個公共的、松散耦合的“目標”音量。 在每幀的基礎上,將當前音量與所需的音量進行比較,並逐漸朝着所需的方向移動。 (音量變化在 1024 幀內線性發生,對於 44100 fps,大約為 1/40 秒。)可以在第 883 行的公共setVolume方法中觀察到一個代碼示例,具體是在第 892 行初始化平滑。代碼在處理循環中應用音量因子的地方是區域 1301-1322(在注釋行//adjust volume if needed之后的方法fillBuffer內的第二級for-loop中)。

在第一次提出問題多年后,我添加了這個答案。 我認為這是值得包含的,因為它提供了一個有用的替代方案,而在第一次提出問題時並沒有給出。

暫無
暫無

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

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