• Home
  • Documents
  • Download
  • Status
  • FAQ
  • Mailing list
  • Applications
  • Links
  • License
  • Volunteers
  • Contacts

Examples : Audio capture


Voice activity detection, speech recognition, recording, environment detection, or sound source detection in CIOS, the functionalities are all provided by this audio capture section.。

If you want to handle all the processes, in order to use record function in CIOS Audio Core, you will need to handle the following five major sections:
  1. Create your own audio conduit
  2. Select audio device
  3. Audio parameters setting
  4. Start the Host API interface
  5. Stream activities handling
If you don't want to handle the stream process and Host API by yourself, you can simply use Record function in the Core and create an audio conduit of your own.

virtual bool Record (Conduit      * conduit              ,
                     CaDeviceIndex  deviceId             ,
                     int            channelCount         ,
                     CaSampleFormat sampleFormat         ,
                     int            sampleRate           ,
                     int            frameCount           ,
                     CaStreamFlags  streamFlags   =  0   ,
                     int            sleepInterval = 50 ) ;
              
Parameter
Explain
conduit
Conduit
deviceId
Audio device ID
channelCount
Audio channel numbers
sampleFormat
Sampling format.  Please read <CaSampleFormat>.
sampleRate
Sampling rate.  CIOS Audio Core supports range from 8000 to 192000.  Some devices might not support specific sampling rates.
frameCount
The block number of each sampling interval.  Suggested values are 0.1 ~ 0.2 second.
If your sampling rate is 44100 or 48000, then frameCount is suggested to be 4410, 8820 or 4800, 9600.
streamFlags
Stream flags, normally it is 0.  Except for specific Host API functionalities, you don't need to care about this flag.
sleepInterval
Interval to detect the status of stream.  Suggested values are 50~250 ms, not to set a big value if possible.

Example

Core core ;
MyOwnConduit * conduit = new MyOwnConduit () ;
...
core . Record ( conduit , 1 , 2 , cafInt16 , 44100 , 4410 , 0 , 100 ) ;
...

If you need a non-blocking recording, please read <Play audio files with FFmpeg> for thread implementation.

Create your own audio conduit

A complete details about creating audio conduit, please read <Create an inherit audio conduit>, <LinearConduit>, or <BridgeConduit>.

If you want to handle audio input stream, what you need is to inherit two functions, obtain function just return Complete:

virtual int put (void) = 0 ;
virtual void finish (ConduitDirection direction = NoDirection ,FinishCondition condition = Correct ) = 0 ;

put function handles StreamIO Input, the way it does as following:

int MyOwnConduit::put (void)
{
  if ( ... condition is ready for audio input ... ) {
     ... copy your audio input into Input.Buffer ...
     // example code in BridgeConduit.cpp : 
Buffer . put ( Input . Buffer , Input . Total ( ) ) ;
     return Continue ;
  }
  if ( ... condition is audio input is completely empty ... ) {
    return Complete ;
  }
  if ( ... condition has something unexpected ... ) {
    return Abort ;
  }
  return Postpone ;
}

When the whole stream is completely stopped, stream wiil give a shot to call finish.

void MyOwnConduit::finish (ConduitDirection direction,FinishCondition condition = Correct)
{
  if ( InputDirection != direction ) return ;
  ... handle your own finishing conditions here ...
}

Select audio device

You will have to obtain the information inside DeviceInfo to know about the details of the audio device.  Please read <DeviceInfo> for details.

Example in CaPlay.cpp

void ListInputDevices(void)
{
  Core core                                      ;
  core . Initialize ( )                          ;
  for (int i=0;i<core.DeviceCount();i++)         {
    DeviceInfo * dev                             ;
    dev = core.GetDeviceInfo((CaDeviceIndex)i)   ;
    if ( NULL != dev && dev->maxInputChannels>0) {
      printf("%4d : %s\n",i,dev->name)           ;
    }                                            ;
  }                                              ;
  core . Terminate  ( )                          ;
}

Normally, you have to know the recording audio device ID before you use it.  If you did not set up audio device ID, the system will select by using the following function:

virtual CaDeviceIndex DefaultInputDevice (void) ;

Due to the underlying implementation, this device might possibly not work properly. Because CIOS Audio Core is using these underlying audio drivers, if the recording device can not work properly, looking for a solution inside CIOS Audio Core is useless.

Audio parameters setting

Set up audio parameters requires to set the values within StreamParameters, please read <StreamParameters> for details.

Normally, use the following declaration to set up the parameters:

StreamParameters inputParameters ( deviceId , channelCount , sampleFormat ) ;

Set up sampling rate can be done only when you open a stream, please read <Start the Host API interface>.

Start the Host API interface


Start and stop a Host API interface require the following steps:

Core core                                                                  ;
...
core . Initialize
( ) ;
//////////////////////////////////////////////////////////////////////////// ... configure input paraments here ... //////////////////////////////////////////////////////////////////////////// rt = core . Open ( &stream , &inputParameters ,
NULL , sampleRate , frameCount , streamFlags , conduit ) ; if ( ( NoError != rt ) || ( NULL == stream ) ) correct = false ; //////////////////////////////////////////////////////////////////////////// if ( correct ) { rt = core . Start ( stream ) ; if ( NoError != rt ) correct = false ;
////////////////////////////////////////////////////////////////////////// ... handle your stream process here ... ////////////////////////////////////////////////////////////////////////// if ( correct && ( 0 != core.IsStopped ( stream ) ) ) core.Stop ( stream ) ; } core . Close ( stream ) ; core . Terminate ( ) ;
...

Stream activities handling


After audio stream are started, you will have to detect its status.  The following two Core functions are what your need:

virtual CaError IsStopped (Stream * stream) ;
virtual CaError IsActive (Stream * stream) ;

Example :

while ( 1 == core . IsActive ( stream ) ) {
 Timer :: Sleep ( sleepInterval ) ;
}

Example codes


/* Record specific device into conduit */
bool Core::Record ( Conduit      * conduit       ,
                    CaDeviceIndex  deviceId      ,
                    int            channelCount  ,
                    CaSampleFormat sampleFormat  ,
                    int            sampleRate    ,
                    int            frameCount    ,
                    CaStreamFlags  streamFlags   ,
                    int            sleepInterval )
{
  if ( NULL == conduit ) return false                                        ;
  ////////////////////////////////////////////////////////////////////////////
  StreamParameters INSP ( deviceId , channelCount , sampleFormat )           ;
  Stream         * stream  = NULL                                            ;
  CaError          rt                                                        ;
  bool             correct = true                                            ;
  ////////////////////////////////////////////////////////////////////////////
  Initialize ( )                                                             ;
  ////////////////////////////////////////////////////////////////////////////
  INSP . suggestedLatency = GetDeviceInfo(deviceId)->defaultLowInputLatency  ;
  ////////////////////////////////////////////////////////////////////////////
  rt = Open ( &stream                                                        ,
              &INSP                                                          ,
              NULL                                                           ,
              sampleRate                                                     ,
              frameCount                                                     ,
              streamFlags                                                    ,
              conduit                                                      ) ;
  if ( ( NoError != rt ) || ( NULL == stream ) ) correct = false             ;
  ////////////////////////////////////////////////////////////////////////////
  if ( correct )                                                             {
    rt = Start ( stream )                                                    ;
    if ( NoError != rt ) correct = false                                     ;
  ////////////////////////////////////////////////////////////////////////////
    while ( correct && ( 1 == IsActive  ( stream ) ) )                       {
      Timer :: Sleep ( sleepInterval )                                       ;
    }                                                                        ;
    //////////////////////////////////////////////////////////////////////////
    if ( correct &&  ( 0 != IsStopped ( stream ) ) ) Stop ( stream )         ;
  }                                                                          ;
  Close     ( stream )                                                       ;
  Terminate (        )                                                       ;
  return correct                                                             ;
}