1 /* 2 * Copyright 2020 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc.audio; 12 13 import static org.junit.Assert.assertTrue; 14 import static org.mockito.AdditionalMatchers.gt; 15 import static org.mockito.AdditionalMatchers.lt; 16 import static org.mockito.ArgumentMatchers.anyInt; 17 import static org.mockito.Mockito.times; 18 import static org.mockito.Mockito.verify; 19 import static org.mockito.Mockito.when; 20 21 import android.media.AudioTrack; 22 import android.os.Build; 23 import androidx.test.runner.AndroidJUnit4; 24 import org.junit.Before; 25 import org.junit.Test; 26 import org.junit.runner.RunWith; 27 import org.mockito.Mock; 28 import org.mockito.MockitoAnnotations; 29 import org.robolectric.annotation.Config; 30 import org.webrtc.audio.LowLatencyAudioBufferManager; 31 32 /** 33 * Tests for LowLatencyAudioBufferManager. 34 */ 35 @RunWith(AndroidJUnit4.class) 36 @Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.O) 37 public class LowLatencyAudioBufferManagerTest { 38 @Mock private AudioTrack mockAudioTrack; 39 private LowLatencyAudioBufferManager bufferManager; 40 41 @Before setUp()42 public void setUp() { 43 MockitoAnnotations.initMocks(this); 44 bufferManager = new LowLatencyAudioBufferManager(); 45 } 46 47 @Test testBufferSizeDecrease()48 public void testBufferSizeDecrease() { 49 when(mockAudioTrack.getUnderrunCount()).thenReturn(0); 50 when(mockAudioTrack.getBufferSizeInFrames()).thenReturn(100); 51 when(mockAudioTrack.getPlaybackRate()).thenReturn(1000); 52 for (int i = 0; i < 9; i++) { 53 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 54 } 55 // Check that the buffer size was not changed yet. 56 verify(mockAudioTrack, times(0)).setBufferSizeInFrames(anyInt()); 57 // After the 10th call without underruns, we expect the buffer size to decrease. 58 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 59 // The expected size is 10ms below the existing size, which works out to 100 - (1000 / 100) 60 // = 90. 61 verify(mockAudioTrack, times(1)).setBufferSizeInFrames(90); 62 } 63 64 @Test testBufferSizeNeverBelow10ms()65 public void testBufferSizeNeverBelow10ms() { 66 when(mockAudioTrack.getUnderrunCount()).thenReturn(0); 67 when(mockAudioTrack.getBufferSizeInFrames()).thenReturn(11); 68 when(mockAudioTrack.getPlaybackRate()).thenReturn(1000); 69 for (int i = 0; i < 10; i++) { 70 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 71 } 72 // Check that the buffer size was not set to a value below 10 ms. 73 verify(mockAudioTrack, times(0)).setBufferSizeInFrames(lt(10)); 74 } 75 76 @Test testUnderrunBehavior()77 public void testUnderrunBehavior() { 78 when(mockAudioTrack.getUnderrunCount()).thenReturn(1); 79 when(mockAudioTrack.getBufferSizeInFrames()).thenReturn(100); 80 when(mockAudioTrack.getPlaybackRate()).thenReturn(1000); 81 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 82 // Check that the buffer size was increased after the underrrun. 83 verify(mockAudioTrack, times(1)).setBufferSizeInFrames(gt(100)); 84 when(mockAudioTrack.getUnderrunCount()).thenReturn(0); 85 for (int i = 0; i < 10; i++) { 86 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 87 } 88 // Check that the buffer size was not changed again, even though there were no underruns for 89 // 10 calls. 90 verify(mockAudioTrack, times(1)).setBufferSizeInFrames(anyInt()); 91 } 92 93 @Test testBufferIncrease()94 public void testBufferIncrease() { 95 when(mockAudioTrack.getBufferSizeInFrames()).thenReturn(100); 96 when(mockAudioTrack.getPlaybackRate()).thenReturn(1000); 97 for (int i = 1; i < 30; i++) { 98 when(mockAudioTrack.getUnderrunCount()).thenReturn(i); 99 bufferManager.maybeAdjustBufferSize(mockAudioTrack); 100 } 101 // Check that the buffer size was not increased more than 5 times. 102 verify(mockAudioTrack, times(5)).setBufferSizeInFrames(gt(100)); 103 } 104 } 105