荥阳市 松滋市 宣恩县 丰台区 广东省 周至县 赤城县 浮山县 汪清县 慈利县 松溪县 长宁区 锡林郭勒盟 滨州市 齐齐哈尔市 姜堰市

文章导航软件下载单机游戏安卓资源苹果资源

pc软件新闻网络操作系统办公工具编程服务器软件评测

安卓新闻资讯应用教程刷机教程安卓游戏攻略tv资讯深度阅读综合安卓评测

苹果ios资讯苹果手机越狱备份教程美化教程ios软件教程mac教程

单机游戏角色扮演即时战略动作射击棋牌游戏体育竞技模拟经营其它游戏游戏工具

网游cf活动dnf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动新游预告手游问答

您的位置:单机游戏角色扮演 → 怪物猎人世界新装备介绍 怪物猎人世界新装备新系统一览

大话西游之月光宝盒_基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(三)

标签:输变电 斗地主 不联网

作品已经完成,先上源码:

https://files.cnblogs.com/files/qzrzq1/WIFISpeaker.zip

全文包含三篇,这是第三篇,主要讲述接收端程序的原理和过英国达人秀_2018年最新新闻网程。

第一篇:基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(一)

第二篇:基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(二)

以下是正文:

  在进行接收端程序开发前,首先要了解Orangpi Zero的声音设备。

  Orangpi可以通过ALSA(The Advanced Linux Sound Architecture )访问系统的声音设备。

一、查找并确定Orangpi Zero的声音设备

  要使用ALSA,首先就是要能正确找到声音设备,作者在使用alsa的时候,尝试过使用armbian官网(链接地址)上三个不同的镜像,发现有些armbian镜像有问题,不知道是什么原因,分别是:

  (1)、基于Ubuntu Xenial的Armbian镜像,版本号3.4.113(下载地址)

  (2)、基于Ubuntu Xenial的Armbian镜像,版本号4.14.14(下载地址)

  (3)、基于Debian Stretch的Armbian镜像,版本号4.14.14(下载地址)

  这三个镜像中,只有第一个能找到声卡设备,其他两个都提示无声卡设备。作者只能使用第一个镜像。

  在armbian中,使用以下命令即可看到声卡设备。

aplay -l

  如上图所示,在OrangePi Zero中,共有两个声卡设备,一个card0是audiocodec,指的是板载的TV接口,另一个card1是sndhdmi,指的是HDMI输出接口,其中card0是默认声卡设备,因为TV接口在开发板上有直接引出,而且只需3线(左声道、右声道、地),本作品直接使用TV接口作为音频输出。硬件电路如图如下所示。

  如果使用aplay命令显示出来的card0不是我们想要的默认声卡设备,那就要进行更改了,更改方法可以参考“linux alsa音频架构的配置与使用”这个文章。

  此外,alsa还有一个虚拟的配置界面,alsamixer,利用它可以方便的设置声卡音量、配置声卡、静音等功能,类似windows桌面右下角的声音管理器。要打开alsamixer,直接使用alsamixer命令即可,具体的使用方法,可以参考“Linux下的音量控制器alsamixer”这篇文章,界面如下图所示。

alsamixer

  设置之后,利用aplay命令测试一下能否播放音乐,如果TV接口播放音频正常,接下来就可以开始接收端的程序开发了。

#播放测试音乐
aplay test.wav

  测试alsa正常后,接下来介绍接收端程序中需要使用到的socketpyalsaaduio模块。

二、socket模块

  socket模块使用比较简单,首先获取本机IP,然后初始化socket为UDP模式,并绑定IP地址和端口号,就可以开始接受数据包了。主要涉及的函数包括:

#创建socket
socket.socket([family[, type[, proto]]])

#连接远程地址
socket.connect(address)

#绑定socket的IP地址和端口号
socket.bind(address)

#从socket接收数据包
socket.recvfrom(bufsize[, flags])

#关闭socket
socket.close()

  socket模块的使用比较简单,网上有很多范例,这里不再详细说明。

三、pyalsaaudio模块

  pyalsaaudio(下载地址)是一个用于python中访问ALSA API的模块,利用这个模块,用户可以很轻松的在程序中访问Orangpi Zero的PCM和混音器设备,这个模块的使用说明和范例在这个链接地址里有。

  1、安装pyalsaaudio模块

  依次安装python对应版本的setuptools、python-dev、libasoud2-dev和pyalsaaudio包即可。其中python-dev包与所使用的python版本有关,可以使用python3 -V命令查看python版本,本作品armbian系统预装了python3.5,所以要安装python3.5-dev包。依次执行以下命令。

  (1)、安装python3-setuptools命令:

apt-get install python3-setuptools

  (2)、安装python3.5-dev命令:

apt-get install python3.5-dev

  (3)、安装libasoud2-dev命令:

apt-get install libasound2-dev

  (4)最后,使用python的pip3命令安装pyalsaaudio模块:

pip3 install pyalsaaudio

  (5)上一步中的pip3命令,是为了与python2区分的,armbian中预安装了python2和python3,作者使用的是python3,如果直接使用pip命令,系统就会给python2安装pyalsaaudio模块了,所以这里需要注意。如果提示没有pip3命令,那就需要使用以下命令安装pip3。安装之后就可以使用pip3命令操作第4步了。

apt-get install python3-pip

四、接收端程序设计

 东方直播室_2018年最新新闻网 接收端比较简单,在Python环境下直接使用socket和pyalsaaudio模块即可快速实现数据包的接收和播放,主要使用的pyalsaaudio模块函数如下。

#默认的构造函数
#系统初始化alsa device,系统默认按以下参数配置:PCM、44.1kHz、双通道、周期大小32帧
#Sample format: PCM_FORMAT_S16_LE
#Rate: 44100 Hz
#Channels: 2
#Period size: 32 frames
class alsaaudio.PCM(type=PCM_PLAYBACK, mode=PCM_NORMAL, device="default", cardindex=-1)

#设置采样率,以Hz为单位。
#典型值是8000(电话)、16000、44100(CD音质)、48000(DVD音质)、96000
PCM.setrate(rate)

#设置周期大小,用户程序每次处理音频数据的帧数,
#即用户程序每次要写入(播放)/读取(录音)的数据大小
#以帧为单位,一帧就是一次采样的字节数
PCM.setperiodsize(period)

#写入待播放的音频数据。
#data的数据长度必须是帧大小的整数倍, 并且等于周期大小。
#如果小于周期大小,则实际不会播放,直到程序把数据按照周期大小完全写入。
PCM.write(data)

  在《基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(二)》中,作者设定了发送来的数据包前40个字节为识别数据格式的包头,真正的音频数据是从第41字节开始。包头数据的40个字节,实际就是C里的WAVEFORMATEX结构体,包含采样率、通道数、位深度信息,在python中,需要对这个结构体(数据包的开始的40字节)的数据进行解析读取,这样,才能正确设置pyalsaaudio的PCM类对象。

  要实现上述功能,在C里,可以直接把数据包首地址强制转换成WAVEFORMATEX结构体类型的指针,再访问各个成员变量即可,可是在python里,没有地址和指针的概念,需要使用struct模块中的pack和unpack函数。

  struct模块的pcak和unpcak函数是用来处理C结构数据的,通过它们可以实现对字节数组的解释。例如WAVEFORMATEX结构体的第2~3字节(以0开始)为通道数,第4~7字节为采样率,unpack函数可以把这些字节数组按照设定的要求进行转换。两个函数的详细用法,可以参考“Python中struct.pack()和struct.unpack()用法详细说明”这篇文章。

  最后,接收端程序设计的流程和源码如下:

  1、初始化socket

  2、初始化PCM类对象

  3、从socket接受数据(阻塞式)

  4、解释数据包头

  5、每隔1s判断数据包头指定的格式跟当前格式是否一致,如果不一致,则关闭PCM类对象并重新初始化

  6、播放从第41字节开始的音频数据

  注意:程序中音频格式只做了对采样率的判断,没对位深度、通道数等信息的判断,有兴趣的读者可以自行添加。

import socket
import alsaaudio
import struct
import time

#函数:获取IP地址
def GetHostIP():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("1.1.1.1", 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip


#以下是主程序
RecCount = 0
#默认的PCM音频格式,参考C里面的WAVEFORMATEX结构体
#格式标识wFormatTag = 0xfe
#通道数nChannels    = 2
#采样率nSamplesPerSec  = 48000Hz
#波特率nAvgBytesPerSec = 192000
#块对齐nBlockAlign     = 4
#位深度wBitsPerSample  = 16
list_pwfx = [65534, 2, 48000, 192000, 4, 16]

Local_IP=GetHostIP()
print("说明")
print("1.本机ip:%s:12321"%(Local_IP))
print("2.默认按照48000Hz、双通道、16位PCM格式播放")
print("3.发送端发出的数据包前40个字节为音频格式信息,接收端(本程序)每隔1s会解释一次包头,读取并自动修改播放器采样率信息(如发生变化)")
print("4.注意:接收端(本程序)只支持11025、12000、44100、48000这4种采样率的自动切换,不支持修改通道数、位深度等其他信息的切换。")
print("5.发送端如果在后台(如Windows的音频管理器)修改了采样率,必须重新点击‘启动’按钮,才能重新发生正确的音频流")

#初始化socket
sss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sss.bind((Local_IP, 12321))

#系统初始化alsa device,系统默认按以下参数配置
#Sample format: PCM_FORMAT_S16_LE
#Rate: 44100 Hz
#Channels: 2
#Period size: 32 frames
device = alsaaudio.PCM()

#修改默认采样率为48kHz
device.setrate(list_pwfx[2])
#修改缓冲区大小(以帧为单位,0.1s是4800帧)
device.setperiodsize(list_pwfx[2]//10)

Lasttime =time.time()

while 1:

    #申请20k字节缓冲区
    BytesRecv,ServerAddr = sss.recvfrom(20000)

    #这里是为了让程序自动更改播放音频的采样率,如果距离上次设置采样率的时刻大于1s,
    #则读取数据包的头40个字节,判断服务尸鬼_2018年最新新闻网器传过来的数据采样率有无变化,重新设置采样率,
    #只支持在11025、12000、44100和48000间切换
    Nowtime = time.time()
    if (Nowtime-Lasttime) > 1 :
        
        Lasttime = Nowtime

        #解释包头(只取前16字节),具体请参考C里面的WAVEFORMATEX结构体或文件开头的说明
    朝鲜氢弹试验成功_2018年最新新闻网    #注意struct.unpac虎皮鹦鹉_2018年最新新闻网k返回值是一个元组
        tuple_pwfx_temp = struct.unpack("HHLLHH",BytesRecv[:16])
        #print(tuple_pwfx_temp)
        if tuple_pwfx_temp[2] != list_pwfx[2]:
            print("采样率发生变化!")
            if tuple_pwfx_temp[2] in [11025,1多普达_2018年最新新闻网2000,44100,48000]:
                #把元组转换为列表,再赋值修改采样率
                list_pwfx[2] =list(tuple_pwfx_temp)[2]

                #关闭设备并重新初始化设备
                device.close()
                device = alsaaudio.PCM()
                device.setrate(list_pwfx[2])
                device.setperiodsize(list_pwfx[2]//10)
                
                print("采样率正确,修改采样率为%s"%(list_pwfx[2]))
            else:
                print("采样率错误!"%(list_pwfx[2]))
                
    #将socket接收到的数据送到device播放
    #收到的数据包,第41字节开始才是音频数据
    device.write(BytesRecv[40:])

    print("RecCount=%s"%(RecCount),end="
")
    RecCount+=1

device.close()
sss.close()

  同时运行发送端程序和接收端程序,在发送端打开音乐播放器,这个时候,OrangPi接的音箱应该能播放音乐了。

五、设置python脚本开机自启动

  好了,最后一步就是把这个python脚本设定成开机自启动,这样就不用每次登录OrangPi Zero运行这个脚本,linux下实现python脚本开机自动启动的方法也简单,“Linux下Python脚本自启动与定时任务详解”这个文章有详细介绍,修改一下系统配置文件即可。

当前文章:http://8lj1-juhoutai-com.xingmaps.cn/yfjb3llfo/89fcd_155024.html

发布时间:2019-10-20 08:23:50

澳门银河手机网站  2288银河主站线路检测足协高层参加亚洲杯抽签仪式 物色国足热身对手  919银河优越会  银河优越会会员申请  澳门银河官网yh163am.com  两劫匪劫持女子敲诈300万 开保时捷飞奔逃窜被围堵  银河国际中心游戏厅  银河优越会会员申请  澳门银河官网yh163am.com  澳门银河娱乐yh163am.com  

相关阅读 仙剑又双叒叕出手游了,西山居制作腾讯代理《仙剑四》《堡垒之夜》被批垄断竞争?负责人:所有人都在受益传微软将公布新《光环》和新《战争机器》等游戏小米MIUI 10红米系列可升级机型汇总:红米Note 3也能升级京东/苏宁自营&斐讯商城0元购:智能音箱R1直降110元,K3+H1抢赚200元《LOL》美测服更新:装备图标更新,“青龙偃月刀”加入趁你病要你命 投资者趁抛售潮大举做空三星电子美女声优水濑祈自曝黑历史 “幻之黑肉妹”很吓人

文章评论
发表评论

热门文章 全面屏系统!小米MIUI 10内测版/体验版开始推送知中国、看世界,“新成长计划”启动仪式在京举行[??]????,??? ???屌丝逆袭网友终成眷属?《劲舞团》电影获得拍摄许可

最新文章 补充21种维生素及矿物质,善存佳维片150+60片119元新低(70元券)城乡居民基础养老金最低标准增至每月88元 三年来最大规模国考补录:1.2万余人“捡漏”进面试滴滴回应“空姐遇害案”救援队索要百万赏金:需有警方证据福建连江鲍鱼全国首次制定产品标准 国内尚属首次又到杏黄枝头的季节 酸甜爽口吃起来

人气排行 3699元小米8透明探索版发布:加持屏幕指纹、Face ID古巴坠机事故致100余人遇难 3名幸存者被送医治疗大人物的小秘密之哈登(答案)卡普空再续《深坑》商标,又一款E3的惊喜?广工大MBA注重基础 打造华南最优质教育品牌公务员考试天价培训现象泛滥 背后或存权钱交易重磅来袭!Facebook确认首次参展ChinaJoyBTOB!手机流量不限套餐遭吐槽:“不限量”字很大,“限速”很难找