音乐盒子mplayer问题review

背景:实现全志R16-linux开发板上的mplayer的调试

一、mplayer软件架构:

 

这里详细介绍了alsa的相关知识

二、问题解决1:播放卡顿

0.问题描述:播放过程中会突然发生卡顿,就是感觉声音突然快进了似的。

1.mplayer.c中的调用了fill_audio_out_buffers  这个函数:

这个代码主要是两个while循环:

循环1:while(1)这一部分主要是通过get_space()函数获取需要写的字节数,一直填充,直到其数值大于outburst才停止。这里还根据数据的大小算出sleep的时间,防止占用cpu过多。

循环2:while(bytes_to_write)这个地方根据上面的值进行数据的填充。

 

2.其中调用了get_space()这个函数

这里面调用了很多alsa驱动的函数。

 snd_pcm_status_get_avail 来获取当前驱动缓冲区中可用的帧数。

就是这个函数主要是来从buffer中拿出一个帧的长度,如果buffer不够一针,就拿出那么多,如果超过了一针,那么久取出一针的长度。

1     ret = snd_pcm_status_get_avail(status) * bytes_per_sample;
2     // printf("aaa:buf=%d\n", ao_data.buffersize); // always 88200
3     // printf("aaa:bpS=%d\n", bytes_per_sample); // always 4
4     if (ret > ao_data.buffersize/8){  // Buffer underrun?
5         // printf("aaa:ret\n");
6     ret = ao_data.buffersize; // never
7     }
8     // printf("aaa:getSpace=%d\n", ret); // 88200 when cracking
9     return ret;

音乐播放buffer层次:

三层buffer:应用程序buffer(mplayer使用的buffer)、alsa驱动buffer(ring uffer)、硬件buffer。

数据在这三层buffer中传输,

 

        playsize    = mpctx->audio_out->play(sh_audio->a_out_buffer, playsize, playflags);

这里需要打印一下看看到底每次传的一样吗?

 

问题分析:

猜测:有hw:0,0 只能write 8的倍数的数据,default数据则是随便的,需要实验验证一下。

暂时结论就是,由于每次都是好像跳过了一针,推测是因为写的时候把之前的buffer覆盖了,导致丢帧了。因为没有用HW:0,0导致写的时候不是8的倍数,

解决:扩大buffer,让后面的不能追上前面的。

 

https://blog.csdn.net/kickxxx/article/details/8291598

 

三、问题解决2:播放器有哒哒哒的声音:

下面是开发板开机的一个启动脚本,经过定位发现是加载一个gpio_key的时候会发生哒哒哒的声音。

因为加载的事案件驱动,尝试按了一下案件,发现只要按一下案件,就不会有噪声了。

首先看问题驱动的源码

/mnt/hdd2/scc153/Tina-V2/lichee/linux-3.4/drivers/input/keyboard /

 

1.首先是初始化代码先进这里

 

通过event_rest确定是因为有一个key1 一直在传回event信息。
在lichee/linux/include/linux/input.h 中找到key(1)是KEY_ESC
 
2.问题解决:原来是多设置了一个按键,然后没有删除。我在sun8i.c 中注释掉就好了

 (需要继续看一下源码更新一下)

 

二、问题解决3:音乐采样率和DAC采样率不匹配

void dsp_init(int sample_rate)
{
    int fd;
    int ret;

    //DSP start
    long data = 0;
    fd = open("/dev/gpio_ctl_dsp",O_RDWR);
    if(fd < 0){
        printf("cant't open the dsp device\n");
        return -1;
    }
    switch(sample_rate)
    {
        case 44100:ret = ioctl(fd,SA441K,data);break;
        case 88200:ret = ioctl(fd,SA882K,data);break;
        case 176400:ret = ioctl(fd,SA1764K,data);break;
        case 48000:ret = ioctl(fd,SA48K,data);break;
        case 96000:ret = ioctl(fd,SA96K,data);break;
        case 192000:ret = ioctl(fd,SA192K,data);break;
        default:break;
    }
    if(ret == 0)
    close(fd);
    //DSP end
    
    //DAC start
    char buf[50];
    int regaddr, slaveaddr;
    slaveaddr = 0x10;
    regaddr = 0x00;
    fd = open("/dev/i2c-2",O_RDWR);
    if(fd < 0){
        printf("#########open i2c failed########\n");
        return -1;
    }
    ioctl(fd,I2C_TENBIT,0);
    ioctl(fd,I2C_SLAVE,slaveaddr);
    buf[0] = 0x07;
        buf[1] = 0x12;
        buf[2] = 0x00;
        buf[3] = 0xF9;
        buf[4] = 0xF9;
        buf[5] = 0x00;
        buf[6] = 0x00;
        buf[7] = 0x03;
        buf[8] = 0x01;
        buf[9] = 0x00;
        buf[10] = 0x0D;
        buf[11] = 0x0C;
        buf[12] = 0x00;
        buf[13] = 0x00;
        buf[14] = 0x50;
        buf[15] = 0xFF;
        buf[16] = 0xFF;
    ret = iic_write(fd, buf, regaddr, 17);
    if(ret > 0){
;
    }
    close(fd);
    //DAC end


    return 0;
    
}

 

转载于:https://www.cnblogs.com/ray5wang/p/9557393.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值