当前位置:网站首页>Audio adaptation of openharmony Standard System Porting
Audio adaptation of openharmony Standard System Porting
2022-06-11 12:39:00 【Zhaokaixin xiansen】
First, put the playing flow chart given on the official website .
First, execute drivers/framework/model/audio/dispatch/src/audio_stream_dispatch.c Published services in
The first is array declaration and initialization
static struct StreamDispCmdHandleList g_streamDispCmdHandle[] = {
{
AUDIO_DRV_PCM_IOCTL_WRITE, StreamHostWrite},
{
AUDIO_DRV_PCM_IOCTL_READ, StreamHostRead},
{
AUDIO_DRV_PCM_IOCTL_HW_PARAMS, StreamHostHwParams},
{
AUDIO_DRV_PCM_IOCTL_RENDER_PREPARE, StreamHostRenderPrepare},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_PREPARE, StreamHostCapturePrepare},
{
AUDIO_DRV_PCM_IOCTL_RENDER_OPEN, StreamHostRenderOpen},
{
AUDIO_DRV_PCM_IOCTL_RENDER_CLOSE, StreamHostRenderClose},
{
AUDIO_DRV_PCM_IOCTL_RENDER_START, StreamHostRenderStart},
{
AUDIO_DRV_PCM_IOCTL_RENDER_STOP, StreamHostRenderStop},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_OPEN, StreamHostCaptureOpen},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_CLOSE, StreamHostCaptureClose},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_START, StreamHostCaptureStart},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_STOP, StreamHostCaptureStop},
{
AUDIO_DRV_PCM_IOCTL_RENDER_PAUSE, StreamHostRenderPause},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_PAUSE, StreamHostCapturePause},
{
AUDIO_DRV_PCM_IOCTL_RENDER_RESUME, StreamHostRenderResume},
{
AUDIO_DRV_PCM_IOCTL_CAPTURE_RESUME, StreamHostCaptureResume},
{
AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER, StreamHostMmapWrite},
{
AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE, StreamHostMmapRead},
{
AUDIO_DRV_PCM_IOCTL_MMAP_POSITION, StreamHostMmapPositionWrite},
{
AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE, StreamHostMmapPositionRead},
{
AUDIO_DRV_PCM_IOCTL_DSPDECODE, StreamHostDspDecode},
{
AUDIO_DRV_PCM_IOCTL_DSPENCODE, StreamHostDspEncode},
{
AUDIO_DRV_PCM_IOCTL_DSPEQUALIZER, StreamHostDspEqualizer},
};
Definition of value
enum StreamDispMethodCmd {
AUDIO_DRV_PCM_IOCTL_HW_PARAMS, // The default from the 0 Start
AUDIO_DRV_PCM_IOCTL_RENDER_PREPARE, // 1
AUDIO_DRV_PCM_IOCTL_CAPTURE_PREPARE, // 2
AUDIO_DRV_PCM_IOCTL_WRITE, // 3
AUDIO_DRV_PCM_IOCTL_READ, // 4
AUDIO_DRV_PCM_IOCTL_RENDER_START,// 5
AUDIO_DRV_PCM_IOCTL_RENDER_STOP, // 6
AUDIO_DRV_PCM_IOCTL_CAPTURE_START,// 7
AUDIO_DRV_PCM_IOCTL_CAPTURE_STOP,// 8
AUDIO_DRV_PCM_IOCTL_RENDER_PAUSE,// 9
AUDIO_DRV_PCM_IOCTL_CAPTURE_PAUSE,// 10
AUDIO_DRV_PCM_IOCTL_RENDER_RESUME,
AUDIO_DRV_PCM_IOCTL_CAPTURE_RESUME,
AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER,
AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE,
AUDIO_DRV_PCM_IOCTL_MMAP_POSITION, // 15
AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE,
AUDIO_DRV_PCM_IOCTL_RENDER_OPEN,
AUDIO_DRV_PCM_IOCTL_RENDER_CLOSE,
AUDIO_DRV_PCM_IOCTL_CAPTURE_OPEN,
AUDIO_DRV_PCM_IOCTL_CAPTURE_CLOSE, // 20
AUDIO_DRV_PCM_IOCTL_DSPDECODE,
AUDIO_DRV_PCM_IOCTL_DSPENCODE,
AUDIO_DRV_PCM_IOCTL_DSPEQUALIZER,
AUDIO_DRV_PCM_IOCTL_BUTT, // 24
};
static int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId,
struct HdfSBuf *data, struct HdfSBuf *reply)
{
unsigned int count = sizeof(g_streamDispCmdHandle) / sizeof(g_streamDispCmdHandle[0]);
unsigned int i = 0;
for (i = 0; i < count; ++i) {
if ((cmdId == (int)(g_streamDispCmdHandle[i].cmd)) && (g_streamDispCmdHandle[i].func != NULL)) {
// Judge whether the parameter value passed from the upper layer and the corresponding function body exist
return g_streamDispCmdHandle[i].func(client, data, reply);
}
}
ADM_LOG_ERR("invalid [cmdId=%d]", cmdId);
return HDF_FAILURE;
}
According to the opening picture , Know that the first command sent is AUDIO_DRV_PCM_IOCTL_RENDER_OPEN, Then the corresponding function to be executed is the following function
static int32_t StreamHostRenderOpen(const struct HdfDeviceIoClient *client, struct HdfSBuf *data,
struct HdfSBuf *reply)
{
char *cardName = NULL;
const char *carNameTemp = NULL;
struct StreamHost *streamHost = NULL;
struct AudioCard *audioCard = NULL;
ADM_LOG_DEBUG("entry.");
if (client == NULL) {
ADM_LOG_ERR("StreamHostRenderOpen input param is NULL.");
return HDF_FAILURE;
}
(void)reply;
cardName = (char *)OsalMemCalloc(sizeof(char) * BUFF_SIZE_MAX);
if (cardName == NULL) {
ADM_LOG_ERR("malloc cardServiceName failed!");
return HDF_FAILURE;
}
streamHost = StreamHostFromDevice(client->device);
if (streamHost == NULL) {
ADM_LOG_ERR("renderHost is NULL");
OsalMemFree(cardName);
return HDF_FAILURE;
}
if (!(carNameTemp = HdfSbufReadString(data))) {
ADM_LOG_ERR("read request cardServiceName failed!");
OsalMemFree(cardName);
return HDF_FAILURE;
}
if (strncpy_s(cardName, BUFF_SIZE_MAX - 1, carNameTemp, strlen(carNameTemp) + 1) != EOK) {
ADM_LOG_ERR("memcpy cardName failed.");
OsalMemFree(cardName);
return HDF_FAILURE;
}
ADM_LOG_DEBUG("card name: %s.", cardName);
streamHost->priv = cardName;
audioCard = StreamHostGetCardInstance(client);
if (audioCard == NULL || audioCard->rtd == NULL) {
ADM_LOG_ERR("StreamHostRenderOpen get card instance or rtd failed.");
return HDF_FAILURE;
}
if (AudioRenderOpen(audioCard) != HDF_SUCCESS) {
ADM_LOG_ERR("platform RenderOpen failed.");
return HDF_FAILURE;
}
if (AudioDaiDeviceStartup(audioCard) != HDF_SUCCESS) {
ADM_LOG_ERR("Dai Device Startup failed.");
return HDF_FAILURE;
}
ADM_LOG_DEBUG("success.");
return HDF_SUCCESS;
}
The first change Kconfig file , Add our audio driver compilation options
diff --git a/drivers/adapter/khdf/linux/model/audio/Kconfig b/drivers/adapter/khdf/linux/model/audio/Kconfig
index 82cc568be9..fe5e0c7e5d 100644
--- a/drivers/adapter/khdf/linux/model/audio/Kconfig
+++ b/drivers/adapter/khdf/linux/model/audio/Kconfig
@@ -18,6 +18,13 @@ config DRIVERS_HDF_AUDIO_RK3568
help
Answer Y to choice HDF Audio Codec driver.
+config DRIVERS_HDF_AUDIO_T113
+ bool "Enable HDF Audio Codec driver for t113"
+ default n
+ depends on DRIVERS_HDF_AUDIO
+ help
+ Answer Y to choice HDF Audio Codec driver.
+
config DRIVERS_HDF_AUDIO_TEST
bool "Enable HDF Audio driver Test"
default n
And then in drivers/peripheral/audio/chipsets Directory to create our own audio driver file storage directory t113, And then t113 Create under directory accessory codec dai dsp soc Catalog , As shown in the figure below 
Then start adding files , We don't know what we're doing yet , So let's imitate others and add them first .
Then start debugging the files in each directory , First of all codec, stay drivers/peripheral/audio/chipsets/t113/codec Create include src Two directories , among src Save drive ,include Save header file . stay src newly build t113_codec_adapter.c t113_codec_impl_linux.c t113_codec_ops.c Three files , Then start writing the driver file , First of all t113_codec_adapter.c file , Here you need to fill in the following three structures
struct CodecData g_codecData = {
.Init = CodecDeviceInit, // codec Device initialization ( Adapting to the new platform needs to be re implemented )
.Read = AudioDeviceReadReg, // Read register ( The existing framework has been implemented , No need to adapt )
.Write = AudioDeviceWriteReg, // Write register ( The existing framework has been implemented , No need to adapt )
};
struct AudioDaiOps g_codecDaiDeviceOps = {
.Startup = CodecDaiStartup, // Start transmission ( Adapting to the new platform needs to be re implemented )
.HwParams = CodecDaiHwParams, // Parameter configuration ( Adapting to the new platform needs to be re implemented )
};
struct DaiData g_codecDaiData = {
.DaiInit = CodecDaiDeviceInit, // codecdai Device initialization ( Adapting to the new platform needs to be re implemented )
.ops = &g_codecDaiDeviceOps, //codecdai Operation function
};
The whole document is as follows
#include "audio_codec_base.h"
#include "audio_core.h"
#include "audio_driver_log.h"
#include "t113_codec_ops.h"
#define HDF_LOG_TAG t113_codec_adapter
struct CodecData g_codecData = {
.Init = AllwinnerCodecDeviceInit, // codec Device initialization
.Read = AllwinnerAudioDeviceReadReg, // A function that reads the value of a register
.Write = AllwinnerAudioDeviceWriteReg, // Functions that write register values
};
struct AudioDaiOps g_codecDaiDeviceOps = {
.Startup = AllwinnerCodecDaiStartup, // Start transmission
.HwParams = AllwinnerCodecDaiHwParams,// Parameter configuration
.Trigger = AllwinnerCodecDaiTrigger,
};
struct DaiData g_codecDaiData = {
.DaiInit = AllwinnerCodecDaiDeviceInit,
.ops = &g_codecDaiDeviceOps,
};
static int32_t CodecDriverBind(struct HdfDeviceObject *device)
{
struct CodecHost *codecHost;
AUDIO_DRIVER_LOG_DEBUG("");
if (device == NULL) {
AUDIO_DRIVER_LOG_ERR("input para is NULL.");
return HDF_FAILURE;
}
codecHost = (struct CodecHost *)OsalMemCalloc(sizeof(*codecHost));
if (codecHost == NULL) {
AUDIO_DRIVER_LOG_ERR("malloc codecHost fail!");
return HDF_FAILURE;
}
codecHost->device = device;
device->service = &codecHost->service;
AUDIO_DRIVER_LOG_DEBUG("success!");
return HDF_SUCCESS;
}
static int32_t CodecDriverInit(struct HdfDeviceObject *device)
{
AUDIO_DRIVER_LOG_DEBUG("start %s",__func__);
if (device == NULL) {
AUDIO_DRIVER_LOG_ERR("device is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (CodecGetConfigInfo(device, &g_codecData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecSetConfigInfo(&g_codecData, &g_codecDaiData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecGetServiceName(device, &g_codecData.drvCodecName) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecGetDaiName(device, &g_codecDaiData.drvDaiName) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (AudioRegisterCodec(device, &g_codecData, &g_codecDaiData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static void CodecDriverRelease(struct HdfDeviceObject *device)
{
struct CodecHost *codecHost;
if (device == NULL) {
AUDIO_DRIVER_LOG_ERR("device is NULL");
return;
}
if (device->priv != NULL) {
OsalMemFree(device->priv);
}
codecHost = (struct CodecHost *)device->service;
if (codecHost == NULL) {
HDF_LOGE("CodecDriverRelease: codecHost is NULL");
return;
}
OsalMemFree(codecHost);
}
struct HdfDriverEntry g_codec_T133_DriverEntry = {
.moduleVersion = 1,
.moduleName = "T113_CODEC",
.Bind = CodecDriverBind,
.Init = CodecDriverInit,
.Release = CodecDriverRelease,
};
HDF_INIT(g_codec_T133_DriverEntry);
Let's focus on CodecDriverInit function
static int32_t CodecDriverInit(struct HdfDeviceObject *device)
{
AUDIO_DRIVER_LOG_DEBUG("start %s",__func__);
if (device == NULL) {
AUDIO_DRIVER_LOG_ERR("device is NULL.");
return HDF_ERR_INVALID_OBJECT;
}
if (CodecGetConfigInfo(device, &g_codecData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecSetConfigInfo(&g_codecData, &g_codecDaiData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecGetServiceName(device, &g_codecData.drvCodecName) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (CodecGetDaiName(device, &g_codecDaiData.drvDaiName) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (AudioRegisterCodec(device, &g_codecData, &g_codecDaiData) != HDF_SUCCESS) {
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
边栏推荐
- Flink multi stream conversion (side output stream shunting, union, connect) real-time reconciliation of APP payment operations and third-party payment operations
- 场馆坪效这么低?关键在这两方面
- STM32 development of practical series 7-data Porter DMA
- Flash framework web development video notes
- 11、Synchronized与锁升级
- ZABBIX installation and configuration application
- Flick controls window behavior (trigger, remover, allow delay, put late data into side output stream)
- Oracle DatabaseLink 跨数据库连接
- Flink spark vs. Flink
- Wireshark packet capturing and debugging RTSP
猜你喜欢
随机推荐
What are the elements of running a gymnasium?
11、Synchronized与锁升级
知麻Z1投影仪真的好用吗?实际效果怎么样?
FTP server: downloading and using Serv-U
羽毛球馆有哪些创收方式
Flick scrolling window, sliding window, session window, global window
flink 部署模式和运行时架构(会话模式、单作业模式、应用模式,JobManager、TaskManager,YARN 模式部署以及运行时架构)
openharmony标准系统之app手动签名
STM32 development of practical series 7-data Porter DMA
2. Completablefuture
Jerry's CMD_ SET_ BT_ Name command format [chapter]
Serveur FTP: téléchargement et utilisation de Serv - U
Is Zhima Z1 projector really easy to use? How about the actual effect?
Redis RDB和AOF
After Oracle deletes a user, it can still use the user to log in
(recommended) how many splunks are appropriate? Search head
9、聊聊ThreadLocal
Another way to achieve family reunion, 2022 flagship projection nut j10s is planted with grass
node结合art-template 模板引擎 创建模板文件
美容院管理系统如何解决门店运营的三大难题?









