当前位置:网站首页>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 .
 Insert picture description here
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
 Insert picture description here
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;
}
原网站

版权声明
本文为[Zhaokaixin xiansen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111223317350.html