Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
0a8e5d97
authored
Feb 02, 2022
by
kimvde
Committed by
Ian Baker
Feb 04, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add SpeedChangingAudioProcessorTest
PiperOrigin-RevId: 425845144
parent
b911e2ee
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
451 additions
and
2 deletions
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SpeedChangingAudioProcessor.java
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/SpeedChangingAudioProcessorTest.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SpeedChangingAudioProcessor.java
View file @
0a8e5d97
...
@@ -68,9 +68,8 @@ import java.nio.ByteBuffer;
...
@@ -68,9 +68,8 @@ import java.nio.ByteBuffer;
if
(
isUsingSonic
())
{
if
(
isUsingSonic
())
{
sonicAudioProcessor
.
setSpeed
(
newSpeed
);
sonicAudioProcessor
.
setSpeed
(
newSpeed
);
sonicAudioProcessor
.
setPitch
(
newSpeed
);
sonicAudioProcessor
.
setPitch
(
newSpeed
);
sonicAudioProcessor
.
flush
();
endOfStreamQueuedToSonic
=
false
;
}
}
flush
();
}
}
int
inputBufferLimit
=
inputBuffer
.
limit
();
int
inputBufferLimit
=
inputBuffer
.
limit
();
...
...
library/transformer/src/test/java/com/google/android/exoplayer2/transformer/SpeedChangingAudioProcessorTest.java
0 → 100644
View file @
0a8e5d97
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkArgument
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.audio.AudioProcessor
;
import
com.google.android.exoplayer2.util.Util
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit tests for {@link SpeedChangingAudioProcessor}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
SpeedChangingAudioProcessorTest
{
private
static
final
AudioProcessor
.
AudioFormat
AUDIO_FORMAT
=
new
AudioProcessor
.
AudioFormat
(
/* sampleRate= */
44100
,
/* channelCount= */
2
,
/* encoding= */
C
.
ENCODING_PCM_16BIT
);
@Test
public
void
queueInput_noSpeedChange_doesNotOverwriteInput
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
assertThat
(
inputBuffer
).
isEqualTo
(
getInputBuffer
(
/* frameCount= */
5
));
}
@Test
public
void
queueInput_speedChange_doesNotOverwriteInput
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
assertThat
(
inputBuffer
).
isEqualTo
(
getInputBuffer
(
/* frameCount= */
5
));
}
@Test
public
void
queueInput_noSpeedChange_copiesSamples
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
inputBuffer
.
rewind
();
assertThat
(
outputBuffer
).
isEqualTo
(
inputBuffer
);
}
@Test
public
void
queueInput_speedChange_modifiesSamples
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
inputBuffer
.
rewind
();
assertThat
(
outputBuffer
.
hasRemaining
()).
isTrue
();
assertThat
(
outputBuffer
).
isNotEqualTo
(
inputBuffer
);
}
@Test
public
void
queueInput_noSpeedChangeAfterSpeedChange_copiesSamples
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
2
,
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
inputBuffer
.
rewind
();
assertThat
(
outputBuffer
).
isEqualTo
(
inputBuffer
);
}
@Test
public
void
queueInput_speedChangeAfterNoSpeedChange_producesSameOutputAsSingleSpeedChange
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
1
,
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
expectedOutputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
outputBuffer
.
hasRemaining
()).
isTrue
();
assertThat
(
outputBuffer
).
isEqualTo
(
expectedOutputBuffer
);
}
@Test
public
void
queueInput_speedChangeAfterSpeedChange_producesSameOutputAsSingleSpeedChange
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
3
,
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
expectedOutputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
outputBuffer
.
hasRemaining
()).
isTrue
();
assertThat
(
outputBuffer
).
isEqualTo
(
expectedOutputBuffer
);
}
@Test
public
void
queueInput_speedChangeBeforeSpeedChange_producesSameOutputAsSingleSpeedChange
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
2
,
3
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
ByteBuffer
outputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
ByteBuffer
expectedOutputBuffer
=
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
outputBuffer
.
hasRemaining
()).
isTrue
();
assertThat
(
outputBuffer
).
isEqualTo
(
expectedOutputBuffer
);
}
@Test
public
void
queueInput_multipleSpeedsInBufferWithLimitAtFrameBoundary_readsDataUntilSpeedLimit
()
throws
Exception
{
long
speedChangeTimeUs
=
4
*
C
.
MICROS_PER_SECOND
/
AUDIO_FORMAT
.
sampleRate
;
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithStartTimes
(
/* startTimesUs= */
new
long
[]
{
0L
,
speedChangeTimeUs
},
/* speeds= */
new
float
[]
{
1
,
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
int
inputBufferLimit
=
inputBuffer
.
limit
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
assertThat
(
inputBuffer
.
position
()).
isEqualTo
(
4
*
AUDIO_FORMAT
.
bytesPerFrame
);
assertThat
(
inputBuffer
.
limit
()).
isEqualTo
(
inputBufferLimit
);
}
@Test
public
void
queueInput_multipleSpeedsInBufferWithLimitInsideFrame_readsDataUntilSpeedLimit
()
throws
Exception
{
long
speedChangeTimeUs
=
(
long
)
(
3.5
*
C
.
MICROS_PER_SECOND
/
AUDIO_FORMAT
.
sampleRate
);
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithStartTimes
(
/* startTimesUs= */
new
long
[]
{
0L
,
speedChangeTimeUs
},
/* speeds= */
new
float
[]
{
1
,
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
int
inputBufferLimit
=
inputBuffer
.
limit
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
assertThat
(
inputBuffer
.
position
()).
isEqualTo
(
4
*
AUDIO_FORMAT
.
bytesPerFrame
);
assertThat
(
inputBuffer
.
limit
()).
isEqualTo
(
inputBufferLimit
);
}
@Test
public
void
queueEndOfStream_afterNoSpeedChangeAndWithOutputRetrieved_endsProcessor
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
2
,
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isTrue
();
}
@Test
public
void
queueEndOfStream_afterSpeedChangeAndWithOutputRetrieved_endsProcessor
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
,
5
},
/* speeds= */
new
float
[]
{
1
,
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
inputBuffer
.
rewind
();
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isTrue
();
}
@Test
public
void
queueEndOfStream_afterNoSpeedChangeAndWithOutputNotRetrieved_doesNotEndProcessor
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isFalse
();
}
@Test
public
void
queueEndOfStream_afterSpeedChangeAndWithOutputNotRetrieved_doesNotEndProcessor
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
speedChangingAudioProcessor
.
queueEndOfStream
();
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isFalse
();
}
@Test
public
void
queueEndOfStream_noInputQueued_endsProcessor
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
speedChangingAudioProcessor
.
queueEndOfStream
();
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isTrue
();
}
@Test
public
void
isEnded_afterNoSpeedChangeAndOutputRetrieved_isFalse
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
1
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isFalse
();
}
@Test
public
void
isEnded_afterSpeedChangeAndOutputRetrieved_isFalse
()
throws
Exception
{
SpeedProvider
speedProvider
=
TestSpeedProvider
.
createWithFrameCounts
(
/* frameCounts= */
new
int
[]
{
5
},
/* speeds= */
new
float
[]
{
2
});
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
getConfiguredSpeedChangingAudioProcessor
(
speedProvider
);
ByteBuffer
inputBuffer
=
getInputBuffer
(
/* frameCount= */
5
);
speedChangingAudioProcessor
.
queueInput
(
inputBuffer
);
getAudioProcessorOutput
(
speedChangingAudioProcessor
);
assertThat
(
speedChangingAudioProcessor
.
isEnded
()).
isFalse
();
}
private
static
SpeedChangingAudioProcessor
getConfiguredSpeedChangingAudioProcessor
(
SpeedProvider
speedProvider
)
throws
AudioProcessor
.
UnhandledAudioFormatException
{
SpeedChangingAudioProcessor
speedChangingAudioProcessor
=
new
SpeedChangingAudioProcessor
(
speedProvider
);
speedChangingAudioProcessor
.
configure
(
AUDIO_FORMAT
);
speedChangingAudioProcessor
.
flush
();
return
speedChangingAudioProcessor
;
}
private
static
ByteBuffer
getInputBuffer
(
int
frameCount
)
{
int
bufferSize
=
frameCount
*
AUDIO_FORMAT
.
bytesPerFrame
;
ByteBuffer
buffer
=
ByteBuffer
.
allocateDirect
(
bufferSize
).
order
(
ByteOrder
.
nativeOrder
());
for
(
int
i
=
0
;
i
<
bufferSize
;
i
++)
{
buffer
.
put
((
byte
)
(
i
%
(
Byte
.
MAX_VALUE
+
1
)));
}
buffer
.
rewind
();
return
buffer
;
}
private
static
ByteBuffer
getAudioProcessorOutput
(
AudioProcessor
audioProcessor
)
{
ByteBuffer
concatenatedOutputBuffers
=
ByteBuffer
.
allocateDirect
(
0
).
order
(
ByteOrder
.
nativeOrder
());
while
(
true
)
{
ByteBuffer
outputBuffer
=
audioProcessor
.
getOutput
();
if
(!
outputBuffer
.
hasRemaining
())
{
break
;
}
ByteBuffer
temp
=
ByteBuffer
.
allocateDirect
(
concatenatedOutputBuffers
.
remaining
()
+
outputBuffer
.
remaining
())
.
order
(
ByteOrder
.
nativeOrder
());
temp
.
put
(
concatenatedOutputBuffers
);
temp
.
put
(
outputBuffer
);
temp
.
rewind
();
concatenatedOutputBuffers
=
temp
;
}
return
concatenatedOutputBuffers
;
}
private
static
final
class
TestSpeedProvider
implements
SpeedProvider
{
private
final
long
[]
startTimesUs
;
private
final
float
[]
speeds
;
/**
* Creates a {@code TestSpeedProvider} instance.
*
* @param startTimesUs The speed change start times, in microseconds. The values must be
* distinct and in increasing order.
* @param speeds The speeds corresponding to each start time. Consecutive values must be
* distinct.
* @return A {@code TestSpeedProvider}.
*/
public
static
TestSpeedProvider
createWithStartTimes
(
long
[]
startTimesUs
,
float
[]
speeds
)
{
return
new
TestSpeedProvider
(
startTimesUs
,
speeds
);
}
/**
* Creates a {@code TestSpeedProvider} instance.
*
* @param frameCounts The frame counts for which the same speed should be applied.
* @param speeds The speeds corresponding to each frame count. The values must be distinct.
* @return A {@code TestSpeedProvider}.
*/
public
static
TestSpeedProvider
createWithFrameCounts
(
int
[]
frameCounts
,
float
[]
speeds
)
{
long
[]
startTimesUs
=
new
long
[
frameCounts
.
length
];
int
totalFrameCount
=
0
;
for
(
int
i
=
0
;
i
<
frameCounts
.
length
;
i
++)
{
startTimesUs
[
i
]
=
totalFrameCount
*
C
.
MICROS_PER_SECOND
/
AUDIO_FORMAT
.
sampleRate
;
totalFrameCount
+=
frameCounts
[
i
];
}
return
new
TestSpeedProvider
(
startTimesUs
,
speeds
);
}
private
TestSpeedProvider
(
long
[]
startTimesUs
,
float
[]
speeds
)
{
checkArgument
(
startTimesUs
.
length
==
speeds
.
length
);
this
.
startTimesUs
=
startTimesUs
;
this
.
speeds
=
speeds
;
}
@Override
public
float
getSpeed
(
long
timeUs
)
{
int
index
=
Util
.
binarySearchFloor
(
startTimesUs
,
timeUs
,
/* inclusive= */
true
,
/* stayInBounds= */
true
);
return
speeds
[
index
];
}
@Override
public
long
getNextSpeedChangeTimeUs
(
long
timeUs
)
{
int
index
=
Util
.
binarySearchCeil
(
startTimesUs
,
timeUs
,
/* inclusive= */
false
,
/* stayInBounds= */
false
);
return
index
<
startTimesUs
.
length
?
startTimesUs
[
index
]
:
C
.
TIME_UNSET
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment