//( { file_desc: "Cross platform audio device interface." kw:[audio rt] } // // This interface provides data declarations for platform dependent // audio I/O functions. The implementation for the functions are // in platform specific modules. See cwAudioDeviceAlsa.cpp. // // ALSA Notes: // Assign capture device to line or mic input: // amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Mic // amixer -c 0 cset iface=MIXER,name='Input Source',index=0 Line // // -c 0 select the first card // -iface=MIXER the cset is targetting the MIXER component // -name='Input Source',index=0 the control to set is the first 'Input Source' // Note that the 'Capture' control sets the input gain. // // See alsamixer for a GUI to accomplish the same thing. // // //) #ifndef cwAudioDevice_H #define cwAudioDevice_H namespace cw { namespace audio { namespace device { typedef float sample_t; // audioPacket_t flags enum { kInterleavedApFl = 0x01, // The audio samples are interleaved. kFloatApFl = 0x02 // The audio samples are single precision floating point values. }; // Audio packet record used by the audioPacket_t callback. // Audio ports send and receive audio using this data structure. typedef struct { unsigned devIdx; // device associated with packet unsigned begChIdx; // first device channel unsigned chCnt; // count of channels unsigned audioFramesCnt; // samples per channel (see note below) unsigned bitsPerSample; // bits per sample word unsigned flags; // kInterleavedApFl | kFloatApFl void* audioBytesPtr; // pointer to sample data void* cbArg; // user defined argument passed in via deviceSetup() time::spec_t timeStamp; // Packet time stamp. } audioPacket_t; // Audio port callback signature. // inPktArray[inPktCnt] are full packets of audio coming from the ADC to the application. // outPktArray[outPktCnt] are empty packets of audio which will be filled by the application // and then sent to the DAC. // // The value of audioFrameCnt gives the number of samples per channel which are available // in the packet data buffer 'audioBytesPtr'. The callback function may decrease this number in // output packets if the number of samples available is less than the size of the buffer. // It is the responsibility of the calling audio port to notice this change and pass the new, // decreased number of samples to the hardware. // // In general it should be assmed that this call is made from a system thread which is not // the same as the application thread. // The usual thread safety precautions should therefore be taken if this function implementation // interacts with data structures also handled by the application. The audio buffer class (\see cwAudioBuf.h) // is designed to provide a safe and efficient way to communicate between // the audio thread and the application. typedef void (*cbFunc_t)( void* cbArg, audioPacket_t* inPktArray, unsigned inPktCnt, audioPacket_t* outPktArray, unsigned outPktCnt ); typedef struct driver_str { void* drvArg; rc_t (*deviceCount)( struct driver_str* drvArg); const char* (*deviceLabel)( struct driver_str* drvArg, unsigned devIdx ); unsigned (*deviceChannelCount)( struct driver_str* drvArg, unsigned devIdx, bool inputFl ); double (*deviceSampleRate)( struct driver_str* drvArg, unsigned devIdx ); unsigned (*deviceFramesPerCycle)( struct driver_str* drvArg, unsigned devIdx, bool inputFl ); rc_t (*deviceSetup)( struct driver_str* drvArg, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData ); rc_t (*deviceStart)( struct driver_str* drvArg, unsigned devIdx ); rc_t (*deviceStop)( struct driver_str* drvArg, unsigned devIdx ); bool (*deviceIsStarted)( struct driver_str* drvArg, unsigned devIdx ); void (*deviceRealTimeReport)( struct driver_str* drvArg, unsigned devIdx ); } driver_t; typedef handle handle_t; rc_t create( handle_t& hRef ); rc_t destroy( handle_t& hRef ); rc_t registerDriver( handle_t h, driver_t* drv ); unsigned deviceCount( handle_t h ); unsigned deviceLabelToIndex( handle_t h, const char* label ); const char* deviceLabel( handle_t h, unsigned devIdx ); unsigned deviceChannelCount( handle_t h, unsigned devIdx, bool inputFl ); double deviceSampleRate( handle_t h, unsigned devIdx ); unsigned deviceFramesPerCycle( handle_t h, unsigned devIdx, bool inputFl ); // Configure a device. // All devices must be setup before they are started. // framesPerCycle is the requested number of samples per audio callback. The // actual number of samples made from a callback may be smaller. See the note // regarding this in audioPacket_t. // If the device cannot support the requested configuration then the function // will return an error code. // If the device is started when this function is called then it will be // automatically stopped and then restarted following the reconfiguration. // If the reconfiguration fails then the device may not be restared. rc_t deviceSetup( handle_t h, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData ); rc_t deviceStart( handle_t h, unsigned devIdx ); rc_t deviceStop( handle_t h, unsigned devIdx ); bool deviceIsStarted( handle_t h, unsigned devIdx ); void deviceRealTimeReport( handle_t h, unsigned devIdx ); void report( handle_t h ); } } } #endif