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:
- Create your own audio conduit
- Select audio device
- Audio parameters setting
- Start the Host API interface
- Stream activities handling
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 ;
}