How do I feed CD audio tracks into an ALSA-driven sound output device? - raspbian

I'm using a USB CD/DVD drive without built-in sound decoder and controlling it via ALSA, which already works. The host is a Raspberry Pi 3B with the current Raspbian. Here is the corresponding config file:
pi#autoradio:/etc $ cat asound.conf
pcm.dmixer {
type dmix
ipc_key 1024
ipc_perm 0666
slave {
pcm "hw:0,0"
period_time 0
period_size 1024
buffer_size 4096
rate 192000
format S32_LE
channels 2
}
bindings {
0 0
1 1
}
}
pcm.dsnooper {
type dsnoop
ipc_key 2048
ipc_perm 0666
slave
{
pcm "hw:0,0"
period_time 0
period_size 1024
buffer_size 4096
rate 192000
format S32_LE
channels 2
}
bindings {
0 0
1 1
}
}
pcm.duplex {
type asym
playback.pcm "dmixer"
capture.pcm "dsnooper"
}
pcm.!default {
type plug
slave.pcm "duplex"
}
ctl.!default {
type hw
card 0
}
To read the music from CD-DA, I'm gonna use the CDIO++ library. Its cd-info utility recognises both the drive, and the audio CD:
pi#autoradio:/etc $ cd-info
cd-info version 2.1.0 armv7l-unknown-linux-gnueabihf
CD location : /dev/cdrom
CD driver name: GNU/Linux
access mode: IOCTL
Vendor : MATSHITA
Model : CD-RW CW-8124
Revision : DA0D
Hardware : CD-ROM or DVD
Can eject : Yes
Can close tray : Yes
Can disable manual eject : Yes
Can select juke-box disc : No
Can set drive speed : No
Can read multiple sessions (e.g. PhotoCD) : Yes
Can hard reset device : Yes
Reading....
Can read Mode 2 Form 1 : Yes
Can read Mode 2 Form 2 : Yes
Can read (S)VCD (i.e. Mode 2 Form 1/2) : Yes
Can read C2 Errors : Yes
Can read IRSC : Yes
Can read Media Channel Number (or UPC) : Yes
Can play audio : Yes
Can read CD-DA : Yes
Can read CD-R : Yes
Can read CD-RW : Yes
Can read DVD-ROM : Yes
Writing....
Can write CD-RW : Yes
Can write DVD-R : No
Can write DVD-RAM : No
Can write DVD-RW : No
Can write DVD+RW : No
__________________________________
Disc mode is listed as: CD-DA
I've already got some code to send the PCM data to the sound card and some insight regarding the (rather poorly documented) CDIO API (I know that the readSectors() method is used for reading sound data from the CD sector after sector), but not really a clue on how to hand over the data from the CD-DA input to the ALSA output routine correctly.
Please nopte that mplayer is off-limits to me as this routine will be a part of a larger solution.
Any help would be greatly appreciated.
UPDATE: Does the different block size of an audio CD (2,352 bytes) and of the sound output (910 bytes, at least in my particular case) matter?

CD audio data is just two channels of little-endian 16-bit samples at 44.1 kHz.
If you output the data to the standard output, you can pipe it into your sound-playing program, or aplay:
./my-read-cdda | ./play 44100 2 99999
./my-read-cdda | aplay --file-type raw --format cd
If you want to do everything in a single program, replace the read(0, ...) with readSectors(). (The buffer size does not need to have any relation with ALSA's period size or buffer size.)

Related

How can I (or is it possible to) convert the AVC codec profile and level to the MIME codec definition?

In my use-case I have to provide codec specification within the HTML5 video source's MIME type. But even a type="video/mp4; codecs=avc1" is not detailed enough for Firefox. Firefox needs the extra detail of for example type="video/mp4; codecs=avc1.64001E". My problem is that I don't know where to get this 64001E part from.
The whole identification happens on server side. So far I was using ffprobe and that's perfectly supplies me JSON format output, like so:
ffprobe -select_streams v:0 -v info -of json -show_entries stream=codec_name,level,profile,width,height -i 1CE89B23-F9BD-43B9-805B-C49ACA9E5FFB_xxxxxxx.mp4
"streams": [
{
"codec_name": "h264",
"profile": "High",
"width": 1080,
"height": 1920,
"level": 50
}
]
}
I can get the profile and the level, but nothing like 64001E. In my local environment I also have mediainfo:
mediainfo 8038B652-106B-4FBB-BAD6-AF7E32913FDE_xxxxxxx.mp4
General
Complete name : 8038B652-106B-4FBB-BAD6-AF7E32913FDE_xxxxxxx.mp4
Format : MPEG-4
Format profile : Base Media
Codec ID : isom (isom/iso2/avc1/mp41)
File size : 1.18 MiB
Duration : 6 s 634 ms
Overall bit rate : 1 496 kb/s
Writing application : Lavf57.83.100
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High#L3
Format settings : CABAC / 5 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 5 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 6 s 634 ms
Bit rate : 1 396 kb/s
Width : 360 pixels
Height : 480 pixels
Display aspect ratio : 0.750
Frame rate mode : Constant
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.269
Stream size : 1.10 MiB (93%)
Writing library : x264 core 152 r2854 e9a5903
Encoding settings : cabac=1 / ref=5 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=8 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=15 / lookahead_threads=2 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=50 / rc=crf / mbtree=1 / crf=17.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Codec configuration box : avcC
Audio
ID : 2
Format : AAC LC
Format/Info : Advanced Audio Codec Low Complexity
Codec ID : mp4a-40-2
Duration : 6 s 632 ms
Duration_LastFrame : -9 ms
Bit rate mode : Constant
Bit rate : 90.4 kb/s
Channel(s) : 1 channel
Channel layout : C
Sampling rate : 44.1 kHz
Frame rate : 43.066 FPS (1024 SPF)
Compression mode : Lossy
Stream size : 73.2 KiB (6%)
Default : Yes
Alternate group : 1
What we see here is that the AAC part has a longer Codec ID mp4a-40-2, but the video stream is still just avc1.
I'm looking at lists https://tools.woolyss.com/html5-canplaytype-tester/ and https://wiki.whatwg.org/wiki/Video_type_parameters and I think maybe there's a programmatic way to convert the codec profile + level to the code what the MIME type codec specification has.
In https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter I see that "avc1.4d002a" means Main Profile, Level 4.2. Looking at the list I linked earlier I figured that the 6 hex digits can be broken down into groups of two. The last two is the level. In this latest example the Level is 4.2, we just have to remove the dot => it becomes 42, which is 2a hex. The other 4 hex digits are related to the profile as Main, High, etc and then Progressive, but I haven't found a definition yet, and I wonder if the ffprobe is able to output things like High 4:2:2 Intra Level or High Progressive Level. We'll see.
https://www.rfc-editor.org/rfc/rfc6381#page-12 has some examples, but I followed the links and still don't see any definitive list or anything.
The ITU-T H.264 specification Annex A lists 14 profiles. In those listings there's a profile_idc mentioned, which seems to be the decimal for the first two hex digits, for example High's profile_idc is 100 decimal, which is 64 hexa. Now we just need to figure out the middle two hexa digits. Preferably a GitHub repo source file would be great where these things are curated into a sane concise const literal array.
It is described in e.g. Mozilla link ("PPCCLL is six hexadecimal digits specifying the profile number (PP), constraint set flags (CC), and level (LL)"). If you don't find a tool fitting your needs, we could extend e.g. MediaInfo for that, let us know.
Note: the CC indicated in the list are the expected flags, not the ones really in the file, it should be OK 99.99% of the time but you can not be sure it is the real content. MediaInfo internally reads the flags but it does not export them for the moment.

ALSA - setting input volume for line in command line - input not recognized but available for programs

I cant see the input device in alsamixer on the usb board, but it is listed as I do arecord -L (also why is it listing the 2nd sound card by default ?)
arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
I can see many informations but I cant figure from man, how to change the level of the line input in command line nor in the gui
amixer info
Card default 'CODEC'/'Burr-Brown from TI USB Audio CODEC at usb-3f980000.usb-1.3, full speed'
Mixer name : 'USB Mixer'
Components : 'USB08bb:2902'
Controls : 4
Simple ctrls : 1
amixer contents
numid=3,iface=MIXER,name='PCM Playback Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=4,iface=MIXER,name='PCM Playback Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=128,step=0
: values=128,128
| dBminmax-min=-128.00dB,max=0.00dB
numid=2,iface=PCM,name='Capture Channel Map'
; type=INTEGER,access=r----R--,values=2,min=0,max=36,step=0
: values=0,0
| container
| chmap-fixed=FL,FR
| chmap-fixed=MONO
numid=1,iface=PCM,name='Playback Channel Map'
; type=INTEGER,access=r----R--,values=2,min=0,max=36,step=0
: values=0,0
| container
| chmap-fixed=FL,FR
| chmap-fixed=MONO
I am actualy not sure about how to achieve this since many people say thousands of different thing
here I try to set the volume in a clumsy way, and it does not work :
amixer -c 1 sset numid=2 0
amixer: Unable to find simple control 'numid=2',0
amixer -c 1 cset numid=2 0
amixer: Control hw:1 element write error: Operation not permitted
sudo amixer -c 1 cset numid=2 0
amixer: Control hw:1 element write error: Operation not permitted
amixer does not list any record device although I can clearly record audio with audacity or puredata
amixer -c 1
Simple mixer control 'PCM',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 128
Mono:
Front Left: Playback 128 [100%] [0.00dB] [on]
Front Right: Playback 128 [100%] [0.00dB] [on]
amixer -c 0
Simple mixer control 'PCM',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback -10239 - 400
Mono: Playback 0 [96%] [0.00dB] [on]
please help me out, this makes no sens at all to me
thanks guys
amixer and alsamixer shows those mixer controls that the hardware actually has.
As figure 31 in the PCM2902 datasheet shows, this device indeed has no mechanism to change the capture volume:
It might be possible to add a softvol plugin, but it would be easier to just use PulseAudio.

Configuring MPD with an 5.1 external surround sound card

I've read tons of threads about this, but i cant figure it out.
So i have a MPD server running on Raspbian, with an external sound card attached to it. Music works fine trough mpd with the 2 channels, but not for 6 channels.
Also i am confused what is the task of all programs involved.
So there's alsa. I Have tried to change the /etc/asound.conf to many different configurations. Like:
pcm.!default {
type route
slave.pcm surround51
slave.channels 6
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
ttable.0.5 0.5
ttable.1.5 0.5
}
But it did not work. My current settings are:
pcm.!default {
type hw
card 2
device 0
}
ctl.!default {
type hw
card 2 #If you want to set HDMI as output ,turn 0 to 1.
}
Then there is pulse audio. I am not sure if the function of both programs overlap, or if you should use them together. To the pulseaudio config file /etc/pulse/daemon.conf i have edited the following line:
default-sample-channels = 6
Furthermore i have added the following line to /etc/pulse/default.pa
set-card-profile 2 output:analog-surround-51
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 # IP of l$
But i am not sure it has any effect at all.
So last there is mpd configuration which I had configure at ~/.mpd/mpd.conf
audio_output {
type "alsa"
name "My ALSA Device"
mixer_type "software"
mixer_control "PCM"
}
If i change alsa to pulse i cant hear sound. Furthermore, the command speaker-test -c 6 -t wav
IS working for 6 channels. Since mpd is configured with alsa, and speaker-test does work, i guess that it is pulseaudio that creates the surround sound. But how can i configure MPD to work with surround sound?
Does anyone have any idea? Any help is much appreciated!
Here is the ouput of aplay -l
xcb_connection_has_error() returned true
card 0: sunxicodec [sunxi-CODEC], device 0: M1 PCM [sunxi PCM]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: sunxisndhdmi [sunxi-sndhdmi], device 0: SUNXI-HDMIAUDIO sndhdmi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: Device [USB Sound Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
and
Update:
If i play sound as the mpd user it also works with surround sound
sudo -u mpd speaker-test -c 6 -t wav
Eventually this worked for me:
pcm.ch51 {
slave sl2
#slave.channels 6
type route
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
ttable.0.4 0.5
ttable.1.4 0.5
ttable.0.5 0.5
ttable.1.5 0.5
}
pcm_slave.sl2 {
channels 6
pcm "hw:1,0"
}
In ~/.asoundrc. The table thing duplicates sound to other speakers so all 5+1 speakers are used. The pcm "hw:1,0" selects my external usb sound card.
Additionally in ~/.mpd/mpd.conf
audio_output {
type "alsa"
name "My ALSA Device"
channels "6"
device "ch51"
You select the device specified in asound.rc

In Bluez A2DP: how can I modify the default audio sample rate

I am using Bluez4 to sink Audio from an iphone 5 to a Raspberry pi audio output.
The default settings for BLuez 4 A2DP appear to be S16_LE, 44,1kHz Stereo.
Similar to other posts about Bluez, I can't catch Select_Configuration DBus messages in order to change the sample rate dynamically. Instead I decided to try to find the default A2DP sample rate in the BLuez Stack.
Does anyone know where the default sample rate is set? My first thought was that it was in the BLuez/audio/ folder but nothing appears to change the default 44.1kHz sample rate.
Now I'm very curious to know where it is set.
Currently using this: sudo ./a2dp-alsa --sink | aplay -c 2 -r 44100 -f S16
would like to use this sudo ./a2dp-alsa --sink | aplay -c 2 -r 16000 -f S16
I came across these lines in a2dp-alsa.c
/* Initialise connection to ALSA */
g_handle = audio_init("hw:0,0", 48000);
maybe its hard coded in a2dp-alsa - not parameterizable

How do I get all the information regarding the header of an audio file?

How do I get all the information regarding the header of an audio file, so it can be displayed in a readable format like ASCII values?
The audio file maybe of any format, most preferably .wav format.
EDIT:- OS can be windows 8.1 or ubuntu. I actually have to understand all the properties of the file like whether it is mono or stereo, its encoding, etc. maybe specifically .wav file, i would say.
I have knowledge about the C++ language, so that would be better.
There is a very powerful command you can use in a bash script: sox.
To get all the info you need about a wav file, you just have to run:
soxi file.wav
and you'll get something like:
Input File : 'file.wav'
Channels : 1
Sample Rate : 8000
Precision : 16-bit
Duration : 00:02:08.40 = 1027236 samples ~ 9630.34 CDDA sectors
File Size : 2.05M
Bit Rate : 128k
Sample Encoding: 16-bit Signed Integer PCM
sox is available for Windows as well, although I have never used there.
You can use FFPROBE utility from FFMPEG: http://ffmpeg.org/
"ffprobe" gathers information from multimedia streams and prints it in human- and machine-readable fashion.
For example it can be used to check the format of the container used by a multimedia stream
and the format and type of each media stream contained in it.
Code
ffprobe -i <file_name>
ffprobe -i myfile.wav
Output will look something like this
Input #0, wav, from 'myfile.wav':
Duration: 00:04:16.88, bitrate: 16 kb/s
Stream #0:0: Audio: g729 ([131][0][0][0] / 0x0083), 8000 Hz, 2 channels, s16p, 16 kb/s
Output Explanation:
g729 is encoding type here.
16 kb/s is the bit-rate.
2 channels
Sample rate 8000 Hz
For detailed information
ffprobe -i <file_name> -show_streams