亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Android AudioTrack getPlaybackHeadPosition 總是返回 0

Android AudioTrack getPlaybackHeadPosition 總是返回 0

慕哥9229398 2022-06-30 11:14:07
我正在編寫一些旨在獲取 Wave 文件的代碼,并將其寫入模式流中的 AudioTrack。這是使 AudioTrack 流模式工作的最小可行測試。但是一旦我將一些音頻緩沖區寫入 AudioTrack,然后調用 play(),getPlaybackHeadPosition() 方法就會不斷返回 0。編輯:如果我忽略我的可用幀檢查,只是不斷地將緩沖區寫入 AudioTrack,則 write 方法返回 0(在第一次緩沖區寫入之后),表明它根本沒有再寫入任何音頻。所以似乎 AudioTrack 只是不想開始播放。我的代碼正確啟動了音軌。play 方法沒有拋出任何異常,所以我不確定出了什么問題。單步執行代碼時,我的所有內容都與我的預期完全一致,所以我在想我的 AudioTrack 配置錯誤。我在模擬器上運行,但我認為這不應該是一個問題。我使用的 WavFile 類是一個經過審查的類,我已經在許多 Java 項目中可靠地運行它,它經過測試運行良好。觀察以下日志寫入,這是來自較大代碼塊的片段。此日志寫入永遠不會命中...                if (headPosition > 0)                    Log.e("headPosition is greater than zero!!");..public static void writeToAudioTrackStream(final WavFile wave)     {    Log.e("writeToAudioTrackStream");    Thread thread = new Thread()    {        public void run()        {            try {                final float[] data = wave.getData();                int format = -1;                if (wave.getChannel() == 1)                    format = AudioFormat.CHANNEL_OUT_MONO;                else if (wave.getChannel() == 2)                    format = AudioFormat.CHANNEL_OUT_STEREO;                else                    throw new RuntimeException("writeToAudioTrackStatic() - unsupported number of channels value = "+wave.getChannel());                final int bufferSizeInFrames = 2048;                final int bytesPerSmp = wave.getBytesPerSmp();                final int bufferSizeInBytes = bufferSizeInFrames * bytesPerSmp * wave.getChannel();                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, wave.getSmpRate(),                        format,                        AudioFormat.ENCODING_PCM_FLOAT,                        bufferSizeInBytes,                        AudioTrack.MODE_STREAM);                int index = 0;                float[] buffer = new float[bufferSizeInFrames * wave.getChannel()];                boolean started = false;                int framesWritten = 0;
查看完整描述

1 回答

?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

根據文檔,

為了可移植性,應用程序應通過寫入數據將數據路徑設置為允許的最大值,直到 write() 方法返回一個短傳輸計數。這允許 play() 立即啟動,并減少欠載的機會。

仔細閱讀,這可能會與之前的說法相矛盾:

...您可以選擇在調用 play() 之前初始化數據路徑,方法是寫到 bufferSizeInBytes...

(強調我的),但意圖很清楚:你應該先寫一篇短文。

這只是為了開始游戲。實際上,一旦發生這種情況,您就可以 getPlaybackHeadPosition()用來確定何時有更多可用空間。我已經在我自己的代碼中成功地使用了這種技術,在許多不同的設備/API 級別上。

順便說一句:您應該準備好getPlaybackHeadPosition()僅以較大的增量進行更改(如果我沒記錯的話,它是getMinBufferSize()/2)。這是系統可用的最大分辨率;onMarkerReached()不能用來做得更好。


查看完整回答
反對 回復 2022-06-30
  • 1 回答
  • 0 關注
  • 400 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號