MonoPipe.h revision 820ba70df8ba595ae9055dfd34fdbfa32f70f14d
1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/* 2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2012 The Android Open Source Project 3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * you may not use this file except in compliance with the License. 6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * You may obtain a copy of the License at 7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software 11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * See the License for the specific language governing permissions and 14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * limitations under the License. 15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */ 16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#ifndef ANDROID_AUDIO_MONO_PIPE_H 18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#define ANDROID_AUDIO_MONO_PIPE_H 19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <time.h> 21010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include "NBAIO.h" 22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 23010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android { 24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 25010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// MonoPipe is similar to Pipe except: 26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - supports only a single reader, called MonoPipeReader 27010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - write() cannot overrun; instead it will return a short actual count if insufficient space 28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - write() can optionally block if the pipe is full 29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// Like Pipe, it is not multi-thread safe for either writer or reader 30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// but writer and reader can be different threads. 31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenclass MonoPipe : public NBAIO_Sink { 32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten friend class MonoPipeReader; 34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenpublic: 36820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten // reqFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2. 37010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // Note: whatever shares this object with another thread needs to do so in an SMP-safe way (like 38010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // creating it the object before creating the other thread, or storing the object with a 39010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // release_store). Otherwise the other thread could see a partially-constructed object. 40820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock = false); 41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ~MonoPipe(); 42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 43010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Port interface 44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers, 46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Format counterOffers[], size_t& numCounterOffers); 47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual NBAIO_Format format() const; 48010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 49010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Sink interface 50010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 51010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t framesWritten() const; 52010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t framesUnderrun() const; 53010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t underruns() const; 54010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 55010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ssize_t availableToWrite() const; 56010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ssize_t write(const void *buffer, size_t count); 57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block); 58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 59e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent // average number of frames present in the pipe under normal conditions. 60e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent // See throttling mechanism in MonoPipe::write() 61820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten size_t getAvgFrames() const { return (mReqFrames * 11) / 16; } 62e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent 63010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenprivate: 64820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten const size_t mReqFrames; // as requested in constructor, unrounded 65010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten const size_t mMaxFrames; // always a power of 2 66010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten void * const mBuffer; 67010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // mFront and mRear will never be separated by more than mMaxFrames. 68010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // 32-bit overflow is possible if the pipe is active for a long time, but if that happens it's 69010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // safe because we "&" with (mMaxFrames-1) at end of computations to calculate a buffer index. 70010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten volatile int32_t mFront; // written by reader with android_atomic_release_store, 71010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // read by writer with android_atomic_acquire_load 72010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten volatile int32_t mRear; // written by writer with android_atomic_release_store, 73010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // read by reader with android_atomic_acquire_load 74010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten const bool mWriteCanBlock; // whether write() should block if the pipe is full 75010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}; 76010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 77010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} // namespace android 78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 79010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#endif // ANDROID_AUDIO_MONO_PIPE_H 80