diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2011-05-24 15:53:33 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2011-06-01 10:55:29 -0700 |
commit | 0d255b2d9061ba31f13ada3fc0f7e51916407176 (patch) | |
tree | 4df26e48710542386bddab7a0d1cbfa5d6835ac0 | |
parent | 65580f9adf6c4d98449ad0716488f9fe3869aa5a (diff) | |
download | frameworks_av-0d255b2d9061ba31f13ada3fc0f7e51916407176.zip frameworks_av-0d255b2d9061ba31f13ada3fc0f7e51916407176.tar.gz frameworks_av-0d255b2d9061ba31f13ada3fc0f7e51916407176.tar.bz2 |
Use channel mask instead of channel count for track creation
Record and playback objects (resp AudioRecord and AudioTrack)
are created using a channel mask, but this information is lost
in the mixer because only the channel count is known to
AudioFlinger. A channel count can always be derived from a
channel mask.
The change consists in:
- disambiguiting variable names for channel masks and counts
- passing the mask information from the client to AudioFlinger
and the mixer.
- when using the DIRECT ouput, only verifying the format of
the track is compatible with the output's for PCM.
Change-Id: I50d87bfb7d7afcabdf5f12d4ab75ef3a54132c0e
-rw-r--r-- | include/media/AudioRecord.h | 16 | ||||
-rw-r--r-- | include/media/AudioTrack.h | 19 | ||||
-rw-r--r-- | include/media/IAudioFlinger.h | 10 | ||||
-rw-r--r-- | include/private/media/AudioTrackShared.h | 3 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 28 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 39 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 14 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 2 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 120 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 44 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 20 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.h | 3 |
12 files changed, 175 insertions, 143 deletions
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index baab2e8..605680a 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -130,7 +130,7 @@ public: * sampleRate: Track sampling rate in Hz. * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed * 16 bits per sample). - * channels: Channel mask: see audio_channels_t. + * channelMask: Channel mask: see audio_channels_t. * frameCount: Total size of track PCM buffer in frames. This defines the * latency of the track. * flags: A bitmask of acoustic values from enum record_flags. It enables @@ -151,7 +151,7 @@ public: AudioRecord(int inputSource, uint32_t sampleRate = 0, int format = 0, - uint32_t channels = AUDIO_CHANNEL_IN_MONO, + uint32_t channelMask = AUDIO_CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -177,7 +177,7 @@ public: status_t set(int inputSource = 0, uint32_t sampleRate = 0, int format = 0, - uint32_t channels = AUDIO_CHANNEL_IN_MONO, + uint32_t channelMask = AUDIO_CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -348,8 +348,8 @@ private: bool processAudioBuffer(const sp<ClientRecordThread>& thread); status_t openRecord_l(uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, audio_io_handle_t input); @@ -364,10 +364,10 @@ private: uint32_t mFrameCount; audio_track_cblk_t* mCblk; - uint8_t mFormat; + uint32_t mFormat; uint8_t mChannelCount; uint8_t mInputSource; - uint8_t mReserved; + uint8_t mReserved[2]; status_t mStatus; uint32_t mLatency; @@ -382,7 +382,7 @@ private: uint32_t mNewPosition; uint32_t mUpdatePeriod; uint32_t mFlags; - uint32_t mChannels; + uint32_t mChannelMask; audio_io_handle_t mInput; int mSessionId; }; diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index de928da..df30e8c 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -69,8 +69,8 @@ public: MUTE = 0x00000001 }; uint32_t flags; - int channelCount; int format; + int channelCount; // will be removed in the future, do not use size_t frameCount; size_t size; union { @@ -129,7 +129,7 @@ public: * sampleRate: Track sampling rate in Hz. * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed * 16 bits per sample). - * channels: Channel mask: see audio_channels_t. + * channelMask: Channel mask: see audio_channels_t. * frameCount: Total size of track PCM buffer in frames. This defines the * latency of the track. * flags: Reserved for future use. @@ -143,7 +143,7 @@ public: AudioTrack( int streamType, uint32_t sampleRate = 0, int format = 0, - int channels = 0, + int channelMask = 0, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -163,7 +163,7 @@ public: AudioTrack( int streamType, uint32_t sampleRate = 0, int format = 0, - int channels = 0, + int channelMask = 0, const sp<IMemory>& sharedBuffer = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -187,7 +187,7 @@ public: status_t set(int streamType =-1, uint32_t sampleRate = 0, int format = 0, - int channels = 0, + int channelMask = 0, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -438,8 +438,8 @@ private: bool processAudioBuffer(const sp<AudioTrackThread>& thread); status_t createTrack_l(int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -459,11 +459,12 @@ private: uint32_t mFrameCount; audio_track_cblk_t* mCblk; + uint32_t mFormat; uint8_t mStreamType; - uint8_t mFormat; uint8_t mChannelCount; uint8_t mMuted; - uint32_t mChannels; + uint8_t mReserved; + uint32_t mChannelMask; status_t mStatus; uint32_t mLatency; diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index d8fdc27..4037c46 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -48,8 +48,8 @@ public: pid_t pid, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -61,8 +61,8 @@ public: pid_t pid, int input, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int *sessionId, @@ -73,7 +73,7 @@ public: */ virtual uint32_t sampleRate(int output) const = 0; virtual int channelCount(int output) const = 0; - virtual int format(int output) const = 0; + virtual uint32_t format(int output) const = 0; virtual size_t frameCount(int output) const = 0; virtual uint32_t latency(int output) const = 0; diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 1827c3e..072329d 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -82,7 +82,7 @@ struct audio_track_cblk_t // 16 bit because data is converted to 16 bit before being stored in buffer uint8_t frameSize; - uint8_t channelCount; + uint8_t pad1; uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger uint16_t waitTimeMs; // Cumulated wait time @@ -90,6 +90,7 @@ struct audio_track_cblk_t volatile int32_t flags; // Cache line boundary (32 bytes) + audio_track_cblk_t(); uint32_t stepUser(uint32_t frameCount); bool stepServer(uint32_t frameCount); diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 446e3df..f6c4cc7 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -88,7 +88,7 @@ AudioRecord::AudioRecord( int inputSource, uint32_t sampleRate, int format, - uint32_t channels, + uint32_t channelMask, int frameCount, uint32_t flags, callback_t cbf, @@ -97,7 +97,7 @@ AudioRecord::AudioRecord( int sessionId) : mStatus(NO_INIT), mSessionId(0) { - mStatus = set(inputSource, sampleRate, format, channels, + mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, sessionId); } @@ -121,7 +121,7 @@ status_t AudioRecord::set( int inputSource, uint32_t sampleRate, int format, - uint32_t channels, + uint32_t channelMask, int frameCount, uint32_t flags, callback_t cbf, @@ -131,7 +131,7 @@ status_t AudioRecord::set( int sessionId) { - LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount); + LOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount); AutoMutex lock(mLock); @@ -156,14 +156,14 @@ status_t AudioRecord::set( return BAD_VALUE; } - if (!audio_is_input_channel(channels)) { + if (!audio_is_input_channel(channelMask)) { return BAD_VALUE; } - int channelCount = popcount(channels); + int channelCount = popcount(channelMask); audio_io_handle_t input = AudioSystem::getInput(inputSource, - sampleRate, format, channels, (audio_in_acoustics_t)flags); + sampleRate, format, channelMask, (audio_in_acoustics_t)flags); if (input == 0) { LOGE("Could not get audio input for record source %d", inputSource); return BAD_VALUE; @@ -190,7 +190,7 @@ status_t AudioRecord::set( mSessionId = sessionId; // create the IAudioRecord - status = openRecord_l(sampleRate, format, channelCount, + status = openRecord_l(sampleRate, format, channelMask, frameCount, flags, input); if (status != NO_ERROR) { return status; @@ -209,7 +209,7 @@ status_t AudioRecord::set( // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk->frameCount; mChannelCount = (uint8_t)channelCount; - mChannels = channels; + mChannelMask = channelMask; mActive = 0; mCbf = cbf; mNotificationFrames = notificationFrames; @@ -437,8 +437,8 @@ unsigned int AudioRecord::getInputFramesLost() // must be called with mLock held status_t AudioRecord::openRecord_l( uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, audio_io_handle_t input) @@ -451,7 +451,7 @@ status_t AudioRecord::openRecord_l( sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, sampleRate, format, - channelCount, + channelMask, frameCount, ((uint16_t)flags) << 16, &mSessionId, @@ -589,7 +589,7 @@ audio_io_handle_t AudioRecord::getInput_l() { mInput = AudioSystem::getInput(mInputSource, mCblk->sampleRate, - mFormat, mChannels, + mFormat, mChannelMask, (audio_in_acoustics_t)mFlags); return mInput; } @@ -756,7 +756,7 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) // if the new IAudioRecord is created, openRecord_l() will modify the // following member variables: mAudioRecord, mCblkMemory and mCblk. // It will also delete the strong references on previous IAudioRecord and IMemory - result = openRecord_l(cblk->sampleRate, mFormat, mChannelCount, + result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, mFrameCount, mFlags, getInput_l()); if (result == NO_ERROR) { result = mAudioRecord->start(); diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 7520ed9..ea44f87 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -87,7 +87,7 @@ AudioTrack::AudioTrack( int streamType, uint32_t sampleRate, int format, - int channels, + int channelMask, int frameCount, uint32_t flags, callback_t cbf, @@ -96,7 +96,7 @@ AudioTrack::AudioTrack( int sessionId) : mStatus(NO_INIT) { - mStatus = set(streamType, sampleRate, format, channels, + mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0, false, sessionId); } @@ -105,7 +105,7 @@ AudioTrack::AudioTrack( int streamType, uint32_t sampleRate, int format, - int channels, + int channelMask, const sp<IMemory>& sharedBuffer, uint32_t flags, callback_t cbf, @@ -114,7 +114,7 @@ AudioTrack::AudioTrack( int sessionId) : mStatus(NO_INIT) { - mStatus = set(streamType, sampleRate, format, channels, + mStatus = set(streamType, sampleRate, format, channelMask, 0, flags, cbf, user, notificationFrames, sharedBuffer, false, sessionId); } @@ -141,7 +141,7 @@ status_t AudioTrack::set( int streamType, uint32_t sampleRate, int format, - int channels, + int channelMask, int frameCount, uint32_t flags, callback_t cbf, @@ -180,8 +180,8 @@ status_t AudioTrack::set( if (format == 0) { format = AUDIO_FORMAT_PCM_16_BIT; } - if (channels == 0) { - channels = AUDIO_CHANNEL_OUT_STEREO; + if (channelMask == 0) { + channelMask = AUDIO_CHANNEL_OUT_STEREO; } // validate parameters @@ -195,15 +195,15 @@ status_t AudioTrack::set( flags |= AUDIO_POLICY_OUTPUT_FLAG_DIRECT; } - if (!audio_is_output_channel(channels)) { + if (!audio_is_output_channel(channelMask)) { LOGE("Invalid channel mask"); return BAD_VALUE; } - uint32_t channelCount = popcount(channels); + uint32_t channelCount = popcount(channelMask); audio_io_handle_t output = AudioSystem::getOutput( (audio_stream_type_t)streamType, - sampleRate,format, channels, + sampleRate,format, channelMask, (audio_policy_output_flags_t)flags); if (output == 0) { @@ -222,8 +222,8 @@ status_t AudioTrack::set( // create the IAudioTrack status_t status = createTrack_l(streamType, sampleRate, - format, - channelCount, + (uint32_t)format, + (uint32_t)channelMask, frameCount, flags, sharedBuffer, @@ -245,8 +245,8 @@ status_t AudioTrack::set( mStatus = NO_ERROR; mStreamType = streamType; - mFormat = format; - mChannels = channels; + mFormat = (uint32_t)format; + mChannelMask = (uint32_t)channelMask; mChannelCount = channelCount; mSharedBuffer = sharedBuffer; mMuted = false; @@ -681,7 +681,7 @@ audio_io_handle_t AudioTrack::getOutput() audio_io_handle_t AudioTrack::getOutput_l() { return AudioSystem::getOutput((audio_stream_type_t)mStreamType, - mCblk->sampleRate, mFormat, mChannels, (audio_policy_output_flags_t)mFlags); + mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags); } int AudioTrack::getSessionId() @@ -705,8 +705,8 @@ status_t AudioTrack::attachAuxEffect(int effectId) status_t AudioTrack::createTrack_l( int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -767,6 +767,7 @@ status_t AudioTrack::createTrack_l( } } else { // Ensure that buffer alignment matches channelcount + int channelCount = popcount(channelMask); if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); return BAD_VALUE; @@ -779,7 +780,7 @@ status_t AudioTrack::createTrack_l( streamType, sampleRate, format, - channelCount, + channelMask, frameCount, ((uint16_t)flags) << 16, sharedBuffer, @@ -1164,7 +1165,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) result = createTrack_l(mStreamType, cblk->sampleRate, mFormat, - mChannelCount, + mChannelMask, mFrameCount, mFlags, mSharedBuffer, diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 158d2f5..4a12962 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -82,8 +82,8 @@ public: pid_t pid, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -98,7 +98,7 @@ public: data.writeInt32(streamType); data.writeInt32(sampleRate); data.writeInt32(format); - data.writeInt32(channelCount); + data.writeInt32(channelMask); data.writeInt32(frameCount); data.writeInt32(flags); data.writeStrongBinder(sharedBuffer->asBinder()); @@ -129,8 +129,8 @@ public: pid_t pid, int input, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int *sessionId, @@ -143,7 +143,7 @@ public: data.writeInt32(input); data.writeInt32(sampleRate); data.writeInt32(format); - data.writeInt32(channelCount); + data.writeInt32(channelMask); data.writeInt32(frameCount); data.writeInt32(flags); int lSessionId = 0; @@ -186,7 +186,7 @@ public: return reply.readInt32(); } - virtual int format(int output) const + virtual uint32_t format(int output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index d51c946..eae93ff 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1164,7 +1164,7 @@ sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, i mem = new MemoryBase(cache->getHeap(), 0, cache->size()); *pSampleRate = cache->sampleRate(); *pNumChannels = cache->channelCount(); - *pFormat = cache->format(); + *pFormat = (int)cache->format(); LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); Exit: diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 053854f..f806624 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -360,8 +360,8 @@ sp<IAudioTrack> AudioFlinger::createTrack( pid_t pid, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -429,7 +429,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( LOGV("createTrack() lSessionId: %d", lSessionId); track = thread->createTrack_l(client, streamType, sampleRate, format, - channelCount, frameCount, sharedBuffer, lSessionId, &lStatus); + channelMask, frameCount, sharedBuffer, lSessionId, &lStatus); // move effect chain to this output thread if an effect on same session was waiting // for a track to be created @@ -477,7 +477,7 @@ int AudioFlinger::channelCount(int output) const return thread->channelCount(); } -int AudioFlinger::format(int output) const +uint32_t AudioFlinger::format(int output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -916,7 +916,7 @@ int AudioFlinger::ThreadBase::channelCount() const return (int)mChannelCount; } -int AudioFlinger::ThreadBase::format() const +uint32_t AudioFlinger::ThreadBase::format() const { return mFormat; } @@ -1002,6 +1002,8 @@ status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args result.append(buffer); snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount); result.append(buffer); + snprintf(buffer, SIZE, "Channel Mask: 0x%08x\n", mChannelMask); + result.append(buffer); snprintf(buffer, SIZE, "Format: %d\n", mFormat); result.append(buffer); snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize); @@ -1075,7 +1077,7 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> snprintf(buffer, SIZE, "Output thread %p tracks\n", this); result.append(buffer); - result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); + result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> track = mTracks[i]; if (track != 0) { @@ -1086,7 +1088,7 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> snprintf(buffer, SIZE, "Output thread %p active tracks\n", this); result.append(buffer); - result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); + result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); for (size_t i = 0; i < mActiveTracks.size(); ++i) { wp<Track> wTrack = mActiveTracks[i]; if (wTrack != 0) { @@ -1172,8 +1174,8 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra const sp<AudioFlinger::Client>& client, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, int sessionId, @@ -1183,11 +1185,14 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra status_t lStatus; if (mType == DIRECT) { - if (sampleRate != mSampleRate || format != mFormat || channelCount != (int)mChannelCount) { - LOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelCount %d for output %p", - sampleRate, format, channelCount, mOutput); - lStatus = BAD_VALUE; - goto Exit; + if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) { + if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) { + LOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x \"" + "for output %p with format %d", + sampleRate, format, channelMask, mOutput, mFormat); + lStatus = BAD_VALUE; + goto Exit; + } } } else { // Resampler implementation limits input sampling rate to 2 x output sampling rate. @@ -1224,7 +1229,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra } track = new Track(this, client, streamType, sampleRate, format, - channelCount, frameCount, sharedBuffer, sessionId); + channelMask, frameCount, sharedBuffer, sessionId); if (track->getCblk() == NULL || track->name() < 0) { lStatus = NO_MEMORY; goto Exit; @@ -1373,7 +1378,7 @@ void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) { switch (event) { case AudioSystem::OUTPUT_OPENED: case AudioSystem::OUTPUT_CONFIG_CHANGED: - desc.channels = mChannels; + desc.channels = mChannelMask; desc.samplingRate = mSampleRate; desc.format = mFormat; desc.frameCount = mFrameCount; @@ -1393,8 +1398,8 @@ void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) { void AudioFlinger::PlaybackThread::readOutputParameters() { mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common); - mChannels = mOutput->stream->common.get_channels(&mOutput->stream->common); - mChannelCount = (uint16_t)popcount(mChannels); + mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common); + mChannelCount = (uint16_t)popcount(mChannelMask); mFormat = mOutput->stream->common.get_format(&mOutput->stream->common); mFrameSize = (uint16_t)audio_stream_frame_size(&mOutput->stream->common); mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize; @@ -1804,7 +1809,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track AudioMixer::FORMAT, (void *)track->format()); mAudioMixer->setParameter( AudioMixer::TRACK, - AudioMixer::CHANNEL_COUNT, (void *)track->channelCount()); + AudioMixer::CHANNEL_MASK, (void *)track->channelMask()); mAudioMixer->setParameter( AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE, @@ -2683,7 +2688,7 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) this, mSampleRate, mFormat, - mChannelCount, + mChannelMask, frameCount); if (outputTrack->cblk() != NULL) { thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f); @@ -2751,8 +2756,8 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -2772,6 +2777,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize); size_t size = sizeof(audio_track_cblk_t); + uint8_t channelCount = popcount(channelMask); size_t bufferSize = frameCount*channelCount*sizeof(int16_t); if (sharedBuffer == 0) { size += bufferSize; @@ -2786,7 +2792,8 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // clear all buffers mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; - mCblk->channelCount = (uint8_t)channelCount; + mChannelCount = channelCount; + mChannelMask = channelMask; if (sharedBuffer == 0) { mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t)); @@ -2810,7 +2817,8 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // clear all buffers mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; - mCblk->channelCount = (uint8_t)channelCount; + mChannelCount = channelCount; + mChannelMask = channelMask; mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t)); // Force underrun condition to avoid false underrun callback until first data is @@ -2877,7 +2885,11 @@ int AudioFlinger::ThreadBase::TrackBase::sampleRate() const { } int AudioFlinger::ThreadBase::TrackBase::channelCount() const { - return (int)mCblk->channelCount; + return (const int)mChannelCount; +} + +uint32_t AudioFlinger::ThreadBase::TrackBase::channelMask() const { + return mChannelMask; } void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const { @@ -2889,9 +2901,9 @@ void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t f if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd || ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) { LOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \ - server %d, serverBase %d, user %d, userBase %d, channelCount %d", + server %d, serverBase %d, user %d, userBase %d", bufferStart, bufferEnd, mBuffer, mBufferEnd, - cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channelCount); + cblk->server, cblk->serverBase, cblk->user, cblk->userBase); return 0; } @@ -2906,12 +2918,12 @@ AudioFlinger::PlaybackThread::Track::Track( const sp<Client>& client, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, int sessionId) - : TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId), + : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, 0, sharedBuffer, sessionId), mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL), mAuxEffectId(0), mHasVolumeController(false) { @@ -2931,7 +2943,7 @@ AudioFlinger::PlaybackThread::Track::Track( mStreamType = streamType; // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack - mCblk->frameSize = audio_is_linear_pcm(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t); + mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * sizeof(int16_t) : sizeof(int8_t); } } @@ -2979,12 +2991,12 @@ void AudioFlinger::PlaybackThread::Track::destroy() void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) { - snprintf(buffer, size, " %05d %05d %03u %03u %03u %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n", + snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n", mName - AudioMixer::TRACK0, (mClient == NULL) ? getpid() : mClient->pid(), mStreamType, mFormat, - mCblk->channelCount, + mChannelMask, mSessionId, mFrameCount, mState, @@ -3219,21 +3231,21 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int sessionId) : TrackBase(thread, client, sampleRate, format, - channelCount, frameCount, flags, 0, sessionId), + channelMask, frameCount, flags, 0, sessionId), mOverflow(false) { if (mCblk != NULL) { LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer); if (format == AUDIO_FORMAT_PCM_16_BIT) { - mCblk->frameSize = channelCount * sizeof(int16_t); + mCblk->frameSize = mChannelCount * sizeof(int16_t); } else if (format == AUDIO_FORMAT_PCM_8_BIT) { - mCblk->frameSize = channelCount * sizeof(int8_t); + mCblk->frameSize = mChannelCount * sizeof(int8_t); } else { mCblk->frameSize = sizeof(int8_t); } @@ -3313,10 +3325,10 @@ void AudioFlinger::RecordThread::RecordTrack::stop() void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size) { - snprintf(buffer, size, " %05d %03u %03u %05d %04u %01d %05u %08x %08x\n", + snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x\n", (mClient == NULL) ? getpid() : mClient->pid(), mFormat, - mCblk->channelCount, + mChannelMask, mSessionId, mFrameCount, mState, @@ -3332,10 +3344,10 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( const wp<ThreadBase>& thread, DuplicatingThread *sourceThread, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount) - : Track(thread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelCount, frameCount, NULL, 0), + : Track(thread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, NULL, 0), mActive(false), mSourceThread(sourceThread) { @@ -3346,8 +3358,10 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( mCblk->volume[0] = mCblk->volume[1] = 0x1000; mOutBuffer.frameCount = 0; playbackThread->mTracks.add(this); - LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channelCount %d mBufferEnd %p", - mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channelCount, mBufferEnd); + LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \ + "mCblk->frameCount %d, mCblk->sampleRate %d, mChannelMask 0x%08x mBufferEnd %p", + mCblk, mBuffer, mCblk->buffers, + mCblk->frameCount, mCblk->sampleRate, mChannelMask, mBufferEnd); } else { LOGW("Error creating output track on thread %p", playbackThread); } @@ -3382,7 +3396,7 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr { Buffer *pInBuffer; Buffer inBuffer; - uint32_t channelCount = mCblk->channelCount; + uint32_t channelCount = mChannelCount; bool outputBufferFull = false; inBuffer.frameCount = frames; inBuffer.i16 = data; @@ -3667,8 +3681,8 @@ sp<IAudioRecord> AudioFlinger::openRecord( pid_t pid, int input, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int *sessionId, @@ -3717,7 +3731,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( } // create new record track. The record track uses one track in mHardwareMixerThread by convention. recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate, - format, channelCount, frameCount, flags, lSessionId); + format, channelMask, frameCount, flags, lSessionId); } if (recordTrack->getCblk() == NULL) { // remove local strong reference to Client before deleting the RecordTrack so that the Client @@ -4065,7 +4079,7 @@ status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) if (mActiveTrack != 0) { result.append("Active Track:\n"); - result.append(" Clien Fmt Chn Session Buf S SRate Serv User\n"); + result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User\n"); mActiveTrack->dump(buffer, SIZE); result.append(buffer); @@ -4219,7 +4233,7 @@ void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) { switch (event) { case AudioSystem::INPUT_OPENED: case AudioSystem::INPUT_CONFIG_CHANGED: - desc.channels = mChannels; + desc.channels = mChannelMask; desc.samplingRate = mSampleRate; desc.format = mFormat; desc.frameCount = mFrameCount; @@ -4242,8 +4256,8 @@ void AudioFlinger::RecordThread::readInputParameters() mResampler = 0; mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common); - mChannels = mInput->stream->common.get_channels(&mInput->stream->common); - mChannelCount = (uint16_t)popcount(mChannels); + mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common); + mChannelCount = (uint16_t)popcount(mChannelMask); mFormat = mInput->stream->common.get_format(&mInput->stream->common); mFrameSize = (uint16_t)audio_stream_frame_size(&mInput->stream->common); mInputBytes = mInput->stream->common.get_buffer_size(&mInput->stream->common); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 0698dcb..f3371bf 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -76,8 +76,8 @@ public: pid_t pid, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -87,7 +87,7 @@ public: virtual uint32_t sampleRate(int output) const; virtual int channelCount(int output) const; - virtual int format(int output) const; + virtual uint32_t format(int output) const; virtual size_t frameCount(int output) const; virtual uint32_t latency(int output) const; @@ -189,8 +189,8 @@ public: pid_t pid, int input, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int *sessionId, @@ -301,8 +301,8 @@ private: TrackBase(const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, @@ -329,12 +329,14 @@ private: virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0; virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); - int format() const { + uint32_t format() const { return mFormat; } int channelCount() const ; + uint32_t channelMask() const; + int sampleRate() const; void* getBuffer(uint32_t offset, uint32_t frames) const; @@ -360,9 +362,11 @@ private: // we don't really need a lock for these int mState; int mClientTid; - uint8_t mFormat; + uint32_t mFormat; uint32_t mFlags; int mSessionId; + uint8_t mChannelCount; + uint32_t mChannelMask; }; class ConfigEvent { @@ -375,7 +379,7 @@ private: uint32_t sampleRate() const; int channelCount() const; - int format() const; + uint32_t format() const; size_t frameCount() const; void wakeUp() { mWaitWorkCV.broadcast(); } void exit(); @@ -406,10 +410,10 @@ private: sp<AudioFlinger> mAudioFlinger; uint32_t mSampleRate; size_t mFrameCount; - uint32_t mChannels; + uint32_t mChannelMask; uint16_t mChannelCount; uint16_t mFrameSize; - int mFormat; + uint32_t mFormat; Condition mParamCond; Vector<String8> mNewParameters; status_t mParamStatus; @@ -442,8 +446,8 @@ private: const sp<Client>& client, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, int sessionId); @@ -530,8 +534,8 @@ private: OutputTrack( const wp<ThreadBase>& thread, DuplicatingThread *sourceThread, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount); ~OutputTrack(); @@ -583,8 +587,8 @@ private: const sp<AudioFlinger::Client>& client, int streamType, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, int sessionId, @@ -829,8 +833,8 @@ private: RecordTrack(const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - int format, - int channelCount, + uint32_t format, + uint32_t channelMask, int frameCount, uint32_t flags, int sessionId); diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 50dcda7..6e9319d 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -26,6 +26,10 @@ #include <utils/Errors.h> #include <utils/Log.h> +#include <cutils/bitops.h> + +#include <system/audio.h> + #include "AudioMixer.h" namespace android { @@ -61,6 +65,7 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate) t->channelCount = 2; t->enabled = 0; t->format = 16; + t->channelMask = AUDIO_CHANNEL_OUT_STEREO; t->buffer.raw = 0; t->bufferProvider = 0; t->hook = 0; @@ -180,13 +185,18 @@ status_t AudioMixer::setParameter(int target, int name, void *value) switch (target) { case TRACK: - if (name == CHANNEL_COUNT) { - if ((uint32_t(valueInt) <= MAX_NUM_CHANNELS) && (valueInt)) { - if (mState.tracks[ mActiveTrack ].channelCount != valueInt) { - mState.tracks[ mActiveTrack ].channelCount = valueInt; - LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", valueInt); + if (name == CHANNEL_MASK) { + uint32_t mask = (uint32_t)value; + if (mState.tracks[ mActiveTrack ].channelMask != mask) { + uint8_t channelCount = popcount(mask); + if ((channelCount <= MAX_NUM_CHANNELS) && (channelCount)) { + mState.tracks[ mActiveTrack ].channelMask = mask; + mState.tracks[ mActiveTrack ].channelCount = channelCount; + LOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask); invalidateState(1<<mActiveTrack); + return NO_ERROR; } + } else { return NO_ERROR; } } diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h index 88408a7..75c9170 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -61,7 +61,7 @@ public: // set Parameter names // for target TRACK - CHANNEL_COUNT = 0x4000, + CHANNEL_MASK = 0x4000, FORMAT = 0x4001, MAIN_BUFFER = 0x4002, AUX_BUFFER = 0x4003, @@ -150,6 +150,7 @@ private: uint8_t enabled : 1; uint8_t reserved0 : 3; uint8_t format; + uint32_t channelMask; AudioBufferProvider* bufferProvider; mutable AudioBufferProvider::Buffer buffer; |