zoukankan      html  css  js  c++  java
  • linux dsp 播放音频文件

    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <linux/soundcard.h>
    /* 下面的三个参数是跟具体文件相关
     * cmd: file 音频文件
     * [file pass.wav] =>> pass.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 44100 Hz
     *  1. 16位
     *  2. mono为当声道=1, Stereo为立体声=2
     *  3. 44100HZ为频率这个大家都知道,及一秒钟采集或者播放音频的bit数量。
     */
    #define RATE 44100
    #define SIZE 16
    #define CHANNELS 1  // 1表示单声道,2为立体/* 缓冲区 */
    unsigned char buff[RATE * SIZE * CHANNELS / 8]; //buff里面正好放一秒钟的音频
    
    int main()
    {
        int fd;
        int wavfd; /* wav文件的描述符 */
        int arg;   /* ioctl参数 */
        int ret;   /* 返回值 */
        /* 打开dsp音频设备 */
        fd = open("/dev/dsp", O_WRONLY);
        if (fd < 0) {
            printf("open of /dev/dsp failed");
            exit(1);
        }
        wavfd = open("pass.wav",O_RDONLY);
        if (wavfd < 0) {
            printf("open of wav failed");
            close(fd);
            exit(1);
        }
    
        /* 设置bit */
        arg = SIZE;
        ret = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
        if (ret == -1)
             perror("SOUND_PCM_WRITE_BITS ioctl failed");
        if (arg != SIZE)
             perror("unable to set sample size");
    
        /* 设置channels */
        arg = CHANNELS;
        ret = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
        if (ret == -1)
            perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
        if (arg != CHANNELS)
            perror("unable to set number of channels");
    
        /* 设置rate */
        arg = RATE;
        ret = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
        if (ret == -1)
            perror("SOUND_PCM_WRITE_WRITE ioctl failed");
    
        /* 从wav文件中读buff大小的内容,然后写入/dev/dsp中,直到文件结束 */
      /* Q:这里我试验时播放了两次,不知道啥情况,如果大家也遇到了请指教。*/
        while ((ret = read(wavfd, buff, sizeof(buff))) > 0) {
            //printf("read size = %d
    ", ret);
            write(fd, buff, sizeof(buff));
            /* 下面的代码用于在更改播放文件的参数时,播放掉缓冲区内的内容 */
            ret = ioctl(fd, SOUND_PCM_SYNC, 0);
            if (ret == -1)
                perror("SOUND_PCM_SYNC ioctl failed");
        }
    
        close(fd);
        close(wavfd);
    }
    
    
    下面是封装的接口可以直接拿过来使用:
    
    void play_audio(int rate, int bits, int channels, char *filename)
    {
        int fd;
        int wavfd; /* wav文件的描述符 */
        int arg;   /* ioctl arg */
        int ret;   /* return value */
    
        unsigned char buff[rate * bits * channels / 8]; //buff里面正好放一秒钟的音频
        /* open device */
        fd = open("/dev/dsp", O_WRONLY);
        if (fd < 0) {
            printf("open of /dev/dsp failed");
            exit(1);
        }
        wavfd = open(filename, O_RDONLY);
        if (wavfd < 0) {
            printf("open of wav failed");
            close(fd);
            exit(1);
        }
    
        /* set bits */
        arg = bits;
        ret = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
        if (ret == -1)
             perror("SOUND_PCM_WRITE_BITS ioctl failed");
        if (arg != SIZE)
             perror("unable to set sample size");
    
        /* set channels */
        arg = channels;
        ret = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
        if (ret == -1)
            perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
        if (arg != CHANNELS)
            perror("unable to set number of channels");
    
        /* set rate */
        arg = rate;
        ret = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
        if (ret == -1)
            perror("SOUND_PCM_WRITE_WRITE ioctl failed");
    
        /* 从wav文件中读buff大小的内容,然后写入/dev/dsp中,直到文件结束 */
        while ((ret = read(wavfd, buff, sizeof(buff))) > 0) {
            printf("read size = %d
    ", ret);
            write(fd, buff, sizeof(buff));
            /* 下面的代码用于在更改播放文件的参数时,播放掉缓冲区内的内容 */
            ret = ioctl(fd, SOUND_PCM_SYNC, 0);
            if (ret == -1)
                perror("SOUND_PCM_SYNC ioctl failed");
        }
    
        close(fd);
        close(wavfd);
    }
  • 相关阅读:
    EOS 数据库RAM使用量的计算
    EOS require_auth函数
    EOS测试链智能合约部署调用
    安装EOS合约工具eosio.cdt
    Linux Ubuntu下搭建Flutter桌面环境
    VMware虚拟机与物理机共享文件的方法总结
    虚拟机macOS Mojave10.14安装XCode10.1
    VMware14 安装 macOS Mojave教程
    VMware 14安装OS X10.11
    Mac OS虚拟机安装VMware Tools的方法
  • 原文地址:https://www.cnblogs.com/Daniel-G/p/3987229.html
Copyright © 2011-2022 走看看