Loading include/media/AudioTrack.h +52 −23 Original line number Diff line number Diff line Loading @@ -52,8 +52,11 @@ public: * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*. */ enum event_type { EVENT_MORE_DATA = 0, // Request to write more data to PCM buffer. EVENT_UNDERRUN = 1, // PCM buffer underrun occurred. EVENT_MORE_DATA = 0, // Request to write more data to buffer. // If this event is delivered but the callback handler // does not want to write more data, the handler must explicitly // ignore the event by setting frameCount to zero. EVENT_UNDERRUN = 1, // Buffer underrun occurred. EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from // loop start if loop count was not 0. EVENT_MARKER = 3, // Playback head is at the specified marker position Loading Loading @@ -115,14 +118,16 @@ public: uint32_t sampleRate = 0); /* Constructs an uninitialized AudioTrack. No connection with * AudioFlinger takes place. * AudioFlinger takes place. Use set() after this. */ AudioTrack(); /* Creates an AudioTrack object and registers it with AudioFlinger. * Once created, the track needs to be started before it can be used. * Unspecified values are set to the audio hardware's current * values. * Unspecified values are set to appropriate default values. * With this constructor, the track is configured for streaming mode. * Data to be rendered is supplied by write() or by the callback EVENT_MORE_DATA. * Intermixing a combination of write() and non-ignored EVENT_MORE_DATA is deprecated. * * Parameters: * Loading @@ -136,10 +141,10 @@ public: * application's contribution to the * latency of the track. The actual size selected by the AudioTrack could be * larger if the requested size is not compatible with current audio HAL * latency. Zero means to use a default value. * configuration. Zero means to use a default value. * flags: See comments on audio_output_flags_t in <system/audio.h>. * cbf: Callback function. If not null, this function is called periodically * to provide new PCM data. * to provide new data and inform of marker, position updates, etc. * user: Context for use by the callback receiver. * notificationFrames: The callback function is called each time notificationFrames PCM * frames have been consumed from track input buffer. Loading @@ -159,13 +164,16 @@ public: int notificationFrames = 0, int sessionId = 0); /* Creates an audio track and registers it with AudioFlinger. With this constructor, * the PCM data to be rendered by AudioTrack is passed in a shared memory buffer * identified by the argument sharedBuffer. This prototype is for static buffer playback. * PCM data must be present in memory before the AudioTrack is started. /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. * The format must not be 8-bit linear PCM. * Data to be rendered is passed in a shared memory buffer * identified by the argument sharedBuffer, which must be non-0. * The memory should be initialized to the desired data before calling start(). * The write() method is not supported in this case. * It is recommended to pass a callback function to be notified of playback end by an * EVENT_UNDERRUN event. * FIXME EVENT_MORE_DATA still occurs; it must be ignored. */ AudioTrack( audio_stream_type_t streamType, Loading @@ -184,13 +192,14 @@ public: */ ~AudioTrack(); /* Initialize an uninitialized AudioTrack. * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful initialization * - INVALID_OPERATION: AudioTrack is already initialized * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * If sharedBuffer is non-0, the frameCount parameter is ignored and * replaced by the shared buffer's total allocated size in frame units. */ status_t set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT, uint32_t sampleRate = 0, Loading @@ -205,7 +214,6 @@ public: bool threadCanCallJava = false, int sessionId = 0); /* Result of constructing the AudioTrack. This must be checked * before using any AudioTrack API (except for set()), because using * an uninitialized AudioTrack produces undefined results. Loading @@ -224,25 +232,31 @@ public: audio_stream_type_t streamType() const { return mStreamType; } audio_format_t format() const { return mFormat; } /* Return channelCount * (bit depth per channel / 8). /* Return frame size in bytes, which for linear PCM is channelCount * (bit depth per channel / 8). * channelCount is determined from channelMask, and bit depth comes from format. * For non-linear formats, the frame size is typically 1 byte. */ uint32_t channelCount() const { return mChannelCount; } uint32_t frameCount() const { return mFrameCount; } size_t frameSize() const { return mFrameSize; } /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */ sp<IMemory> sharedBuffer() const { return mSharedBuffer; } /* After it's created the track is not active. Call start() to * make it active. If set, the callback will start being called. * If the track was previously paused, volume is ramped up over the first mix buffer. */ void start(); /* Stop a track. If set, the callback will cease being called and /* Stop a track. * In static buffer mode, the track is stopped immediately. * In streaming mode, the callback will cease being called and * obtainBuffer returns STOPPED. Note that obtainBuffer() still works * and will fill up buffers until the pool is exhausted. * The stop does not occur immediately: any data remaining in the buffer * is first drained, mixed, and output, and only then is the track marked as stopped. */ void stop(); bool stopped() const; Loading @@ -254,9 +268,11 @@ public: */ void flush(); /* Pause a track. If set, the callback will cease being called and /* Pause a track. After pause, the callback will cease being called and * obtainBuffer returns STOPPED. Note that obtainBuffer() still works * and will fill up buffers until the pool is exhausted. * Volume is ramped down over the next mix buffer following the pause request, * and then the track is marked as paused. It can be resumed with ramp up by start(). */ void pause(); Loading Loading @@ -285,6 +301,7 @@ public: uint32_t getSampleRate() const; /* Enables looping and sets the start and end points of looping. * Only supported for static buffer mode. * * Parameters: * Loading @@ -300,13 +317,15 @@ public: /* Sets marker position. When playback reaches the number of frames specified, a callback with * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker * notification callback. * notification callback. To set a marker at a position which would compute as 0, * a workaround is to the set the marker at a nearby position such as -1 or 1. * If the AudioTrack has been opened with no callback function associated, the operation will * fail. * * Parameters: * * marker: marker position expressed in frames. * marker: marker position expressed in wrapping (overflow) frame units, * like the return value of getPosition(). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation Loading @@ -315,13 +334,13 @@ public: status_t setMarkerPosition(uint32_t marker); status_t getMarkerPosition(uint32_t *marker) const; /* Sets position update period. Every time the number of frames specified has been played, * a callback with event type EVENT_NEW_POS is called. * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification * callback. * If the AudioTrack has been opened with no callback function associated, the operation will * fail. * Extremely small values may be rounded up to a value the implementation can support. * * Parameters: * Loading Loading @@ -349,20 +368,26 @@ public: * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation * - INVALID_OPERATION: the AudioTrack is not stopped. * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack * buffer */ status_t setPosition(uint32_t position); /* Return the total number of frames played since playback start. * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz. * It is reset to zero by flush(), reload(), and stop(). */ status_t getPosition(uint32_t *position); /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids * rewriting the buffer before restarting playback after a stop. * This method must be called with the AudioTrack in paused or stopped state. * Not allowed in streaming mode. * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation * - INVALID_OPERATION: the AudioTrack is not stopped. * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. */ status_t reload(); Loading Loading @@ -410,6 +435,9 @@ public: * or return WOULD_BLOCK depending on the value of the "blocking" * parameter. * * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications, * which should use write() or callback EVENT_MORE_DATA instead. * * Interpretation of waitCount: * +n limits wait time to n * WAIT_PERIOD_MS, * -1 causes an (almost) infinite wait time, Loading Loading @@ -447,6 +475,7 @@ public: * STOPPED AudioTrack was stopped during the write * NO_MORE_BUFFERS when obtainBuffer() returns same * or any other error code returned by IAudioTrack::start() or restoreTrack_l(). * Not supported for static buffer mode. */ ssize_t write(const void* buffer, size_t size); Loading Loading @@ -548,7 +577,7 @@ protected: sp<IMemory> mSharedBuffer; int mLoopCount; uint32_t mRemainingFrames; uint32_t mMarkerPosition; // in frames uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; uint32_t mNewPosition; // in frames uint32_t mUpdatePeriod; // in frames Loading media/libmedia/AudioTrack.cpp +15 −9 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ AudioTrack::AudioTrack( mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) { if (sharedBuffer == 0) { ALOGE("sharedBuffer must be non-0"); mStatus = BAD_VALUE; return; } mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId); Loading Loading @@ -535,6 +540,10 @@ status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount // must be called with mLock held status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } audio_track_cblk_t* cblk = mCblk; Mutex::Autolock _l(cblk->lock); Loading @@ -547,10 +556,6 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou return NO_ERROR; } if (mIsTimed) { return INVALID_OPERATION; } if (loopStart >= loopEnd || loopEnd - loopStart > mFrameCount || cblk->server > loopStart) { Loading Loading @@ -624,7 +629,7 @@ status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const status_t AudioTrack::setPosition(uint32_t position) { if (mIsTimed) { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } Loading Loading @@ -660,6 +665,10 @@ status_t AudioTrack::getPosition(uint32_t *position) status_t AudioTrack::reload() { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } AutoMutex lock(mLock); if (!stopped_l()) { Loading Loading @@ -1036,10 +1045,7 @@ void AudioTrack::releaseBuffer(Buffer* audioBuffer) ssize_t AudioTrack::write(const void* buffer, size_t userSize) { if (mSharedBuffer != 0) { return INVALID_OPERATION; } if (mIsTimed) { if (mSharedBuffer != 0 || mIsTimed) { return INVALID_OPERATION; } Loading Loading
include/media/AudioTrack.h +52 −23 Original line number Diff line number Diff line Loading @@ -52,8 +52,11 @@ public: * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*. */ enum event_type { EVENT_MORE_DATA = 0, // Request to write more data to PCM buffer. EVENT_UNDERRUN = 1, // PCM buffer underrun occurred. EVENT_MORE_DATA = 0, // Request to write more data to buffer. // If this event is delivered but the callback handler // does not want to write more data, the handler must explicitly // ignore the event by setting frameCount to zero. EVENT_UNDERRUN = 1, // Buffer underrun occurred. EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from // loop start if loop count was not 0. EVENT_MARKER = 3, // Playback head is at the specified marker position Loading Loading @@ -115,14 +118,16 @@ public: uint32_t sampleRate = 0); /* Constructs an uninitialized AudioTrack. No connection with * AudioFlinger takes place. * AudioFlinger takes place. Use set() after this. */ AudioTrack(); /* Creates an AudioTrack object and registers it with AudioFlinger. * Once created, the track needs to be started before it can be used. * Unspecified values are set to the audio hardware's current * values. * Unspecified values are set to appropriate default values. * With this constructor, the track is configured for streaming mode. * Data to be rendered is supplied by write() or by the callback EVENT_MORE_DATA. * Intermixing a combination of write() and non-ignored EVENT_MORE_DATA is deprecated. * * Parameters: * Loading @@ -136,10 +141,10 @@ public: * application's contribution to the * latency of the track. The actual size selected by the AudioTrack could be * larger if the requested size is not compatible with current audio HAL * latency. Zero means to use a default value. * configuration. Zero means to use a default value. * flags: See comments on audio_output_flags_t in <system/audio.h>. * cbf: Callback function. If not null, this function is called periodically * to provide new PCM data. * to provide new data and inform of marker, position updates, etc. * user: Context for use by the callback receiver. * notificationFrames: The callback function is called each time notificationFrames PCM * frames have been consumed from track input buffer. Loading @@ -159,13 +164,16 @@ public: int notificationFrames = 0, int sessionId = 0); /* Creates an audio track and registers it with AudioFlinger. With this constructor, * the PCM data to be rendered by AudioTrack is passed in a shared memory buffer * identified by the argument sharedBuffer. This prototype is for static buffer playback. * PCM data must be present in memory before the AudioTrack is started. /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. * The format must not be 8-bit linear PCM. * Data to be rendered is passed in a shared memory buffer * identified by the argument sharedBuffer, which must be non-0. * The memory should be initialized to the desired data before calling start(). * The write() method is not supported in this case. * It is recommended to pass a callback function to be notified of playback end by an * EVENT_UNDERRUN event. * FIXME EVENT_MORE_DATA still occurs; it must be ignored. */ AudioTrack( audio_stream_type_t streamType, Loading @@ -184,13 +192,14 @@ public: */ ~AudioTrack(); /* Initialize an uninitialized AudioTrack. * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful initialization * - INVALID_OPERATION: AudioTrack is already initialized * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * If sharedBuffer is non-0, the frameCount parameter is ignored and * replaced by the shared buffer's total allocated size in frame units. */ status_t set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT, uint32_t sampleRate = 0, Loading @@ -205,7 +214,6 @@ public: bool threadCanCallJava = false, int sessionId = 0); /* Result of constructing the AudioTrack. This must be checked * before using any AudioTrack API (except for set()), because using * an uninitialized AudioTrack produces undefined results. Loading @@ -224,25 +232,31 @@ public: audio_stream_type_t streamType() const { return mStreamType; } audio_format_t format() const { return mFormat; } /* Return channelCount * (bit depth per channel / 8). /* Return frame size in bytes, which for linear PCM is channelCount * (bit depth per channel / 8). * channelCount is determined from channelMask, and bit depth comes from format. * For non-linear formats, the frame size is typically 1 byte. */ uint32_t channelCount() const { return mChannelCount; } uint32_t frameCount() const { return mFrameCount; } size_t frameSize() const { return mFrameSize; } /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */ sp<IMemory> sharedBuffer() const { return mSharedBuffer; } /* After it's created the track is not active. Call start() to * make it active. If set, the callback will start being called. * If the track was previously paused, volume is ramped up over the first mix buffer. */ void start(); /* Stop a track. If set, the callback will cease being called and /* Stop a track. * In static buffer mode, the track is stopped immediately. * In streaming mode, the callback will cease being called and * obtainBuffer returns STOPPED. Note that obtainBuffer() still works * and will fill up buffers until the pool is exhausted. * The stop does not occur immediately: any data remaining in the buffer * is first drained, mixed, and output, and only then is the track marked as stopped. */ void stop(); bool stopped() const; Loading @@ -254,9 +268,11 @@ public: */ void flush(); /* Pause a track. If set, the callback will cease being called and /* Pause a track. After pause, the callback will cease being called and * obtainBuffer returns STOPPED. Note that obtainBuffer() still works * and will fill up buffers until the pool is exhausted. * Volume is ramped down over the next mix buffer following the pause request, * and then the track is marked as paused. It can be resumed with ramp up by start(). */ void pause(); Loading Loading @@ -285,6 +301,7 @@ public: uint32_t getSampleRate() const; /* Enables looping and sets the start and end points of looping. * Only supported for static buffer mode. * * Parameters: * Loading @@ -300,13 +317,15 @@ public: /* Sets marker position. When playback reaches the number of frames specified, a callback with * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker * notification callback. * notification callback. To set a marker at a position which would compute as 0, * a workaround is to the set the marker at a nearby position such as -1 or 1. * If the AudioTrack has been opened with no callback function associated, the operation will * fail. * * Parameters: * * marker: marker position expressed in frames. * marker: marker position expressed in wrapping (overflow) frame units, * like the return value of getPosition(). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation Loading @@ -315,13 +334,13 @@ public: status_t setMarkerPosition(uint32_t marker); status_t getMarkerPosition(uint32_t *marker) const; /* Sets position update period. Every time the number of frames specified has been played, * a callback with event type EVENT_NEW_POS is called. * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification * callback. * If the AudioTrack has been opened with no callback function associated, the operation will * fail. * Extremely small values may be rounded up to a value the implementation can support. * * Parameters: * Loading Loading @@ -349,20 +368,26 @@ public: * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation * - INVALID_OPERATION: the AudioTrack is not stopped. * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack * buffer */ status_t setPosition(uint32_t position); /* Return the total number of frames played since playback start. * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz. * It is reset to zero by flush(), reload(), and stop(). */ status_t getPosition(uint32_t *position); /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids * rewriting the buffer before restarting playback after a stop. * This method must be called with the AudioTrack in paused or stopped state. * Not allowed in streaming mode. * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation * - INVALID_OPERATION: the AudioTrack is not stopped. * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode. */ status_t reload(); Loading Loading @@ -410,6 +435,9 @@ public: * or return WOULD_BLOCK depending on the value of the "blocking" * parameter. * * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications, * which should use write() or callback EVENT_MORE_DATA instead. * * Interpretation of waitCount: * +n limits wait time to n * WAIT_PERIOD_MS, * -1 causes an (almost) infinite wait time, Loading Loading @@ -447,6 +475,7 @@ public: * STOPPED AudioTrack was stopped during the write * NO_MORE_BUFFERS when obtainBuffer() returns same * or any other error code returned by IAudioTrack::start() or restoreTrack_l(). * Not supported for static buffer mode. */ ssize_t write(const void* buffer, size_t size); Loading Loading @@ -548,7 +577,7 @@ protected: sp<IMemory> mSharedBuffer; int mLoopCount; uint32_t mRemainingFrames; uint32_t mMarkerPosition; // in frames uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; uint32_t mNewPosition; // in frames uint32_t mUpdatePeriod; // in frames Loading
media/libmedia/AudioTrack.cpp +15 −9 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ AudioTrack::AudioTrack( mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) { if (sharedBuffer == 0) { ALOGE("sharedBuffer must be non-0"); mStatus = BAD_VALUE; return; } mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, sharedBuffer, false /*threadCanCallJava*/, sessionId); Loading Loading @@ -535,6 +540,10 @@ status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount // must be called with mLock held status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } audio_track_cblk_t* cblk = mCblk; Mutex::Autolock _l(cblk->lock); Loading @@ -547,10 +556,6 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou return NO_ERROR; } if (mIsTimed) { return INVALID_OPERATION; } if (loopStart >= loopEnd || loopEnd - loopStart > mFrameCount || cblk->server > loopStart) { Loading Loading @@ -624,7 +629,7 @@ status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const status_t AudioTrack::setPosition(uint32_t position) { if (mIsTimed) { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } Loading Loading @@ -660,6 +665,10 @@ status_t AudioTrack::getPosition(uint32_t *position) status_t AudioTrack::reload() { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } AutoMutex lock(mLock); if (!stopped_l()) { Loading Loading @@ -1036,10 +1045,7 @@ void AudioTrack::releaseBuffer(Buffer* audioBuffer) ssize_t AudioTrack::write(const void* buffer, size_t userSize) { if (mSharedBuffer != 0) { return INVALID_OPERATION; } if (mIsTimed) { if (mSharedBuffer != 0 || mIsTimed) { return INVALID_OPERATION; } Loading