2016-01-19 15 views
8

Tôi đang sử dụng AudioTrack để phát một chuỗi sóng sin, nhưng khi tôi chạy trên HTC M9, nó chỉ phát một phần trong các mẫu và thời gian phát ngẫu nhiên. e. g. Tôi có 20 tấn để chơi, nhưng nó chỉ chơi như 2 đến 17,5 tấn của họ. Và có nó thậm chí sẽ dừng lại ở giữa một giai điệu.Android AudioTrack không phát tất cả các mẫu

Đây là mã của tôi, từ câu trả lời khác:

ArrayList<double[]> samples = new ArrayList<>(); 
    int numSamples = 0; 
    for (final ToneSegment seg : sequence) { 
     int num = seg.getDuration() * sampleRate/1000; 
     double[] sample = new double[num]; 
     for (int i = 0; i < num; ++i) { 
      sample[i] = Math.sin(2 * Math.PI * i * seg.getPitch()/sampleRate); 
     } 
     samples.add(sample); 
     numSamples += num; 
    } 

    byte generatedSnd[] = new byte[2 * numSamples]; 
    int idx = 0; 
    for (double[] sample : samples) { 
     for (final double dVal : sample) { 
      final short val = (short) ((dVal * 32767)); 
      generatedSnd[idx++] = (byte) (val & 0x00ff); 
      generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     } 
    } 

    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
      sampleRate, AudioFormat.CHANNEL_OUT_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 
      AudioTrack.MODE_STATIC); 
    audioTrack.write(generatedSnd, 0, generatedSnd.length); 
    audioTrack.play(); 

Có ai có bất kỳ ý tưởng? Cảm ơn!

Trả lời

0

Có thể bộ sưu tập rác gây ra sự cố này. Tôi đã viết mã này trong một phương thức trả về ngay lập tức, vì đối tượng audioTrack sẽ mất tham chiếu đến nó. Nếu thu gom rác xảy ra trong khi phát lại, audioTrack sẽ được hoàn thành và ngừng phát nhạc chuông. Do đó vấn đề này thỉnh thoảng xảy ra, tùy thuộc vào cách hoạt động của GC khi phát nhạc chuông.

Vì vậy, tôi cần giữ tham chiếu đối tượng AudioTrack cho đến khi phát lại kết thúc. Tôi nghĩ rằng có rất nhiều cách để làm điều này, nhưng cuối cùng tôi sử dụng cách đơn giản nhất:

class Player { 
    private static AudioTrack sAudioTrack; 
} 

MediaPlayer cũng có cạm bẫy này, và là cách tôi tìm thấy được vấn đề vì nó sẽ viết log rằng nó hoàn tất trước khi phát hành.

2

Bạn đang sử dụng AudioTrack.MODE_STATIC dành cho âm thanh ngắn và yêu cầu độ trễ thấp trong khi bạn nên sử dụng AudioTrack.MODE_STREAM. AudioTrack.MODE_STREAM có nghĩa là cho các luồng dài hơn, nhưng tôi không biết các mẫu của bạn dài bao lâu. Vì vậy, bạn có thể thử và thay đổi AudioTrack:

audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     sampleRate, AudioFormat.CHANNEL_OUT_MONO, 
     AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, 
     AudioTrack.MODE_STREAM); 

Cũng Các AudioTrack yêu cầu kích thước bộ đệm trong byte, một nhu cầu ngắn để được nhân bởi hai để tính toán số lượng byte đúng yêu cầu. Bạn có thể hack nó như thế này:

audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     sampleRate, AudioFormat.CHANNEL_OUT_MONO, 
     AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length*2, 
     AudioTrack.MODE_STREAM); 
+0

Tôi đã thử MODE_STREAM, nhưng cũng vậy. Mẫu của tôi chỉ phát trong 3 đến 7 giây. –

+0

Họ chơi trong một khoảng thời gian ngẫu nhiên? Bạn đã thử các mẫu âm thanh ngắn hơn hay các mẫu âm thanh khác chưa? Và bạn có nhân số byte quá không? – jobbert

+0

Có, tôi đã thử các mẫu khác. Chúng không phải là thời gian ngẫu nhiên. Điều gì là nhân số lượng byte? –

Các vấn đề liên quan