【鼎革‧革鼎】︰ Raspbian Stretch 《六之 H.3下 》

在 Raspbian 的世界裡,一切都是『檔案』。這是真的嗎?從古早的 Unix 系統開始,就用著一種『統一』unified 的觀點來看待檔案。假如說 『程式』是執行檔很好了解,可是講到『硬體裝置』不過是特殊檔呢?這得從兩個方面來理解。首先抽象上來說,各種硬體設備可以分類成『輸入』裝置、『輸出』裝置和『輸出入』裝置。這些裝置,要嘛一個一個的作出入 ── 比如鍵盤一按輸入一個字元;滑鼠一動從一點移動到另一點 ── ;要不就一塊一塊的來讀寫 ── 就像硬碟一讀一個磁區,SD 卡一寫一個區塊。所以又被劃成了『字元』和『區塊』兩類。另一方面從操作共性上來講,檔案是可讀可寫的,可以一個一個字元的讀寫,也可以一區塊一區塊的讀寫,那為什麼不能表示不同的裝置呢?Why not!  就這樣裝置成了『特殊檔案』──裝置檔了,一般放在 Linux 檔案系統  /dev 目錄下。難道真的所有裝置都是這樣的嗎?事實上,上網用的乙太網路裝置,並不放在 /dev 目錄下,而被放在 /proc/net 目錄之下。原因正由於前面提到的『操作共性 』這一個非常重要的『類化』原則 ── 如何『比類相宜』。就像 python 的鴨子上說的一樣︰

當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子, 那麼這隻鳥就可以被稱為鴨子。

─── 《都是檔案惹的禍?

 

若講古早 Unix 之『硬體裝置檔案說』是理解 ALSA 全域觀的重要關鍵

Global view of ALSA config file framework, executive summary

The alsa-lib package (at least on Debian libasound2-data 1.0.27) provides the /usr/share/alsa/alsa.conf file as the main entry point. That file is responsible for including the full list of potential .asoundrc-format-type files on the system. It contains a reference to the ALSA “DATADIR” (Debian: /usr/share/alsa/). It continues by loading the DATADIR’s cards/aliases.conf file: that one defines translation mappings from the kernel driver’s sound card name (as listed at /proc/asound/cards, or aplay -Ll) to a “more detailed” description string. That “more detailed name” of a sound card then gets used to lookup a corresponding card-specific config file at DATADIR/cards/CARD.conf. And THAT card-specific file then attempts to provide a maximally elegant sound setup for its specific card brand, by compensating for various limitations of cards (e.g. use dmix to combat single-stream playback only, or stereo downmix to lessen a mono-output-only restriction). Finally (to support those cases where the standard setup of a soundcard is deficient/lacking, or custom plugin setup is desired), alsa.conf loads a system-global custom settings file /etc/asound.conf and a per-user custom settings file ~/.asoundrc.

So, the objective should be to achieve having the common alsa-lib configuration file framework enhanced by default in the best possible manner for each specific soundcard brand, to avoid the need of creating manually customized config files in all standard cases.

With this global overview done and cared for, let’s have a look at the actual configuration format of alsa-lib files.

……

 

,恐怕令人難以置信!

何妨仔細讀讀 alsa.conf 文本︰

pi@raspberrypi:~ more /usr/share/alsa/alsa.conf # #  ALSA library configuration file #  # pre-load the configuration files  @hooks [ 	{ 		func load 		files [ 			{ 				@func concat 				strings [ 					{ @func datadir } 					"/alsa.conf.d/" 				] 			} 			"/etc/asound.conf" 			"~/.asoundrc" 		] 		errors false 	} ] --More--(2%) </pre>    <span style="color: #666699;">想想只有兩塊聲卡︰</span> <pre class="lang:default decode:true">pi@raspberrypi:~ cat /proc/asound/cards
 0 [ALSA           ]: bcm2835 - bcm2835 ALSA
                      bcm2835 ALSA
 1 [seeed4micvoicec]: seeed-4mic-voic - seeed-4mic-voicecard
                      seeed-4mic-voicecard

 

那麼多的錄、放裝置打哪來呢?

pi@raspberrypi:~ aplay -L null     Discard all samples (playback) or generate zero samples (capture) playback dmixed ac108 default sysdefault:CARD=ALSA     bcm2835 ALSA, bcm2835 ALSA     Default Audio Device dmix:CARD=ALSA,DEV=0     bcm2835 ALSA, bcm2835 ALSA     Direct sample mixing device dmix:CARD=ALSA,DEV=1     bcm2835 ALSA, bcm2835 IEC958/HDMI     Direct sample mixing device dsnoop:CARD=ALSA,DEV=0     bcm2835 ALSA, bcm2835 ALSA     Direct sample snooping device dsnoop:CARD=ALSA,DEV=1     bcm2835 ALSA, bcm2835 IEC958/HDMI     Direct sample snooping device hw:CARD=ALSA,DEV=0     bcm2835 ALSA, bcm2835 ALSA     Direct hardware device without any conversions hw:CARD=ALSA,DEV=1     bcm2835 ALSA, bcm2835 IEC958/HDMI     Direct hardware device without any conversions plughw:CARD=ALSA,DEV=0     bcm2835 ALSA, bcm2835 ALSA     Hardware device with all software conversions plughw:CARD=ALSA,DEV=1     bcm2835 ALSA, bcm2835 IEC958/HDMI     Hardware device with all software conversions pi@raspberrypi:~ 
pi@raspberrypi:~ arecord -L null     Discard all samples (playback) or generate zero samples (capture) playback dmixed ac108 default sysdefault:CARD=seeed4micvoicec     seeed-4mic-voicecard,      Default Audio Device dmix:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct sample mixing device dsnoop:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct sample snooping device hw:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct hardware device without any conversions plughw:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Hardware device with all software conversions pi@raspberrypi:~ 

 

即使根本沒有聲卡︰

pi@raspberrypi:~ cat /proc/asound/cards --- no soundcards --- </pre>   <pre class="lang:default decode:true ">pi@raspberrypi:~ aplay -l
aplay: device_list:270: no soundcards found...
pi@raspberrypi:~ arecord -l arecord: device_list:270: no soundcards found... pi@raspberrypi:~ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
default
pi@raspberrypi:~ arecord -L null     Discard all samples (playback) or generate zero samples (capture) default </pre>    <span style="color: #666699;">都還有一個稱作 null 的設備呦!</span> <h1><span style="color: #ff9900;"><a style="color: #ff9900;" href="http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html">Plugin: Null</a></span></h1> <span style="color: #808080;">This plugin discards contents of a PCM stream or creates a stream with zero samples.</span>  <span style="color: #808080;">Note: This implementation uses devices /dev/null (playback, must be writable) and /dev/full (capture, must be readable).</span> <pre class="lang:default decode:true ">pcm.name {         type null       # Null PCM } </pre> <h2><span style="color: #808080;">Function reference</span></h2> <ul>  	<li><span style="color: #808080;"><a class="el" style="color: #808080;" title="Creates a new Empty PCM." href="http://www.alsa-project.org/alsa-doc/alsa-lib/pcm__empty_8c.html#a55df6f9b1b71d37ea91557cc26e8ab3a">_snd_pcm_empty_open()</a></span></li> </ul>    <span style="color: #666699;">故知其可看成插件 Plugin 與 Soundcards 交織的裝置樹 Device Tree 也 。無怪乎有人嘗試擴張哩!?</span> <h1><span style="color: #ff9900;"><a style="color: #ff9900;" href="https://github.com/NikitaKarnauhov/lansink">LANSink</a></span></h1> <span style="color: #808080;">LANSink is simple unreliable half-duplex audio transport over UDP implemented as an ALSA plugin on sender side and as a stand-alone daemon on receiver side. It currently performs no audio compression or latency control. It is designed as a means to connect HTPC with other computers on the same network.</span>     <span style="color: #666699;">咀嚼 <a style="color: #666699;" href="https://www.alsa-project.org/main/index.php/Asoundrc">Asoundrc</a></span>  <span style="color: #666699;">A more complex tool for conversion is the pcm type plug. the syntax is:</span> <pre class="">type plug             	# Format adjusted PCM slave STR               # Slave name (see pcm_slave) # or slave {                 # Slave definition 	pcm STR         # Slave PCM name 	# or 	pcm { }         # Slave PCM definition 	[format STR]    # Slave format (default nearest) or "unchanged" 	[channels INT]  # Slave channels (default nearest) or "unchanged" 	[rate INT]      # Slave rate (default nearest) or "unchanged" } route_policy STR 	# route policy for automatic ttable generation       	                # STR can be 'default', 'average', 'copy', 'duplicate'                        # average: result is average of input channels                       	# copy: only first channels are copied to destination                       	# duplicate: duplicate first set of channels                        # default: copy policy, except for mono capture - sum ttable {               # Transfer table (bidimensional compound of                         # cchannels * schannels numbers) 	CCHANNEL { 		SCHANNEL REAL     # route value (0.0 ... 1.0) 	} }</pre> <span style="color: #808080;">We can use it as follows:</span> <pre class="">pcm_slave.sl3 { 	pcm "hw:1,0" 	format S16_LE 	channels 1 	rate 16000 }  pcm.complex_convert { 	type plug 	slave sl3 } </pre> <span style="color: #808080;">By calling it with:</span> <pre>aplay -vD complex_convert test.wav </pre> <span style="color: #808080;">You will convert the sample during playing to the sample format: S16_LE, one channel and a sample rate of 16 kHz. As you called aplay with the verbose option -v you see this options as it appears as it comes from the original file. with:</span> <pre class="">aplay -v test.wav </pre>    <span style="color: #666699;">其中味後,思 ac108 </span> <pre class="lang:default decode:true">pi@raspberrypi:~ more /etc/asound.conf 
……

pcm.ac108 {
        type ac108
        slavepcm "hw:1,0"
        channels 4       
}

 

想 mmap_emulation 難矣哉?!

The Control device

The control device for a card is the way that programs modify various “controls” on the card. For many cards this includes the mixer (but some cards, for example the rme9652, have no mixer). However, they do still have a number of other controls and some programs like JACK need to be able to access them. Examples include the digital I/O sync indicators, sample clock source switch and so on.

Aliases

With the ‘PCM hw type’ you are able to define aliases for your devices. The syntax for this definition is:

pcm.NAME {
	type hw               # Kernel PCM
	card INT/STR          # Card name or number
	[device] INT          # Device number (default 0)     
	[subdevice] INT       # Subdevice number, -1 first available (default -1)
	mmap_emulation BOOL   # enable mmap emulation for ro/wo devices
}

For example, this gives your first soundcard an alias:

pcm.primary {
	type hw
	card 0
	device 0
}

Now you can access this card by the alias ‘primary‘.

aplay -D primary test.wav

 

 

 

 

 

 

 

【鼎革‧革鼎】︰ Raspbian Stretch 《六之 H.3中 》

如果我們知道如何在樹莓派上

Add an I2S mic using device tree & simple-audio-card

gregeric

Sun Feb 05, 2017 3:44 pm

Here I’m using an ICS43432. Other I2S mics will likely work with the same steps & codec.

For wiring, see https://github.com/nejohnson2/rpi-i2s

For software, you can either follow the steps there, or do it the modern way here using a device tree overlay.

……

 

明白驅動程式編譯過程︰

rpi-i2s

Using the ICS43432 MEMS microphone on a Raspberry Pi with i2s

There has been poor documentation online about using i2s on a RaspberryPi and in particular connecting a MEMs microphone. There is plenty of discussion but no clear tutorial and/or explaination. These notes are meant to be a comprehensive way of connecting a microphone to an RPi over i2s.

Hardware Setup

The following documentation used the ICS43432 MEMs microphone with a breakout board on an RPi 3. Mirophone documentation can be found here. Header pins were soldered to the breakout board. Unfortunately the breakout board was poorly designed and in order to properly install the header pins, the pin labels were covered. Regardless, the connection uses Pulse Code Modulation which requires four GPIO pins from the RPi. The PCM setup can be found here. The connection is as follows:

Mic - RPi
---------
VCC - 3.3v
Gnd - Gnd
L/R - Gnd (this is used for channel selection. Connect to 3.3 or GND)
SCK - BCM 18 (pin 12)
WS  - BCM 19 (pin 35)
SD  - BCM 20 (pin 38)

INCS43432 Breakoutboard

………

 

也許藉著 kernel Simple-Card 之文件說明︰

Simple-Card:

Simple-Card specifies audio DAI connections of SoC <-> codec.

Required properties:

- compatible				: "simple-audio-card"

Optional properties:

- simple-audio-card,name		: User specified audio sound card name, one string
					  property.
- simple-audio-card,widgets		: Please refer to widgets.txt.
- simple-audio-card,routing		: A list of the connections between audio components.
					  Each entry is a pair of strings, the first being the
					  connection's sink, the second being the connection's
					  source.
- simple-audio-card,mclk-fs             : Multiplication factor between stream rate and codec
					  mclk. When defined, mclk-fs property defined in
					  dai-link sub nodes are ignored.
- simple-audio-card,hp-det-gpio		: Reference to GPIO that signals when
					  headphones are attached.
- simple-audio-card,mic-det-gpio	: Reference to GPIO that signals when
					  a microphone is attached.
- simple-audio-card,aux-devs		: List of phandles pointing to auxiliary devices, such
					  as amplifiers, to be added to the sound card.

Optional subnodes:

- simple-audio-card,dai-link		: Container for dai-link level
					  properties and the CPU and CODEC
					  sub-nodes. This container may be
					  omitted when the card has only one
					  DAI link. See the examples and the
					  section below.

 

或可解讀 seeed-voicecard 之 dts 吧!

pi@raspberrypi:~/seeed-voicecard more seeed-4mic-voicecard-overlay.dts  /dts-v1/; /plugin/;  / {     compatible = "brcm,bcm2708"; 	fragment@0 { 		target = <&i2s>; 		__overlay__ { 			#sound-dai-cells = <0>; 			status = "okay";         	}; 	};     fragment@1 {         target-path = "/clocks";         __overlay__ {             ac108_mclk: codec-mclk {                 compatible = "fixed-clock";                 #clock-cells = <0>;                 clock-frequency = <24000000>;             };           };     };     fragment@2 { 		target = <&i2c1>; 		__overlay__ { 			#address-cells = <1>; 			#size-cells = <0>; 			status = "okay";  			ac108_a: ac108@3b{ 				compatible = "x-power,ac108_0"; 				reg = <0x3b>; 				#sound-dai-cells = <0>;                 data-protocol = <1>; 			}; 		};     };        fragment@3 {         target = <&sound>;         sound_overlay: __overlay__ {                 compatible = "simple-audio-card";                 simple-audio-card,format = "i2s";                 simple-audio-card,name = "seeed-4mic-voicecard";                  status = "okay";                                  simple-audio-card,bitclock-master = <&dailink0_slave>;                 simple-audio-card,frame-slave = <&dailink0_slave>;                                dailink0_slave: simple-audio-card,cpu {                     sound-dai = <&i2s>;                 };                 codec_dai: simple-audio-card,codec {                     sound-dai = <&ac108_a>;                     clocks =  <&ac108_mclk>;                 };         };     };     __overrides__ {         card-name = <&sound_overlay>,"seeed-voicecard,name";     };           };  pi@raspberrypi:~/seeed-voicecard 

 

果能推知又為立體麥克風嗎?

 

故連偏愛 mmap 之 jackd 亦能用呦◎

 

且趁此時亦讀讀

Overview

 

For many microcontrollers, adding audio input is easy with one of our analog microphone breakouts. But as you get to bigger and better microcontrollers and microcomputers, you’ll find that you don’t always have an analog input, or maybe you want to avoid the noise that can seep in with an analog mic system. Once you get past 8-bit micros, you will often find an I2S peripheral, that can take digital audio data in! That’s where this I2S Microphone Breakout comes in.

Instead of an analog output, there are three digital pins: Clock, Data and Word-Select. When connected to your microcontroller/computer, the ‘I2S Master’ will drive the clock and word-select pins at a high frequency and read out the data from the microphone. No analog conversion required!

 

The microphone is a single mono element. You can select whether you want it to be on the Left or Right channel by connecting the Select pin to power or ground. If you have two microphones, you can set them up to be stereo by sharing the Clock, WS and Data lines but having one with Select to ground, and one with Select to high voltage.

 

This I2S MEMS microphone is bottom ported, so make sure you have the hole in the bottom facing out towards the sounds you want to read. It’s a 1.6-3.3V device only, so not for use with 5V logic (its really unlikely you’d have a 5V-logic device with I2S anyways). Many beginner microcontroller boards don’t have I2S, so make sure its a supported interface before you try to wire it up! This microphone is best used with Cortex M-series chips like the Arduino Zero, Feather M0, or single-board computers like the Raspberry Pi.

 

哩☆

 

 

 

 

 

 

 

【鼎革‧革鼎】︰ Raspbian Stretch 《六之 H.3上 》

由於想知道為什麼 jackd 會發生 mmap-based 之問題?

pi@raspberrypi:~ jackd -dalsa  -r44100 -p512 -n4 -Phw:0 -Cac108 jackdmp 1.9.11 Copyright 2001-2005 Paul Davis and others. Copyright 2004-2014 Grame. jackdmp comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details JACK server starting in realtime mode with priority 10 self-connect-mode is "Don't restrict self connect requests" ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL ac108 control open "ac108" (No such file or directory) audio_reservation_init Acquire audio card Audio0 creating alsa driver ... hw:0|ac108|512|4|44100|0|0|nomon|swmeter|-|32bit configuring for 44100Hz, period = 512 frames (11.6 ms), buffer = 4 periods ALSA: mmap-based access is not possible for the capture stream of this audio interface ALSA: cannot configure capture channel Cannot initialize driver JackServer::Open failed with -1 Failed to open server </pre>    <span style="color: #666699;">分明 /boot/config.txt 已設定了</span>  <span style="color: #ff9900;">dtoverlay=i2s-mmap</span>  <span style="color: #666699;">的也!故爾閱讀 github 上 <a style="color: #666699;" href="https://github.com/respeaker/seeed-voicecard">seeed-voicecard</a> <a style="color: #666699;" href="http://www.freesandal.org/?p=26396">dtoverlay</a> 的原始碼︰</span> <pre class="lang:default decode:true">pi@raspberrypi:~/seeed-voicecard more seeed-4mic-voicecard-overlay.dts 
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2708";
	fragment@0 {
		target = <&i2s>;
		__overlay__ {
			#sound-dai-cells = <0>;
			status = "okay";
        	};
	};
    fragment@1 {
        target-path = "/clocks";
        __overlay__ {
            ac108_mclk: codec-mclk {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <24000000>;
            };  
        };
    };
    fragment@2 {
		target = <&i2c1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			ac108_a: ac108@3b{
				compatible = "x-power,ac108_0";
				reg = <0x3b>;
				#sound-dai-cells = <0>;
                data-protocol = <1>;
			};
		};
    };



    fragment@3 {
        target = <&sound>;
        sound_overlay: __overlay__ {
                compatible = "simple-audio-card";
                simple-audio-card,format = "i2s";
                simple-audio-card,name = "seeed-4mic-voicecard"; 
                status = "okay";
                
                simple-audio-card,bitclock-master = <&dailink0_slave>;
                simple-audio-card,frame-slave = <&dailink0_slave>;               
                dailink0_slave: simple-audio-card,cpu {
                    sound-dai = <&i2s>;
                };
                codec_dai: simple-audio-card,codec {
                    sound-dai = <&ac108_a>;
                    clocks =  <&ac108_mclk>;
                };
        };
    };
    __overrides__ {
        card-name = <&sound_overlay>,"seeed-voicecard,name";
    };    

    
};

pi@raspberrypi:~/seeed-voicecard </pre>    <span style="color: #666699;">初看唯得知其稱作 seeed-4mic-voicecard 名目之由來哩︰</span> <pre class="lang:default decode:true ">pi@raspberrypi:~ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: seeed4micvoicec [seeed-4mic-voicecard], device 0: bcm2835-i2s-ac108-codec0 ac108-codec0-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
pi@raspberrypi:~ </pre>    <span style="color: #666699;">再看它的 asound_4mic.conf 之設定︰</span> <pre class="lang:default decode:true">pi@raspberrypi:~/seeed-voicecard more asound_4mic.conf 
# The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one

pcm.!default {
    type asym
    playback.pcm "playback"
    capture.pcm "ac108"
}

pcm.playback {
    type plug
    slave.pcm "dmixed"
}


pcm.dmixed {
    type dmix
    slave.pcm "hw:0,0"
    ipc_key 555555 
}


pcm.ac108 {
        type ac108
        slavepcm "hw:1,0"
        channels 4
}
pi@raspberrypi:~/seeed-voicecard $ 

 

雖然查覽列出其所用之

PCM (digital audio) plugins

PCM plugins extends functionality and features of PCM devices. The plugins take care about various sample conversions, sample copying among channels and so on.

的定義與範例︰

Slave definition

The slave plugin can be specified directly with a string or the definition can be entered inside a compound configuration node. Some restrictions can be also specified (like static rate or count of channels).

pcm_slave.NAME {
pcm STR # PCM name
# or
pcm { } # PCM definition
format STR # Format or "unchanged"
channels INT # Count of channels or "unchanged" string
rate INT # Rate in Hz or "unchanged" string
period_time INT # Period time in us or "unchanged" string
buffer_time INT # Buffer time in us or "unchanged" string
}

Example:

pcm_slave.slave_rate44100Hz {
pcm "hw:0,0"
rate 44100
}
pcm.rate44100Hz {
type plug
slave slave_rate44100Hz
}

The equivalent configuration (in one compound):

pcm.rate44100Hz {
type plug
slave {
pcm "hw:0,0"
rate 44100
}
}

Plugin: asym

This plugin is a combination of playback and capture PCM streams. Slave PCMs can be defined asymmetrically for both directions.

pcm.name {
type asym # Asym PCM
playback STR # Playback slave name
# or
playback { # Playback slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
capture STR # Capture slave name
# or
capture { # Capture slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
}

For example, you can combine a dmix plugin and a dsnoop plugin as as a single PCM for playback and capture directions, respectively.

pcm.duplex {
type asym
playback.pcm "dmix"
capture.pcm "dsnoop"
}

By defining only a single direction, the resultant PCM becomes half-duplex.

……

Plugin: dmix

This plugin provides direct mixing of multiple streams. The resolution for 32-bit mixing is only 24-bit. The low significant byte is filled with zeros. The extra 8 bits are used for the saturation.

pcm.name {
type dmix # Direct mix
ipc_key INT # unique IPC key
ipc_key_add_uid BOOL # add current uid to unique IPC key
ipc_perm INT # IPC permissions (octal, default 0600)
slave STR
# or
slave { # Slave definition
pcm STR # slave PCM name
# or
pcm { } # slave PCM definition
format STR # format definition
rate INT # rate definition
channels INT
period_time INT # in usec
# or
period_size INT # in bytes
buffer_time INT # in usec
# or
buffer_size INT # in bytes
periods INT # when buffer_size or buffer_time is not specified
}
bindings { # note: this is client independent!!!
N INT # maps slave channel to client channel N
}
slowptr BOOL # slow but more precise pointer updates
}

ipc_key specfies the unique IPC key in integer. This number must be unique for each different dmix definition, since the shared memory is created with this key number. When ipc_key_add_uid is set true, the uid value is added to the value set in ipc_key. This will avoid the confliction of the same IPC key with different users concurrently.

Note that the dmix plugin itself supports only a single configuration. That is, it supports only the fixed rate (default 48000), format (S16), channels (2), and period_time (125000). For using other configuration, you have to set the value explicitly in the slave PCM definition. The rate, format and channels can be covered by an additional plug plugin, but there is only one base configuration, anyway.

An example configuration for setting 44100 Hz, S32_LE format as the slave PCM of “hw:0” is like below:

pcm.dmix_44 {
type dmix
ipc_key 321456 # any unique value
ipc_key_add_uid true
slave {
pcm "hw:0"
format S32_LE
rate 44100
}
}

You can hear 48000 Hz samples still using this dmix pcm via plug plugin like:

% aplay -Dplug:dmix_44 foo_48k.wav

 

尚且難知又頭大呦!!仍得爬文乎??

TwoCardsAsOne

From the ALSA wiki

Jump to: navigation, search

Contents

Notes

WARNING NOTE added by LudwigSchwardt: (comments welcome!)

Be careful when using this scheme for capturing (recording) audio data. It might work with multiple sample-synchronized cards (i.e. Hammerfall/ICE1712) that have a single sample clock signal driving all of them, or when the dummy soundcard is combined with another soundcard for testing. It will definitely fail when combining two or more unlinked soundcards. When using JACK, I typically got an error message of

snd_pcm_mmap_commit: Assertion `frames \<= snd_pcm_mmap_avail(pcm)’ failed

and jackd hangs in the process. This error may take a while to pop up, but it is inevitable, since this is a basic hardware limitation.

Each soundcard has its own sample clock. If these aren’t linked to the same clock in some way (eg. wordclock), the clock frequencies will differ, sometimes substantially, due to manufacturing tolerances on the crystals, etc. This means that the hardware interrupts announcing the availability of new data will be out of sync. Even worse, the cards with faster clocks will produce more data than the slower cards during the same time interval. Therefore, even if a program like JACK waited until all the soundcards had audio data available and then presented this data to its callback, at some stage data from the soundcard with a faster sample clock will have to be discarded to keep up with the rest. At the very least xruns will occur.

It might be possible to write a software layer (ALSA driver/plugin?) to hide the clock differences by effectively resampling the streams to a common frequency. This will be the only way to keep programs like JACK completely happy. As this will inevitably involve the discarding and/or generation of samples, it is still not a pretty solution. It will probably also increase the latency of the system.

On the other hand, this .asoundrc trick seems to work OK for playback. During playback, programs dump audio data into soundcard buffers and let the hardware decide when the data will reach the output terminals. These buffers in effect hide the difference in clock frequencies. However, xruns are probably still going to happen, for instance when the faster card runs out of data or the slower card’s buffer is full.

regards, Ludwig

 

樂知好學者或早先登耶◎

ALSA – PCM接口

 

 

 

 

 

 

 

【鼎革‧革鼎】︰ Raspbian Stretch 《六之 H.2 》

我們將如何解讀 Asoundrc 的

The default plugin

Make a file called .asoundrc in your home and/or root directory.

vi /home/xxx/.asoundrc

copy and paste the following into the file then save it.

pcm.!default {
	type hw
	card 0
}

ctl.!default {
	type hw           
	card 0
}

 

之 default 一詞呢?

The keyword default is defined in the ALSA lib API and will always access hw:0,0 — the default device on the default soundcard. Specifying the !default name supersedes the one defined in the ALSA lib API.

aplay -D default test.wav

 

顧名思義,『 ! 』也者,重新定義原本 API 預設者『hw:0,0』呦!方說 default \neq hw:0,0 矣。若有軟體將之視為 default  \ {\equiv}_{df} \  hw:0,0

或將忽略 bluealsa 實乃首選聲音輸出者哩?!

pi@raspberrypi:~ more ~/.asoundrc  pcm.!default { 	type plug 	slave.pcm { 		type bluealsa 		device "00:02:5B:00:47:4E" 		profile "a2dp" 	} }  ctl.!default { 	type bluealsa } </pre>    <span style="color: #666699;">所以並非 jackd 無法使用藍牙喇叭︰</span> <pre class="lang:default decode:true">pi@raspberrypi:~ jackd -dalsa  -r44100 -p2048 -n4  -Pdefault
jackdmp 1.9.11
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2014 Grame.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
audio_reservation_init
Acquire audio card Audio0
creating alsa driver ... default|-|2048|4|44100|0|0|nomon|swmeter|-|32bit
configuring for 44100Hz, period = 2048 frames (46.4 ms), buffer = 4 periods
ALSA: final selected sample format for playback: 32bit float little-endian
You appear to be using the ALSA software "plug" layer, probably
a result of using the "default" ALSA device. This is less
efficient than it could be. Consider using a hardware device
instead rather than using the plug layer. Usually the name of the
hardwa
ALSA: use 5 periods for playback
Unknown destination port in attempted (dis)connection src_name [alsaplayer-2734:out_1] dst_name [alsa_pcm:playback_1]
Unknown destination port in attempted (dis)connection src_name [alsaplayer-2734:out_2] dst_name [alsa_pcm:playback_2]

 

恐是 QjackCtl 錯解未讀 (default) 導至哩!!

 

因此 SonicPi 亦可如是看也︰

 

 

 

 

 

 

 

 

【鼎革‧革鼎】︰ Raspbian Stretch 《六之 H.1 》

如果觀察一個『』的歷史,也許會發現『』的人生際遇『起起伏伏』,『』的待人處事『好好壞壞』,以及『』的言行思想『真真假假』。過去『孔子作春秋』有所謂的『一字褒貶』,這是就一個『』一生行述之『總評』。觀察一個『』,就像是『閱讀』一本『』,衡量一件『』彷彿在『聽聞』一段『』 ,『前因後果』的『錯綜複雜』實在需要『理清思路』方能有『適切判斷』的啊!正如『孟子』說的︰盡信書,不如無書。

在此引用孟子與梁惠王的一段『對話』,來看看『千古遺音』與『當今鑼鈸』的『交響』,期望能在『失衡』和『不和』的現代,寄語『未來者』能夠『慎選』發展的『道路』!!

───《孟子‧梁惠王上

 

孟子見梁惠王。王曰:「叟!不遠千里而來,亦將有以乎? 」

孟子對曰:「王!何必曰?亦有仁義而已矣。王曰:『何以利吾?』大夫曰:『何以利吾?』士庶人曰:『何以利吾?』上下交征而國。萬乘之國,弒其君者,必千乘之家;千乘之國 ,弒其君者,必百乘之家。萬取千焉,千取百焉,不為不多矣。苟為後義而先利,不奪不饜。未有仁而遺其親者也,未有義而後其君者也。王亦曰仁義而已矣,何必曰利?」

孟子見梁惠王。王立於沼上,顧鴻雁麋鹿,曰:「賢者亦樂此乎? 」

孟子對曰:「賢者而後樂此,不賢者雖有此,不樂也。詩云:『經始靈台,經之營之,庶民攻之,不日成之。經始勿亟,庶民子來。王在靈囿,麀鹿攸伏,麀鹿濯濯,白鳥鶴鶴。王在靈沼,於牣魚躍 。』文王以民力為台為沼,而民歡樂之,謂其台曰靈台,謂其沼曰靈沼,樂其有麋鹿魚鱉。古之人與民偕樂,故能樂。湯誓曰:『時日害喪,予及女皆亡。』民欲與之偕亡,雖有台池鳥獸,豈能獨樂哉?」

梁惠王曰:「寡人之於國也,盡心焉耳矣。河內凶,則移其民於河東,移其粟於河內;河東凶亦然。察鄰國之政,無如寡人之用心者 。鄰國之民不加少,寡人之民不加多,何也?」

孟子對曰:「王好戰,請以戰喻。填然鼓之,兵刃既接,棄甲曳兵而走。或百步而後,或五十步而後以五十步笑百步,則何如?

曰:「不可,直不百步耳,是亦走也。」

曰:「王如知此,則無望民之多於鄰國也。」

不違農時,穀不可勝食也;數罟不入洿池,魚鼈不可勝食也 ;斧斤以時入山林,材木不可勝用也。穀與魚鼈不可勝食,材木不可勝用,是使民養生喪死無憾也。養生喪死無憾,王道之始也。

五畝之宅,樹之以桑,五十者可以衣帛矣;雞豚狗彘之畜,無失其時,七十者可以食肉矣;百畝之田,勿奪其時,數口之家可以無饑矣;謹庠序之教,申之以孝悌之義,頒白者不負戴於道路矣。七十者衣帛食肉,黎民不饑不寒,然而不王者,未之有也!

「狗彘食人食而不知檢,塗有餓莩而不知發,人死,則曰:『非我也,歲也。』是何異於刺人而殺之,曰:『非我也,兵也。』王無罪歲,斯天下之民至焉。」

梁惠王曰:「寡人願安承教。」

孟子對曰:「殺人以梃與刃,有以異乎?

曰:「無以異也。

以刃與政,有以異乎?

曰:「無以異也。

曰:「庖有肥肉,廄有肥馬,民有饑色,野有餓莩,此率獸而食人也。獸相食,且人惡之;為民父母,行政,不免於率獸而食人。惡在其為民父母也?仲尼曰:『始作俑者,其無後乎!』為其像人而用之也。如之何其使斯民饑而死也?
…… ───

Venetian_Patent_Statute_1474

220px-Puckle_gun_advertisement

175px-US_Patent_cover

220px-US_patents_1790-2008

220px-Ejector_seat_with_patents_crooped

專利』 patent 一詞源自拉丁文『patere』意指 to lay open。西元前五百年在希臘的某些城邦裡曾經有類似發明的專利權。

一六二三年英國國王詹姆士一世,同時也是蘇格蘭國王詹姆士六世 James I and James VI 設立『專利權』,用以保護發明者的『權利』。這對英國與世界日後的工業革命和歷史產生巨大的影響。為什麼會設立『專利權』的呢?意旨在對公眾『公開知識』與『激勵創新』,又想免於『不勞而獲』和『仿冒抄襲』的劣行。藉著保護了『發明者』使其樂於公開『知識』及『技術』,於是『知識』及『技術』就成了『計價之物』,也產生了以『利益』為中心的『發明』與『創造』。一九四四年中華民國政府公布了『第一部專利法典』,直到一九四九年一月一日才開始實施。

現今的世界又拓展到了『著作權』,這不可不說是一把『雙面刃』,好或不好但看社會之『世道人心』的啊!在那個沒有『專利保護』的『祖傳秘方』年代,也許有人會因為『知識無價』和『智慧共享』破解所謂的『巧妙』,這樣的人在今天就成了標準『傻鳥』,豈有不先『申請專利』後,再談公開的『道理』呢!果真如俗語所說的『成也蕭何,敗也蕭何』的啊!!

社會中人的『分工』和『合作』,是所有人的『福祉』與『共享』,一個『誰多誰寡』以及『勞心勞力』的『計價』和『分配』問題,不知還要再『繼續』爭議幾千年呢!!

─── 《【Sonic π】電路學之補充《三》

 

故事常始於很久很久以前 ,或說萬事起頭難乎?

若僅依人之言

5. Open Audacity and select AC108 & 4 channels as input and bcm2835 alsa: – (hw:0:0) as output to test:

 

sudo apt update sudo apt install audacity
audacity</pre> <code class="hljs smalltalk"> </code>  <img src="https://github.com/SeeedDocument/ReSpeaker-4-Mic-Array-for-Raspberry-Pi/blob/master/img/audacity.png?raw=true" alt="" />     <span style="color: #666699;">且經證確果無疑焉??</span>  <img class="alignnone size-full wp-image-78617" src="http://www.freesandal.org/wp-content/uploads/audacity.png" alt="" width="1920" height="1080" />     <span style="color: #666699;">但為何心又懷疑呦!! </span>  <img class="alignnone size-full wp-image-78616" src="http://www.freesandal.org/wp-content/uploads/jackd-4mic.png" alt="" width="1920" height="1080" />     <span style="color: #666699;">故<a style="color: #666699;" href="http://ctext.org/liji/da-xue/zh">大學</a>曰知止</span> <pre class="lang:default decode:true">pi@raspberrypi:~ more /etc/asound.conf 
# The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one

pcm.!default {
    type asym
    playback.pcm "playback"
    capture.pcm "ac108"
}

pcm.playback {
    type plug
    slave.pcm "dmixed"
}


pcm.dmixed {
    type dmix
    slave.pcm "hw:0,0"
    ipc_key 555555 
}


pcm.ac108 {
        type ac108
        slavepcm "hw:1,0"
        channels 4

 

pi@raspberrypi:~ arecord -l **** List of CAPTURE Hardware Devices **** card 1: seeed4micvoicec [seeed-4mic-voicecard], device 0: bcm2835-i2s-ac108-codec0 ac108-codec0-0 []   Subdevices: 1/1   Subdevice #0: subdevice #0 pi@raspberrypi:~ 
pi@raspberrypi:~ arecord -L null     Discard all samples (playback) or generate zero samples (capture) playback dmixed ac108 default sysdefault:CARD=seeed4micvoicec     seeed-4mic-voicecard,      Default Audio Device dmix:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct sample mixing device dsnoop:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct sample snooping device hw:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Direct hardware device without any conversions plughw:CARD=seeed4micvoicec,DEV=0     seeed-4mic-voicecard,      Hardware device with all software conversions pi@raspberrypi:~ 

 

后定靜安慮得矣◎

 

pi@raspberrypi:~ $ jackd -dalsa  -r44100 -p512 -n4 -Phw:0 -Cac108
jackdmp 1.9.11
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2014 Grame.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL ac108
control open "ac108" (No such file or directory)
audio_reservation_init
Acquire audio card Audio0
creating alsa driver ... hw:0|ac108|512|4|44100|0|0|nomon|swmeter|-|32bit
configuring for 44100Hz, period = 512 frames (11.6 ms), buffer = 4 periods
ALSA: mmap-based access is not possible for the capture stream of this audio interface
ALSA: cannot configure capture channel
Cannot initialize driver
JackServer::Open failed with -1
Failed to open server