设为首页 收藏本站
查看: 948|回复: 0

[经验分享] Linux ALSA音频PCM播放编程

[复制链接]
发表于 2017-11-18 17:41:48 | 显示全部楼层 |阅读模式
  使用ALSA播放两个频率的单音,并使用GNU Radio中的Audio Source和FFT来观测声音的频谱。



#include <alsa/asoundlib.h>
#include <math.h>
#include <inttypes.h>
int main(int argc, char **argv)
{
     long loops;
     snd_pcm_t *handle;
     snd_pcm_hw_params_t *params;
     snd_pcm_uframes_t frames;
     unsigned int val;
     int rc;
     int size;
     int dir;
     char *buffer;

     /* Open PCM device for playback. */
     rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
     if (rc < 0) {
         fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc));
         exit(1);
     }

     /* Allocate a hardware parameters object. */
     snd_pcm_hw_params_alloca(&params);

     /* Fill it in with default values. */
     snd_pcm_hw_params_any(handle, params);

     /* Interleaved mode */
     snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
     /* Signed 16-bit format */
     snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16);
     /* Two channels (stereo) */
     snd_pcm_hw_params_set_channels(handle, params, 2);
     /* 16000 samples/second sampling rate */
     val = 16000;
     snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
     /* Set period size to 32 frames. */
     frames = 32;
     snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);

     /* Write the parameters to the driver */
     rc = snd_pcm_hw_params(handle, params);
     if (rc < 0) {
         fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));
         exit(1);
     }

     /* Use a buffer large enough to hold one period */
     snd_pcm_hw_params_get_period_size(params, &frames, &dir);

     size = frames * 2 * 2; /* 2 bytes/sample, 2 channels */
     buffer = (char *) malloc(size);
     if(buffer == NULL) {
         fprintf(stderr, "Not enough Memory!\n");
         exit(1);
     }

     /* We want to loop for 15 seconds */
     snd_pcm_hw_params_get_period_time(params, &val, &dir);

     /* 15 seconds in microseconds divided by period time */
     loops = 15000000 / val;

     for (size_t i = 0; i < size; i += 4) {
         // Generate a 500Hz tone
         *((int16_t *)(buffer + i)) = (uint16_t)(16384.0*sin(i*2.0*M_PI/size));
         *((int16_t *)(buffer + i + 2)) = (uint16_t)(16384.0*sin(i*2.0*M_PI/size));
         // Generate a 2kHz tone
         *((int16_t *)(buffer + i)) += (uint16_t)(16384.0*sin(i*8.0*M_PI/size));
         *((int16_t *)(buffer + i + 2)) += (uint16_t)(16384.0*sin(i*8.0*M_PI/size));
     }

     while (loops > 0) {
         loops--;
         //rc = read(0, buffer, size);
         //if (rc == 0) {
         //    fprintf(stderr, "end of file on input\n");
         //    break;
         //} else if (rc != size) {
         //    fprintf(stderr, "short read: read %d bytes\n", rc);
         //}
         rc = snd_pcm_writei(handle, buffer, frames);
         if (rc == -EPIPE) {
             /* EPIPE means underrun */
             fprintf(stderr, "underrun occurred\n");
             snd_pcm_prepare(handle);
         } else if (rc < 0) {
             fprintf(stderr,"error from writei: %s\n", snd_strerror(rc));
         } else if (rc != (int)frames) {
             fprintf(stderr,"short write, write %d frames\n", rc);
         }
     }
     snd_pcm_drop(handle);
     snd_pcm_drain(handle);
     snd_pcm_close(handle);
     free(buffer);
     return 0;
}
DSC0000.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408299-1-1.html 上篇帖子: linux运维、架构之路-Zabbix监控 下篇帖子: 【每天一个linux命令】grep
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表