summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2015-04-10 03:28:12 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-04-10 03:28:12 +0000
commit7d014e50b3acd60e73ed7d7a74dc58485c7a413c (patch)
treed2d5a07889b721c5d775c9da8c9dbc0531d19173 /include
parente62e16371b6c2f33072b3345e1d1853673b9a3d8 (diff)
parent8edb8dc44b8a2f81bdb5db645b6b708548771a31 (diff)
downloadframeworks_av-7d014e50b3acd60e73ed7d7a74dc58485c7a413c.zip
frameworks_av-7d014e50b3acd60e73ed7d7a74dc58485c7a413c.tar.gz
frameworks_av-7d014e50b3acd60e73ed7d7a74dc58485c7a413c.tar.bz2
Merge "Add playback rate to AudioTrack"
Diffstat (limited to 'include')
-rw-r--r--include/media/AudioResamplerPublic.h11
-rw-r--r--include/media/AudioTrack.h20
-rw-r--r--include/private/media/AudioTrackShared.h36
3 files changed, 65 insertions, 2 deletions
diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h
index 3c30148..07d946d 100644
--- a/include/media/AudioResamplerPublic.h
+++ b/include/media/AudioResamplerPublic.h
@@ -42,6 +42,8 @@
#define AUDIO_TIMESTRETCH_PITCH_MAX 2.0f
#define AUDIO_TIMESTRETCH_PITCH_NORMAL 1.0f
+// TODO: Consider putting these inlines into a class scope
+
// Returns the source frames needed to resample to destination frames. This is not a precise
// value and depends on the resampler (and possibly how it handles rounding internally).
// Nevertheless, this should be an upper bound on the requirements of the resampler.
@@ -66,4 +68,13 @@ static inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSam
return dstFrames > 2 ? dstFrames - 2 : 0;
}
+static inline size_t sourceFramesNeededWithTimestretch(
+ uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate,
+ float speed) {
+ // required is the number of input frames the resampler needs
+ size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate);
+ // to deliver this, the time stretcher requires:
+ return required * (double)speed + 1 + 1; // accounting for rounding dependencies
+}
+
#endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index e7e0703..a06197f 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -359,6 +359,21 @@ public:
/* Return current source sample rate in Hz */
uint32_t getSampleRate() const;
+ /* Set source playback rate for timestretch
+ * 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster
+ * 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch
+ *
+ * AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX
+ * AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX
+ *
+ * Speed increases the playback rate of media, but does not alter pitch.
+ * Pitch increases the "tonal frequency" of media, but does not affect the playback rate.
+ */
+ status_t setPlaybackRate(float speed, float pitch);
+
+ /* Return current playback rate */
+ void getPlaybackRate(float *speed, float *pitch) const;
+
/* Enables looping and sets the start and end points of looping.
* Only supported for static buffer mode.
*
@@ -719,6 +734,9 @@ protected:
// increment mPosition by the delta of mServer, and return new value of mPosition
uint32_t updateAndGetPosition_l();
+ // check sample rate and speed is compatible with AudioTrack
+ bool isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const;
+
// Next 4 fields may be changed if IAudioTrack is re-created, but always != 0
sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
@@ -730,6 +748,8 @@ protected:
float mVolume[2];
float mSendLevel;
mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it
+ float mSpeed; // timestretch: 1.0f for normal speed.
+ float mPitch; // timestretch: 1.0f for normal pitch.
size_t mFrameCount; // corresponds to current IAudioTrack, value is
// reported back by AudioFlinger to the client
size_t mReqFrameCount; // frame count to request the first or next time
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 5644428..6cc2e2b 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -25,6 +25,7 @@
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <audio_utils/roundup.h>
+#include <media/AudioResamplerPublic.h>
#include <media/SingleStateQueue.h>
namespace android {
@@ -113,6 +114,14 @@ struct AudioTrackSharedStatic {
mPosLoopQueue;
};
+
+struct AudioTrackPlaybackRate {
+ float mSpeed;
+ float mPitch;
+};
+
+typedef SingleStateQueue<AudioTrackPlaybackRate> AudioTrackPlaybackRateQueue;
+
// ----------------------------------------------------------------------------
// Important: do not add any virtual methods, including ~
@@ -159,6 +168,8 @@ private:
uint32_t mSampleRate; // AudioTrack only: client's requested sample rate in Hz
// or 0 == default. Write-only client, read-only server.
+ AudioTrackPlaybackRateQueue::Shared mPlaybackRateQueue;
+
// client write-only, server read-only
uint16_t mSendLevel; // Fixed point U4.12 so 0x1000 means 1.0
@@ -313,7 +324,8 @@ public:
AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool clientInServer = false)
: ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
- clientInServer) { }
+ clientInServer),
+ mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }
virtual ~AudioTrackClientProxy() { }
// No barriers on the following operations, so the ordering of loads/stores
@@ -333,6 +345,13 @@ public:
mCblk->mSampleRate = sampleRate;
}
+ void setPlaybackRate(float speed, float pitch) {
+ AudioTrackPlaybackRate playbackRate;
+ playbackRate.mSpeed = speed;
+ playbackRate.mPitch = pitch;
+ mPlaybackRateMutator.push(playbackRate);
+ }
+
virtual void flush();
virtual uint32_t getUnderrunFrames() const {
@@ -344,6 +363,9 @@ public:
bool getStreamEndDone() const;
status_t waitStreamEndDone(const struct timespec *requested);
+
+private:
+ AudioTrackPlaybackRateQueue::Mutator mPlaybackRateMutator;
};
class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
@@ -458,8 +480,11 @@ class AudioTrackServerProxy : public ServerProxy {
public:
AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
- : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) {
+ : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
+ mPlaybackRateObserver(&cblk->mPlaybackRateQueue) {
mCblk->mSampleRate = sampleRate;
+ mPlaybackRate.mSpeed = AUDIO_TIMESTRETCH_SPEED_NORMAL;
+ mPlaybackRate.mPitch = AUDIO_TIMESTRETCH_PITCH_NORMAL;
}
protected:
virtual ~AudioTrackServerProxy() { }
@@ -493,6 +518,13 @@ public:
// Return the total number of frames that AudioFlinger has obtained and released
virtual size_t framesReleased() const { return mCblk->mServer; }
+
+ // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
+ void getPlaybackRate(float *speed, float *pitch);
+
+private:
+ AudioTrackPlaybackRate mPlaybackRate; // last observed playback rate
+ AudioTrackPlaybackRateQueue::Observer mPlaybackRateObserver;
};
class StaticAudioTrackServerProxy : public AudioTrackServerProxy {