WiFi Wireless speaker based on Orangpi Zero and Linux ALSA (iii)

Source: Internet
Author: User
Tags get ip pack unpack python script

Work has been completed, first on the source:

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

The full text contains three articles, this is the third chapter, mainly on the receiving end program principles and procedures.

First article: Implement WiFi Wireless speaker based on Orangpi Zero and Linux alsa (i)

Second article: Based on ORANGPI Zero and Linux alsa to implement WiFi wireless speaker (ii)

The following is the text:

Before the development of the receiving terminal program, we must first understand the ORANGPI zero sound device.

The ORANGPI can access the system's sound devices through ALSA (the Advanced Linux voice Architecture).

First, find and determine the ORANGPI zero sound device

To use ALSA, the first is to be able to correctly find the sound device, the author in the use of ALSA, tried to use the Armbian official website (link address) on the three different images, found some Armbian mirror has a problem, do not know what reason, respectively:

(1), Ubuntu xenial-based Armbian image, version number 3.4.113 ()

(2), Ubuntu xenial-based Armbian image, version number 4.14.14 ()

(3), Armbian image based on Debian stretch, version number 4.14.14 ()

Of these three images, only the first one can find the sound card device, the other two prompts the silent card device. The author can only use the first image.

In Armbian, use the following command to see your sound card device.

Aplay-l

As shown in Orangepi Zero, there are two sound card devices, one card0 is Audiocodec, refers to the onboard TV interface, the other card1 is SNDHDMI, refers to the HDMI output interface, where card0 is the default sound card device , because the TV interface on the Development Board has a direct lead, and only 3 lines (left channel, right channel, ground), this work directly using the TV interface as audio output. The hardware circuit is shown below.

If you use the Aplay command to display the CARD0 is not the default sound card device we want, it will be changed, the change method can refer to the "Linux ALSA Audio architecture configuration and use" this article.

In addition, ALSA also has a virtual configuration interface, Alsamixer, it can easily set the sound card volume, configure sound card, mute and other functions, similar to the right corner of the Windows Desktop Sound Manager. To open alsamixer, directly using the Alsamixer command, the specific use of the method, you can refer to the "Linux Volume Controller Alsamixer" This article, the interface as shown.

Alsamixer

After setting, use the Aplay command to test if the music can be played, if the TV interface plays audio properly, then you can start the program development of the receiving end.

# Play test music Aplay test.wav

After the test alsa is normal, the socket and Pyalsaaduio modules that need to be used in the receive-side program are described next.

Second, Socket module

The socket module is relatively simple to use, first get the native IP, and then initialize the socket to UDP mode, and bind the IP address and port number, you can begin to accept the packet. The main functions involved include:

# Create socket Socket.socket ([family[, type[, Proto]]) # Connect Remote Address Socket.connect (address) # bind the socket's IP address and port number Socket.bind (address) # receiving packets from the socket Socket.recvfrom (bufsize[, flags]) # Close Socketsocket.close ()

The use of the socket module is relatively simple, there are many examples on the internet, which is no longer described in detail.

Three, Pyalsaaudio module

Pyalsaaudio () is a module for accessing the ALSA API in Python, which makes it easy for users to access ORANGPI zero PCM and mixer devices in the program, with instructions and examples for the use of this module in the link address.

  1. Installing the Pyalsaaudio module

Install Python's corresponding version of Setuptools, Python-dev, Libasoud2-dev, and Pyalsaaudio packages in turn. Where the Python-dev package is related to the Python version used, you can use the PYTHON3-V command to view the Python version, the Armbian system is preloaded with python3.5, so the Python3.5-dev package is installed. Execute the following command in turn.

(1), install Python3-setuptools command:

Apt-get Install Python3-setuptools

(2), install Python3.5-dev command:

Apt-get Install Python3.5-dev

(3), install Libasoud2-dev command:

Apt-get Install Libasound2-dev

(4) Finally, install the Pyalsaaudio module using the python PIP3 command:

PIP3 Install Pyalsaaudio

(5) The PIP3 command in the previous step is for the purpose of distinguishing python2 from the Armbian, Python2 and Python3 are pre-installed, and the author uses Python3, if the PIP command is used directly, The system will install the Pyalsaaudio module for Python2, so you need to pay attention here. If you are prompted without the PIP3 command, you need to install PIP3 using the following command. After installation, you can use the PIP3 command to operate the 4th step.

Apt-get Install Python3-pip

Four, the receiver terminal design

Receiver is relatively simple, in the Python environment directly using the socket and the Pyalsaaudio module can quickly achieve packet reception and playback, the main use of the Pyalsaaudio module functions are as follows.

#the default constructor#the system initializes the ALSA device, which is configured by default in the following parameters: PCM, 44.1kHz, dual channel, cycle size 32 frames#Sample Format:pcm_format_s16_le#rate:44100 Hz#Channels:2#Period size:32 FramesclassAlsaaudio. PCM (Type=pcm_playback, Mode=pcm_normal, device='default', Cardindex=-1)#sets the sample rate, in Hz. #Typical values are 8000 (phone), 16000, 44100 (CD quality), 48000 (DVD sound quality), 96000pcm.setrate (Rate)#set the period size, the number of frames each time the user program processes audio data,#that is, the data size of the user program to write (play)/read (record) each time#in frames, one frame is the number of bytes sampled at a timepcm.setperiodsize (period)#writes the audio data to be played. #The data length must be an integer multiple of the frame size and equal to the period size. #if it is less than the cycle size, it will not actually play until the program writes the data exactly as the cycle size. Pcm.write (data)

In the ORANGPI zero and Linux ALSA to achieve WiFi wireless speaker (ii), the author set the packet sent to the first 40 bytes to identify the data format of the packet header, the real audio data from the 41st byte start. Baotou Data 40 bytes, is actually the C WAVEFORMATEX structure, contains the sample rate, the number of channels, bit depth information, in Python, the structure (the beginning of the packet's 40 bytes) to parse the data read, so, To correctly set the Pyalsaaudio PCM class object.

To achieve the above function, in C, you can directly convert the header address of the packet to WaveFormatEx struct type pointer, and then access the individual member variables, but in Python, there is no concept of address and pointers, you need to use the pack and unpack function in the struct module.

The Pcak and Unpcak functions of a struct module are used to process C-structured data, which enables the interpretation of byte arrays. For example, the 2nd to 3rd byte of the WaveFormatEx struct (starting at 0) is the number of channels, and the 4th to 7th byte is the sample rate, and the unpack function can convert these byte arrays according to the set requirements. For a detailed usage of two functions, refer to the "Python Struct.pack () and Struct.unpack () usage Details" article.

Finally, the process and source code of the receiving terminal program design are as follows:

1. Initialize socket

2. Initialize the PCM class object

3. Accept data from socket (blocked)

4. Interpreting the data header

5, every 1s to determine the data header specified format is consistent with the current format, if inconsistent, close the PCM class object and re-initialize

6. Play audio data starting from the 41st byte

Note: The audio format of the program only makes the judgment of the sampling rate, the information such as bit depth and number of channels is not judged, and interested readers can add their own.

ImportSocketImportAlsaaudioImportstructImport Time#function: Get IP addressdefGethostip ():Try: S=Socket.socket (socket.af_inet, socket. SOCK_DGRAM) S.connect (('1.1.1.1', 80)) IP=s.getsockname () [0]finally: S.close ()returnIP#The following is the main programRecCount =0#The default PCM audio format, refer to C inside the WAVEFORMATEX structure body#format id wformattag = 0xFE#number of channels Nchannels = 2#sample Rate nsamplespersec = 48000Hz#baud Rate navgbytespersec = 192000#block Alignment nblockalign = 4#bit Depth wbitspersample =LIST_PWFX = [65534, 2, 48000, 192000, 4, 16]local_ip=Gethostip ()Print('Description')Print('1. Native ip:%s:12321'%(LOCAL_IP))Print('2. Default in 48000Hz, dual-channel, 16-bit PCM format playback')Print('3. The first 40 bytes of the packet sent by the sender are audio format information, the receiving end (this program) will interpret the packet header every 1s, read and automatically modify the Player sample rate information (such as changes)')Print('4. Note: The receiving end (this program) only supports 11025, 12000, 44100, 48000 of these 4 sampling rate automatic switching, does not support the modification of the channel number, bit depth and other information switching. ')Print('5. Sender If you modify the sample rate in the background (such as the Audio manager of Windows), you must re-click the ' Start ' button to re-occur the correct audio stream')#Initialize SocketSSS =Socket.socket (Socket.af_inet,socket. SOCK_DGRAM) Sss.bind (LOCAL_IP,12321))#the system initializes the ALSA device, which is configured by default by the following parameters#Sample Format:pcm_format_s16_le#rate:44100 Hz#Channels:2#Period size:32 Framesdevice =Alsaaudio. PCM ()#Modify the default sample rate to 48kHzDevice.setrate (list_pwfx[2])#Modify the buffer size (in frames, 0.1s is 4800 frames)Device.setperiodsize (LIST_PWFX[2]//10) Lasttime=time.time () while1:    #request a 20k byte bufferBYTESRECV,SERVERADDR = Sss.recvfrom (20000)    #This is to allow the program to automatically change the sample rate of the playback audio, if the distance from the last time set sampling rate is greater than 1s,    #Read the first 40 bytes of the packet, determine whether the data sample rate of the server has changed, reset the sampling rate,    #only supports switching between 11025, 12000, 44100 and 48000Nowtime =time.time ()if(nowtime-lasttime) > 1: Lasttime=Nowtime#explain Baotou (take the first 16 bytes), please refer to C WAVEFORMATEX structure or the description of the beginning of the file        #Note The Struct.unpack return value is a tupleTuple_pwfx_temp = Struct.unpack ('hhllhh', bytesrecv[:16])        #print (tuple_pwfx_temp)        ifTUPLE_PWFX_TEMP[2]! = list_pwfx[2]:            Print('Sample Rate Changes! ')            ifTUPLE_PWFX_TEMP[2]inch[11025,12000,44100,48000]:                #convert a tuple to a list, and then assign a value to modify the sample rateLIST_PWFX[2] =list (tuple_pwfx_temp) [2]                #turn off the device and reinitialize the devicedevice.close () device=Alsaaudio. PCM () device.setrate (list_pwfx[2]) device.setperiodsize (list_pwfx[2]//10)                                Print('sample rate correct, modified sample rate is%s'% (list_pwfx[2]))            Else:                Print('Sample Rate Error! '% (list_pwfx[2]))                    #send data received by the socket to device playback    #received packets, the 41st byte is the beginning of the audio dataDevice.write (bytesrecv[40:]) Print('reccount=%s'% (RecCount), end='\ r') RecCount+=1device.close () sss.close ( )

At the same time running the sender program and the receiving Terminal program, open the music player on the sending side, this time, the ORANGPI speaker should be able to play music.

V. Set up a Python script to boot from

OK, the last step is to set this Python script to boot, so that you do not have to run the script every time ORANGPI zero, Linux implementation of the Python script boot automatically start the method is also simple, "Linux under the Python script self-launch and the timing of the task detailed "This article is described in detail, modify the system configuration file can be."

WiFi Wireless speaker based on Orangpi Zero and Linux ALSA (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.