Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_AUDIO_TRACK_SHARED_H
     18 #define ANDROID_AUDIO_TRACK_SHARED_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 
     23 #include <utils/threads.h>
     24 #include <utils/Log.h>
     25 
     26 namespace android {
     27 
     28 // ----------------------------------------------------------------------------
     29 
     30 // Maximum cumulated timeout milliseconds before restarting audioflinger thread
     31 #define MAX_STARTUP_TIMEOUT_MS  3000    // Longer timeout period at startup to cope with A2DP
     32                                         // init time
     33 #define MAX_RUN_TIMEOUT_MS      1000
     34 #define WAIT_PERIOD_MS          10
     35 
     36 #define CBLK_UNDERRUN   0x01 // set: underrun (out) or overrrun (in), clear: no underrun or overrun
     37 #define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
     38                              // clear: track is ready when buffer full
     39 #define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
     40 #define CBLK_DISABLED   0x08 // track disabled by AudioFlinger due to underrun, need to re-start
     41 
     42 struct AudioTrackSharedStreaming {
     43     // similar to NBAIO MonoPipe
     44     volatile int32_t mFront;
     45     volatile int32_t mRear;
     46 };
     47 
     48 // future
     49 struct AudioTrackSharedStatic {
     50     int mReserved;
     51 };
     52 
     53 // ----------------------------------------------------------------------------
     54 
     55 // Important: do not add any virtual methods, including ~
     56 struct audio_track_cblk_t
     57 {
     58                 friend class Proxy;
     59                 friend class AudioTrackClientProxy;
     60                 friend class AudioRecordClientProxy;
     61                 friend class ServerProxy;
     62 
     63     // The data members are grouped so that members accessed frequently and in the same context
     64     // are in the same line of data cache.
     65                 Mutex       lock;           // sizeof(int)
     66                 Condition   cv;             // sizeof(int)
     67 
     68                 // next 4 are offsets within "buffers"
     69     volatile    uint32_t    user;
     70     volatile    uint32_t    server;
     71                 uint32_t    userBase;
     72                 uint32_t    serverBase;
     73 
     74                 int         mPad1;          // unused, but preserves cache line alignment
     75 
     76                 size_t      frameCount_;    // used during creation to pass actual track buffer size
     77                                             // from AudioFlinger to client, and not referenced again
     78                                             // FIXME remove here and replace by createTrack() in/out parameter
     79                                             // renamed to "_" to detect incorrect use
     80 
     81                 // Cache line boundary (32 bytes)
     82 
     83                 uint32_t    loopStart;
     84                 uint32_t    loopEnd;        // read-only for server, read/write for client
     85                 int         loopCount;      // read/write for client
     86 
     87                 // Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
     88                 // Left channel is in [0:15], right channel is in [16:31].
     89                 // Always read and write the combined pair atomically.
     90                 // For AudioTrack only, not used by AudioRecord.
     91 private:
     92                 uint32_t    mVolumeLR;
     93 
     94                 uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
     95                                             // or 0 == default. Write-only client, read-only server.
     96 
     97                 uint8_t     mPad2;           // unused
     98 
     99 public:
    100                 // read-only for client, server writes once at initialization and is then read-only
    101                 uint8_t     mName;           // normal tracks: track name, fast tracks: track index
    102 
    103                 // used by client only
    104                 uint16_t    bufferTimeoutMs; // Maximum cumulated timeout before restarting
    105                                              // audioflinger
    106 
    107                 uint16_t    waitTimeMs;      // Cumulated wait time, used by client only
    108 private:
    109                 // client write-only, server read-only
    110                 uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
    111 public:
    112     volatile    int32_t     flags;
    113 
    114                 // Cache line boundary (32 bytes)
    115 
    116 #if 0
    117                 union {
    118                     AudioTrackSharedStreaming   mStreaming;
    119                     AudioTrackSharedStatic      mStatic;
    120                     int                         mAlign[8];
    121                 } u;
    122 
    123                 // Cache line boundary (32 bytes)
    124 #endif
    125 
    126                 // Since the control block is always located in shared memory, this constructor
    127                 // is only used for placement new().  It is never used for regular new() or stack.
    128                             audio_track_cblk_t();
    129 
    130 private:
    131                 // if there is a shared buffer, "buffers" is the value of pointer() for the shared
    132                 // buffer, otherwise "buffers" points immediately after the control block
    133                 void*       buffer(void *buffers, uint32_t frameSize, size_t offset) const;
    134 
    135                 bool        tryLock();
    136 
    137                 // isOut == true means AudioTrack, isOut == false means AudioRecord
    138                 bool        stepServer(size_t stepCount, size_t frameCount, bool isOut);
    139                 uint32_t    stepUser(size_t stepCount, size_t frameCount, bool isOut);
    140                 uint32_t    framesAvailable(size_t frameCount, bool isOut);
    141                 uint32_t    framesAvailable_l(size_t frameCount, bool isOut);
    142                 uint32_t    framesReady(bool isOut);
    143 };
    144 
    145 // ----------------------------------------------------------------------------
    146 
    147 // Proxy for shared memory control block, to isolate callers from needing to know the details.
    148 // There is exactly one ClientProxy and one ServerProxy per shared memory control block.
    149 // The proxies are located in normal memory, and are not multi-thread safe within a given side.
    150 class Proxy {
    151 protected:
    152     Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
    153         : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize) { }
    154     virtual ~Proxy() { }
    155 
    156 public:
    157     void*   buffer(size_t offset) const {
    158         return mCblk->buffer(mBuffers, mFrameSize, offset);
    159     }
    160 
    161 protected:
    162     // These refer to shared memory, and are virtual addresses with respect to the current process.
    163     // They may have different virtual addresses within the other process.
    164     audio_track_cblk_t* const   mCblk;          // the control block
    165     void* const                 mBuffers;       // starting address of buffers
    166 
    167     const size_t                mFrameCount;    // not necessarily a power of 2
    168     const size_t                mFrameSize;     // in bytes
    169 #if 0
    170     const size_t                mFrameCountP2;  // mFrameCount rounded to power of 2, streaming mode
    171 #endif
    172 
    173 };
    174 
    175 // ----------------------------------------------------------------------------
    176 
    177 // Proxy seen by AudioTrack client and AudioRecord client
    178 class ClientProxy : public Proxy {
    179 protected:
    180     ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
    181         : Proxy(cblk, buffers, frameCount, frameSize) { }
    182     virtual ~ClientProxy() { }
    183 };
    184 
    185 // ----------------------------------------------------------------------------
    186 
    187 // Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
    188 class AudioTrackClientProxy : public ClientProxy {
    189 public:
    190     AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
    191         : ClientProxy(cblk, buffers, frameCount, frameSize) { }
    192     virtual ~AudioTrackClientProxy() { }
    193 
    194     // No barriers on the following operations, so the ordering of loads/stores
    195     // with respect to other parameters is UNPREDICTABLE. That's considered safe.
    196 
    197     // caller must limit to 0.0 <= sendLevel <= 1.0
    198     void        setSendLevel(float sendLevel) {
    199         mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
    200     }
    201 
    202     // caller must limit to 0 <= volumeLR <= 0x10001000
    203     void        setVolumeLR(uint32_t volumeLR) {
    204         mCblk->mVolumeLR = volumeLR;
    205     }
    206 
    207     void        setSampleRate(uint32_t sampleRate) {
    208         mCblk->mSampleRate = sampleRate;
    209     }
    210 
    211     // called by:
    212     //   PlaybackThread::OutputTrack::write
    213     //   AudioTrack::createTrack_l
    214     //   AudioTrack::releaseBuffer
    215     //   AudioTrack::reload
    216     //   AudioTrack::restoreTrack_l (2 places)
    217     size_t      stepUser(size_t stepCount) {
    218         return mCblk->stepUser(stepCount, mFrameCount, true /*isOut*/);
    219     }
    220 
    221     // called by AudioTrack::obtainBuffer and AudioTrack::processBuffer
    222     size_t      framesAvailable() {
    223         return mCblk->framesAvailable(mFrameCount, true /*isOut*/);
    224     }
    225 
    226     // called by AudioTrack::obtainBuffer and PlaybackThread::OutputTrack::obtainBuffer
    227     // FIXME remove this API since it assumes a lock that should be invisible to caller
    228     size_t      framesAvailable_l() {
    229         return mCblk->framesAvailable_l(mFrameCount, true /*isOut*/);
    230     }
    231 
    232 };
    233 
    234 // ----------------------------------------------------------------------------
    235 
    236 // Proxy used by AudioRecord client
    237 class AudioRecordClientProxy : public ClientProxy {
    238 public:
    239     AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
    240         : ClientProxy(cblk, buffers, frameCount, frameSize) { }
    241     ~AudioRecordClientProxy() { }
    242 
    243     // called by AudioRecord::releaseBuffer
    244     size_t      stepUser(size_t stepCount) {
    245         return mCblk->stepUser(stepCount, mFrameCount, false /*isOut*/);
    246     }
    247 
    248     // called by AudioRecord::processBuffer
    249     size_t      framesAvailable() {
    250         return mCblk->framesAvailable(mFrameCount, false /*isOut*/);
    251     }
    252 
    253     // called by AudioRecord::obtainBuffer
    254     size_t      framesReady() {
    255         return mCblk->framesReady(false /*isOut*/);
    256     }
    257 
    258 };
    259 
    260 // ----------------------------------------------------------------------------
    261 
    262 // Proxy used by AudioFlinger server
    263 class ServerProxy : public Proxy {
    264 public:
    265     ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut)
    266         : Proxy(cblk, buffers, frameCount, frameSize), mIsOut(isOut) { }
    267     virtual ~ServerProxy() { }
    268 
    269     // for AudioTrack and AudioRecord
    270     bool        step(size_t stepCount) { return mCblk->stepServer(stepCount, mFrameCount, mIsOut); }
    271 
    272     // return value of these methods must be validated by the caller
    273     uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
    274     uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
    275     uint32_t    getVolumeLR() const { return mCblk->mVolumeLR; }
    276 
    277     // for AudioTrack only
    278     size_t      framesReady() {
    279         ALOG_ASSERT(mIsOut);
    280         return mCblk->framesReady(true);
    281     }
    282 
    283     // for AudioRecord only, called by RecordThread::RecordTrack::getNextBuffer
    284     // FIXME remove this API since it assumes a lock that should be invisible to caller
    285     size_t      framesAvailableIn_l() {
    286         ALOG_ASSERT(!mIsOut);
    287         return mCblk->framesAvailable_l(mFrameCount, false);
    288     }
    289 
    290 private:
    291     const bool  mIsOut;     // true for AudioTrack, false for AudioRecord
    292 
    293 };
    294 
    295 // ----------------------------------------------------------------------------
    296 
    297 }; // namespace android
    298 
    299 #endif // ANDROID_AUDIO_TRACK_SHARED_H
    300