文档章节

将usb 声卡集成到android4.0上

雨焰
 雨焰
发布于 2014/01/20 15:54
字数 1233
阅读 4295
收藏 4

1. 任务分解
1.1 android 使用了tinyalsa库,看了一下代码,这个库实在功能太弱,google总是放弃稳定的好用的东西不用,自己乱搞,或许是因为licence的问题?于是第一个子任务是将原来android 2.3.3上的alsa库移植上来。
1.2 内核要打开配置,至少把UAC打开
1.3 找一个usb声卡,淘宝上7块钱就能买到,真他妈便宜,不知道这些人怎么挣钱的!
1.4 使用编译出来的alsa库进行测试,验证可正常使用
1.5 使用android自带的tinyalsa进行播放测试,因为android的HAL层是调用这个库的,所以这个还非测试不可
1.6 修改audio_hw(android声音的HAL层)代码,将UAC声卡接入到android4.0中去
1.7 使用android自带的Music.apk,SoundRecorder.apk进行最后测试,我想这两个过了其它软件应该没问题了吧
2. 各子任务的具体实施
2.1 移植alsa库
将原来android2.3.3/external/alsa-lib,android2.3.3/external/alsa-utils
这两个库cp到 android4.0/external/中 直接编译生成 相应的alsa_aplay,alsa_amixer,alsa_ctl,并cp到目标板子上,
将alsa的配置文件也从android2.3.3 复制到目标板子/system/usr/share/alsa 目录下
具体配置文件为 
./pcm/center_lfe.conf
./pcm/surround40.conf
./pcm/surround50.conf
./pcm/dmix.conf
./pcm/rear.conf
./pcm/front.conf
./pcm/surround71.conf
./pcm/surround51.conf
./pcm/dsnoop.conf
./pcm/dpl.conf
./pcm/default.conf
./pcm/modem.conf
./pcm/side.conf
./pcm/iec958.conf
./pcm/surround41.conf
./alsa.conf
./cards/aliases.conf

adb shell进入目标板
执行alsa_amixer ,alsa_aplay -l 执行成功,到此alsa工具移植成功,这点看来没有太大难度

2.2 打开kernel配置,menuconfig,打开如下配置
========================================================
Device Drivers --->
<*> Sound card support --->
     <*> Advanced Linux Sound Architecture --->
  • USB sound devices ---> 
    <*> USB Audio/MIDI driver
    ========================================================
    重新编译内核,并烧写到目标板子上
    2.3 找一个usb声卡,插入usb端口
    并使用dmesg查看内核日志输出,从dmesg上应该可以看见UAC设备的驱动加载信息
    ls /dev/snd/*
    /dev/snd/pcmC0D0c
    /dev/snd/pcmC0D0p
    /dev/snd/pcmC1D0c //uac capture
    /dev/snd/pcmC1D0p //uac play out

    说明声卡已经加载成功了
    2.4 使用alsa 工具测试
    列出设备
    alsa_aplay -l
    alsa_aplay 001.wav -D default:CARD=USB Set  default:CARD=USB Set是从alsa_aplay -l中列出的设备名
    可正常听到声音
    2.5 使用tinyalsa测试
    # tinyplay -d 1 001.wav //居然提示invalid parameter 只能看代码了


    external/tinyalsa/tinyplay.c
    发现主要问题在于tinyplay只打开了设备0多的设备不理,这点真比alsa库差远了,只能山寨一下了,修改如下红色字体部分


    void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits);


    int main(int argc, char **argv)
    {
        FILE *file;
        struct wav_header header;
        unsigned int device = 0;
              unsigned int card = 0;



        argv += 2;
        while (*argv) {
    if (strcmp(*argv, "-d") == 0) {
                argv++;
                device = atoi(*argv);
                    }
                    if (strcmp(*argv, "-c") == 0) {
                argv++;//命令行多一个 -c 选项,这样可以选择声卡了
                card = atoi(*argv);
                    }
            argv++;
        }


        fread(&header, sizeof(struct wav_header), 1, file);


        if ((header.riff_id != ID_RIFF) ||
            (header.riff_fmt != ID_WAVE) ||
            (header.fmt_id != ID_FMT) ||
            (header.audio_format != FORMAT_PCM) ||
            (header.fmt_sz != 16)) {
            fprintf(stderr, "Error: '%s' is not a PCM riff/wave file\n", argv[1]);
            fclose(file);
            return 1;
        }


        play_sample(file,card, device, header.num_channels, header.sample_rate,
                    header.bits_per_sample);


        fclose(file);


        return 0;
    }
    void play_sample(FILE *file,unsigned int card, unsigned int device, unsigned int channels,
                     unsigned int rate, unsigned int bits)
    {
        struct pcm_config config;
        struct pcm *pcm;
        char *buffer;
        int size;
        int num_read;
    //config 的配置很重要,tinyalsa直接从wav文件把channels,rate,等读出来并配置进声卡,而像我买的7块钱声卡,功能很弱从windows的设备管理器上看,只支持 16000hz, 16bits,2 channels
    //所以我只好录一个 16000hz,16bits,2 channel的001.wav文件了
    //如果config 配置出错,将看到 invalid parameter的错误提示,这点和alsa_aplay的功能 就差远了
        config.channels = channels;
        config.rate = rate;
        config.period_size = 1024;
        config.period_count = 4;
        if (bits == 32)
            config.format = PCM_FORMAT_S32_LE;
        else if (bits == 16)
            config.format = PCM_FORMAT_S16_LE;
        config.start_threshold = 0;
        config.stop_threshold = 0;
        config.silence_threshold = 0;


        pcm = pcm_open(card, device, PCM_OUT, &config);//原来是pcm = pcm_open(0, device, PCM_OUT, &config);
        if (!pcm || !pcm_is_ready(pcm)) {
            fprintf(stderr, "Unable to open PCM device %u (%s)\n",
                    device, pcm_get_error(pcm));
            return;
        }


        size = pcm_get_buffer_size(pcm);
    buffer = malloc(size);
        if (!buffer) {
            fprintf(stderr, "Unable to allocate %d bytes\n", size);
            free(buffer);
            pcm_close(pcm);
            return;
        }


        printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);


        do {
            num_read = fread(buffer, 1, size, file);
            if (num_read > 0) {
                if (pcm_write(pcm, buffer, num_read)) {
                    fprintf(stderr, "Error playing sample\n");
                    break;
                }
            }
        } while (num_read > 0);


        free(buffer);
        pcm_close(pcm);
    }

              按以上修改完文件后重新编译,并执行
    # tinyplay -d 1 001.wav
       成功从UAC听到声音了,看来集成到android HAL只差一步了,因为android HAL也是用的tinyalsa库的


    2.6 修改audio_hw(android声音的HAL层)代码,将UAC声卡接入到android4.0中去
    HAL层代码位置:
    hardware/targetboard目标板/audio/audio_hw.c
    找到 pcm_open(card, port, PCM_OUT,&config); 的地方把相应的config配置成和tinyplay.c里正确的配置
    像我的声卡就是16000hz 16bits,2 channels
    重新编译  生成 audio.primary.$(TARGET_BOARD_PLATFORM).so 并更新到目标板上
    重新 启动 mediaserver进程 (kill掉这个进程,就会自动重启,并重新加载audio.primary.xxx.so库)
    使用android音乐播放,播放mp3,OK可成功听到声音了
    使用android录音机, 可成功录音了


本文转载自:http://armboard.org/forum.php?mod=viewthread&tid=297&extra=page%3D1

共有 人打赏支持
雨焰
粉丝 58
博文 255
码字总数 46691
作品 0
新乡
程序员
私信 提问
在HG255D OpenWrt上安装ShairPort实现无线音乐播放

在HG255D OpenWrt上安装ShairPort实现无线音乐播放 树叶的BLOG2017-12-0311 阅读 安装音乐 概述 ShairPort是一个Airtunes 模拟器,在OpenWrt设备上安装之后,Apple device就可以将设备的音乐...

树叶的BLOG
2017/12/03
0
0
手把手教你修改pcDuino系统默认的音频输出

最近要搞个小玩意儿,要用到pcduino的音频输出,但是系统默认的是输出到hdmi的音频,我的显示器上没有喇叭,只能搞个USB声卡。但是系统默认又不是输出到USB,这里我手把手叫你怎么设置系统默...

pc朵拉
2013/08/27
669
2
KNOPPIX 7.0.4 发布

KNOPPIX是一张可启动光盘,上面收集了一些GNU/Linux软件,并集成了自动硬件识别以及对许多图形显示卡、声卡、SCSI和USB设备以及其 他外围设备的支持。KNOPPIX可以用于Linux演示、教学光盘、应...

oschina
2012/08/27
1K
2
在Debian里不重启切换两块声卡

在电磁干扰严重的狭小空间里,笔记本的内置声卡表现一般比较差,至少我的n600c底噪就很明显。要获得更好的效果或者需要数字输出时只能借助外置声卡了,包括pcmcia接口和usb接口两种,前者如创...

青夜之衫
2017/12/06
0
0
pcDuino 香蕉钢琴

前面我们已经介绍使用TouchkeyUSB Shield在Arduino上实现香蕉钢琴,Arduino是通过模拟USB HID(Human Interface Device)的方法来实现的,而在强大的pcDuino上面直接通过模拟键盘的输入就可以...

酸酸苹果汁
2013/12/24
1K
3

没有更多内容

加载失败,请刷新页面

加载更多

AWS的自动部署工具codedeploy 部署前的准备工作

开始部署codedeploy: 1.先预置IAM用户: 创建一个IAM用户或使用一个与AWS相关联的用户; 复制以下的策略附加到IAM用户,向IAM用户赋予对codedeploy(及codedeploy所依赖的AWS服务和操作)的...

守护-创造
28分钟前
0
0
这可能是最详细的一线大厂Mysql面试题详解了

1、MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联; 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中; 从:io线程——在使用start slave 之后...

Java干货分享
38分钟前
1
0
人的精力是什么?如何强化精力

人的精力是什么? 人的精力是什么? 精力指精神和体力。精神包括一个人的精神状态,兴奋度,做事情的投入度,专注度,持续时间等。 人的精力来源 人的精力有4种来源,身体的、情感的、思想的和...

莫库什勒
57分钟前
2
0
JFinal开发的旅游线路营销Saas平台演示系统我部署了一个

今天部署了一个旅游线路营销管理系统的演示版: 演示地址:http://lvyou.jfinalxueyuan.com 演示账号:(暂时只给一个门店版的吧,批发商和总部的如果需要 演示看看 单独联系我微信:1876673...

山东-小木
今天
2
0
如何学习大数据技术

学习大数据技术,首先要明确大数据的概念。 大数据的概念作者认为有如下几点: 1.数据的来源多样性。例如关系数据库+文本+excel等 2.数据量大。TB级别的数据。 3.业务应用领域。实时性高与实...

董黎明
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部