音频设备(1)——Android音频设备

本文详细介绍了Android系统中针对rk3399和ok4418平台的音频设备信息,包括内核加载的音频设备、设备树定义的虚拟声卡以及驱动文件。在缺少外部音频codec时,Android系统的某些功能如摄像头录像和播放视频可能出现问题。为解决这些问题,文章提到了注册虚拟声卡的方法,展示了如何通过驱动程序和板级文件定义虚拟网卡,以确保系统正常运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

涉及平台:rk3399、ok4418

系统音频设备信息

rk3399_all:/ $ ls /dev/snd/                                                    
controlC0 controlC2 pcmC0D0p pcmC1D0p timer 
controlC1 pcmC0D0c  pcmC1D0c pcmC2D0p

rk3399_all:/ $ ls /sys/class/sound/                                            
card0 card2     controlC1 pcmC0D0c pcmC1D0c pcmC2D0p 
card1 controlC0 controlC2 pcmC0D0p pcmC1D0p timer

rk3399_all:/ $ cat /sys/class/sound/card0/id                                 
RKPCMCARD
rk3399_all:/ $ cat /sys/class/sound/card0/number                               
0
rk3399_all:/ $ cat /sys/class/sound/card0/controlC0/dev                        
116:2

rk3399_all:/ $ cat /sys/class/sound/card1/id                                   
RKWM8960
rk3399_all:/ $ cat /sys/class/sound/card1/number                               
1
rk3399_all:/ $ cat /sys/class/sound/card1/controlC1/dev                        
116:5

rk3399_all:/ $ cat /sys/class/sound/card2/id                                   
rockchiphdmi
rk3399_all:/ $ cat /sys/class/sound/card2/number                               
2
rk3399_all:/ $ cat /sys/class/sound/card2/controlC2/dev                        
116:8

内核音频设备加载信息

RK3399:
[    5.280018] ALSA device list:
[    5.280228]   #0: RK-PCM-CARD
[    5.280428]   #1: RKWM8960
[    5.280671]   #2: rockchip,hdmi

ok4418:
[    2.477000] ALSA device list:
[    2.480000]   #0: I2S-WM8960
[    2.483000]   #1: SPDIF-Transciever

虚拟声卡

RK3399 设备树定义的虚拟声卡

        rockchip_pcm_codec: rockchip-pcm-codec {
                compatible = "rockchip-pcm-codec";
        };

        rockchip-pcm-card {
                compatible = "rockchip-pcm-card";
                status = "okay";
                dais {
                        dai0 {
                                audio-codec = <&rockchip_pcm_codec>;
                                audio-controller = <&i2s1>;
                                format = "i2s";
                        };
                };
        };

驱动文件

kernel/sound/soc/codecs/rk_pcm_codec.c

struct snd_soc_dai_driver pcm_card_dai = {
        .name = "rockchip-pcm-card-hifi",
        .playback = {
                .stream_name = "HiFi Playback",
                .channels_min = 2,
                .channels_max = 2,
                .rates = (SNDRV_PCM_RATE_8000|
                        SNDRV_PCM_RATE_16000 |
                        SNDRV_PCM_RATE_32000 |
                        SNDRV_PCM_RATE_44100 |
                        SNDRV_PCM_RATE_48000 |
                        SNDRV_PCM_RATE_96000 |
                        SNDRV_PCM_RATE_192000),
                .formats = FORMATS,
        },
        .capture = {
                .stream_name = "HiFi Capture",
                .channels_min = 2,
                .channels_max = 2,
                .rates = (
                        SNDRV_PCM_RATE_8000|
                        SNDRV_PCM_RATE_16000|
                        SNDRV_PCM_RATE_32000 |
                        SNDRV_PCM_RATE_44100 |
                        SNDRV_PCM_RATE_48000 |
                        SNDRV_PCM_RATE_96000 |
                        SNDRV_PCM_RATE_192000),
                .formats = FORMATS,
        },

};

xx18 板级文件定义的虚拟网卡

#if defined(CONFIG_SND_CODEC_NULL)
static struct platform_device snd_null = {
        .name = "snd-null",
        .id = -1,
};

struct nxp_snd_dai_plat_data snd_null_dai_data = {
        .i2s_ch = 0,
        .sample_rate = 48000,
        .pcm_format = SNDRV_PCM_FMTBIT_S16_LE,
};

static struct platform_device snd_null_dai = {
        .name = "snd-null-card",
        .id = -1,
        .dev = {
                .platform_data = &snd_null_dai_data,
        }
};

//-------------------------------------
static struct platform_device snd_null_1 = {
        .name = "snd-null",
        .id = 1,
};

struct nxp_snd_dai_plat_data snd_null_dai_data_1 = {
        .i2s_ch = 1,
        .sample_rate = 48000,
        .pcm_format = SNDRV_PCM_FMTBIT_S16_LE,
};

static struct platform_device snd_null_dai_1 = {
        .name = "snd-null-card",
        .id = 1,
        .dev = {
                .platform_data = &snd_null_dai_data_1 ,
        }
};

//-------------------------------------
static struct platform_device snd_null_2 = {
        .name = "snd-null",
        .id = 2,
};

struct nxp_snd_dai_plat_data snd_null_dai_data_2 = {
        .i2s_ch = 2,
        .sample_rate = 48000,
        .pcm_format = SNDRV_PCM_FMTBIT_S16_LE,
};

static struct platform_device snd_null_dai_2 = {
        .name = "snd-null-card",
        .id = 2,
        .dev = {
                .platform_data = &snd_null_dai_data_2 ,
        }
};
#endif

驱动程序

linux/kernel/kernel-3.4.39/sound/soc/nexell/nxp-null.c

static struct platform_driver snd_null_driver = {
        .probe          = snd_null_probe,
        .remove         = snd_null_remove,
        .driver         = {
                .name   = "snd-null",
                .owner  = THIS_MODULE,
        },
};

module_platform_driver(snd_null_driver);

static struct platform_driver snd_card_driver = {
        .driver         = {
                .name   = "snd-null-card",
                .owner  = THIS_MODULE,
                .pm     = &snd_soc_pm_ops,      /* for suspend */
        },
        .probe          = snd_card_probe,
        .remove         = snd_card_remove,
};
module_platform_driver(snd_card_driver);

Android下虚拟声卡的应用

当外接的音频codec缺失的情况下,Android系统有部分功能会因声卡的缺失而异常:
1、摄像头不能录像

I/MediaCodec(  132): MediaCodec will operate in async mode
E/audio_hw_primary(  132): get_input_buffer_size not opened input device, set default pcm config !!!
E/audio_hw_primary(  132): pcm_config_setup pcmC0D0c device does not exist.
E/AudioSystem(  132): AudioSystem::getInputBufferSize failed sampleRate 44100 format 0x1 channelMask 10
E/AudioRecord(  132): AudioSystem could not query the input buffer size for sampleRate 44100, format 0x1, channelMask 0x10; status -22
E/StagefrightRecorder(  132): audio source is not initialized
D/MPEG4Writer(  132): Video track stopping
E/MPEG4Writer(  132): Stop() called but track is not started
D/NX_OMXENC(  132): Sequrnce buffer Size = 21
E/MediaRecorder( 1337): start failed: -2147483648
E/CAM_VideoModule( 1337): Could not start media recorder.
E/CAM_VideoModule( 1337): java.lang.RuntimeException: start failed.
E/CAM_VideoModule( 1337):       at android.media.MediaRecorder.start(Native Method)
E/CAM_VideoModule( 1337):       at com.android.camera.VideoModule$11.onStorageUpdateDone(VideoModule.java:1376)
E/CAM_VideoModule( 1337):       at com.android.camera.CameraActivity$19.onPostExecute(CameraActivity.java:2089)
E/CAM_VideoModule( 1337):       at com.android.camera.CameraActivity$19.onPostExecute(CameraActivity.java:2074)
E/CAM_VideoModule( 1337):       at android.os.AsyncTask.finish(AsyncTask.java:636)
E/CAM_VideoModule( 1337):       at android.os.AsyncTask.access$500(AsyncTask.java:177)
E/CAM_VideoModule( 1337):       at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
E/CAM_VideoModule( 1337):       at android.os.Handler.dispatchMessage(Handler.java:102)
E/CAM_VideoModule( 1337):       at android.os.Looper.loop(Looper.java:135)
E/CAM_VideoModule( 1337):       at android.app.ActivityThread.main(ActivityThread.java:5254)
E/CAM_VideoModule( 1337):       at java.lang.reflect.Method.invoke(Native Method)
E/CAM_VideoModule( 1337):       at java.lang.reflect.Method.invoke(Method.java:372)
E/CAM_VideoModule( 1337):       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/CAM_VideoModule( 1337):       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I/CAM_VideoModule( 1337): Releasing media recorder.

2、播放视频卡顿

这个时候注册虚拟声卡就可以解决这种问题。

TBC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值