Inter Core Audio Protocol (ICAP) to exchange playback and record audio data between audio device and audio application on different cores. Currently it is using rpmsg as a transport layer but can be expanded to other transport layers.
Current ICAP implementations include bare metal application using rpmsg-lite library and Linux kernel implementation. Future implementations will cover Linux user space library for user space applications.
ICAP has GPLv2 license when distributed with Linux kernel, otherwise it has Apache 2.0 license. For details see the LICENSE file.
Software running on different cores communicate with each using ICAP in application-device relation. One end of the ICAP communication must be application, other end must be device - application creates audio data stream for device to playback and reads audio data recorded by device.
Application side includes icap_application.h with application specific functions and callbacks. Device side includes icap_device.h with device specific functions and callbacks. Each ICAP function call sends appropriate message to the other side which triggers corresponding callback (#icap_device_callbacks or #icap_application_callbacks) for the message. The other side sends back a positive response message (#ICAP_ACK) with or without payload. In case of failure the other side can send back a negative response (#ICAP_NAK) with error code. ICAP application functions are synchronous, they wait for response until #ICAP_MSG_TIMEOUT_US. Application functions work like Remote Function Calls (RFC). ICAP device functions are asynchronous, they don't wait for corresponding response message therefore it is possible to call them in interrupt context which may be required to implement proper playback and record audio streams. When an ICAP device receives a response the proper callback is executed.
It is possible to cascade ICAP communication by calling application functions
inside device callbacks creating a proxy between first ICAP application side and
final ICAP device side. E.G on SC584 SOC it's possible to establish ICAP
communication between:
ICAP application on ARM <-> ICAP proxy on SHARC0 <-> ICAP device on SHARC1
- Include icap_application.h and allocate statically or dynamically
struct icap_instance
andstruct icap_application_callbacks
. - Initialize
icap_application_callbacks
with proper callback funtions. - Set appropriate field of the
icap_instance.transport
:
- for bare metal + rpmsg-lite set the
icap_transport.rpmsg_instance
andicap_transport.rpmsg_ept
fields. - for linux kernel set the
icap_transport.rpdev
field. - for linux user space set the
icap_transport.fd
field.
- Initialize the ICAP instance with
icap_application_init()
. - Get number of subdevices from ICAP device using
icap_get_subdevices()
. - Get features of each device using
icap_get_subdevice_features()
. - For a playback subdevice (
#ICAP_DEV_PLAYBACK
) allocate source buffer and attach the buffer to thesubdevice using icap_add_src()
. - For a record subdevice
(#ICAP_DEV_RECORD)
allocate destination buffer and attach the buffer to the subdeviceusing icap_add_dst()
. - Fill the playback buffer with audio data.
- Start subdevices with
icap_start()
. - Monitor buffer levels with
icap_application_callbacks.frag_ready()
, fill more playback audio data if necessary and read recorded audio data.
- Include icap_device.h and allocate statically or dynamically
struct icap_instance
andstruct icap_device_callbacks
. - Initialize icap_device_callbacks with proper callback functions.
- Set appropriate field of the
icap_instance.transport
:
- for bare metal + rpmsg-lite set the
icap_transport.rpmsg_instance
andicap_transport.rpmsg_ept
fields - for linux kernel set the
icap_transport.rpdev
field - for linux user space set the
icap_transport.fd
field
- Initialize the ICAP instance with
icap_device_init()
- Wait until playback and record buffers are attached by
add_src()
andadd_dst()
callbacks. - Wait until a subdevice is started by
start()
callback. - Read audio data from playback buffer and write the data to audio hardware.
- Read audio data from audio hardware and write to record buffer.
- Notify application side about audio fragments consumed from the buffers
using
icap_frag_ready()
.