Tuesday, 22 March 2016

Tagging! Sound Files!

Right. I've worked out (duh!) that the reason why the reformatted tracks aren't appearing, and the Thomas Dolby WAV tracks aren't showing as an album is because they have incorrect or non-existent metadata. So, a quick download, and we'll be fixing them up and retrying them!

Update: Nope. Hard to find a Mac OS X tag editor that doesn't crash that's free... The only one I've found is not very intuitive!

No idea yet why the 24/96 Bowie material is not playing on my 24/96 DAC. I have the IQAudio PI+ I2S DAC arriving shortly, let's see if that works. The Thomas Dolby stuff plays, but I'm not sure why...

mpd.conf has the following output entry:

audio_output {
        type            "alsa"
        name            "ODACverB"
        device          "hw:1,0"        # optional
#       mixer_type      "software"      # optional
#       mixer_device    "default"       # optional
#       mixer_control   "PCM"           # optional
#       mixer_index     "0"             # optional

}

i.e. I'm using the direct hardware interface, no means of converting - see below!

The ODAC has the following support embedded (using the cool scripts here):

pi@raspberrypi:~ $ ./alsa-capabilities -s -l usb
 0) USB Audio Class Digital alsa audio output interface `hw:1,0'
 - device name       = ODAC-revB                                                   
 - interface name    = USB Audio                                                   
 - usb audio class   = 1 - isochronous adaptive                                    
 - character device  = /dev/snd/pcmC1D0p                                           
 - rates per format  = S24_3LE:             96000Hz 88200Hz 48000Hz 44100Hz 32000Hz 
                       S16_LE:              96000Hz 88200Hz 48000Hz 44100Hz 32000Hz 
 - monitor file      = /proc/asound/card1/pcm0p/sub0/hw_params                     

 - stream file       = /proc/asound/card1/stream0        

So it does 16/24 bit, at 32/4.1/48/88.2/96 KHz. Anything else is a no-no, unless it's converted to one of those first.

Checking out the actual file content...
WAV files have the following header structure:

The format for a wave file is as follows:

     Offset    Description
     ------    -----------
      0x00     chunk id 'RIFF'
      0x04     chunk size (32-bits)
      0x08     wave chunk id 'WAVE'
      0x0C     format chunk id 'fmt '
      0x10     format chunk size (32-bits)
      0x14     format tag (currently pcm)
      0x16     number of channels 1=mono, 2=stereo
      0x18     sample rate in hz
      0x1C     average bytes per second
      0x20     number of bytes per sample
                    1 =  8-bit mono
                    2 =  8-bit stereo or
                        16-bit mono
                    4 = 16-bit stereo
      0x22     number of bits in a sample
      0x24     data chunk id 'data'
      0x28     length of data chunk (32-bits)

      0x2C     Sample data

Thomas Dolby WAV Oceana.wav has the following data:


     Offset    Value      Description
     ------               -----------
      0x00     'RIFF'(!)  chunk id 'RIFF'
      0x04     524C 2704  (69,684,306) the file size! chunk size (32-bits)
      0x08     'WAVE'     wave chunk id 'WAVE'
      0x0C     'fmt '     format chunk id 'fmt '
      0x10     1000 0000  (65,536) format chunk size (32-bits)
      0x14     0100       (1) format tag (currently pcm)
      0x16     0200       (2) number of channels 1=mono, 2=stereo
      0x18     80BB 0000  (48000) sample rate in hz
      0x1C     0065 0400  (288,000 i.e. 48k*3) average bytes per second
      0x20     0600       (6 i.e. 24*2=48) number of bytes per sample
      0x22     1800       (24) number of bits in a sample
      0x24     'data'     data chunk id 'data'
      0x28     7C46 1B04  (68,896,380) length of data chunk (32-bits)

      0x2C     blah blah  Sample data

Note: This is WAV, so the entries are "little endian", so 524C 2704 is actually 04274C52

The mpd log has entries for these WAV files like:

Mar 22 12:09 : playlist: play 0:"http://192.168.1.3:9790/minimserver/*/pi/Thomas
*20Dolby/Oceanea*20EP/01*20Oceanea.wav"
Mar 22 12:09 : client: [0] command returned 0
Mar 22 12:09 : client: [0] process command "status"
Mar 22 12:09 : client: [0] command returned 0
Mar 22 12:09 : client: [0] process command "currentsong"
Mar 22 12:09 : client: [0] command returned 0
Mar 22 12:09 : client: [0] process command "playlistinfo "1""
Mar 22 12:09 : client: [0] command returned 0
Mar 22 12:09 : decoder_thread: probing plugin sndfile
Mar 22 12:09 : decoder: audio_format=48000:32:2, seekable=true
Mar 22 12:09 : alsa_output: opened hw:1,0 type=HW
Mar 22 12:09 : alsa_output: format=S24_3LE (Signed 24 bit Little Endian in 3bytes)
Mar 22 12:09 : alsa_output: buffer: size=96..174762 time=2000..3640875
Mar 22 12:09 : alsa_output: period: size=48..87381 time=1000..1820438
Mar 22 12:09 : alsa_output: default period_time = buffer_time/4 = 500000/4 = 125000
Mar 22 12:09 : alsa_output: buffer_size=24000 period_size=6000
Mar 22 12:09 : output: opened plugin=alsa name="ODACverB" 
Mar 22 12:09 : output: opened plugin=alsa name="ODACverB" audio_format=48000:24:2
Mar 22 12:09 : output: converting from 48000:32:2

48000 ok, but 32 bits? WTF?! Anyway, the Dolby tracks play. Hurrah. I'll check the sndfile plug-in to see why it thinks it's 32 bit. [Update: Ouch - C is horrible, and if course it's hard to get past the literals!]

Let's see what the Bowie stuff looks like...

mpd.log has

Mar 22 12:18 : playlist: play 0:"http://192.168.1.3:9790/minimserver/*/pi/David*
20Bowie/Blackstar/02-*27Tis*20a*20Pity*20She*20Was*20a*20Whore.aif"
Mar 22 12:18 : decoder_thread: probing plugin sndfile
Mar 22 12:18 : decoder: audio_format=96000:32:2, seekable=true
Mar 22 12:18 : alsa_output: opened hw:1,0 type=HW
Mar 22 12:18 : alsa_output: format=S24_3LE (Signed 24 bit Little Endian in 3byte
s)
Mar 22 12:18 : alsa_output: buffer: size=192..174762 time=2000..1820438
Mar 22 12:18 : alsa_output: period: size=96..87381 time=1000..910219
Mar 22 12:18 : alsa_output: default period_time = buffer_time/4 = 500000/4 = 125
000
Mar 22 12:18 : alsa_output: buffer_size=48000 period_size=12000
Mar 22 12:18 : output: opened plugin=alsa name="ODACverB" audio_format=96000:24:
2
Mar 22 12:18 : output: converting from 96000:32:2
Mar 22 12:18 : player: played "http://192.168.1.3:9790/minimserver/*/pi/David*20
Bowie/Blackstar/02-*27Tis*20a*20Pity*20She*20Was*20a*20Whore.aif"
Mar 22 12:18 : playlist: stop

and then it doesn't play!

Minim server log has the following info:

12:19:39.463 Thread-459: HTTPConnection: reading HTTP request
12:19:39.463 Thread-459: GET /minimserver/*/pi/David*20Bowie/Blackstar/02-*27Tis*20a*20Pity*20She*20Was*20a*20Whore.aif HTTP/1.1
12:19:39.463 Thread-459: User-Agent: Music Player Daemon 0.19.1, Host: 192.168.1.3:9790, Accept: */*, Icy-Metadata: 1
12:19:39.463 Thread-459: HTTPConnection: reading HTTP request
12:19:39.463 Thread-458: HTTPConnection: writer thread processing request
12:19:39.467 Thread-458: HTTP/1.1 200 OK, Accept-Ranges: bytes, Date: Tue, 22 Mar 2016 12:19:39 GMT, Content-Length: 168631966, Content-Type: audio/x-aiff, Connection: keep-alive, Last-Modified: Sat, 19 Mar 2016 17:32:32 GMT
12:19:39.467 Thread-458: writing data: total=168631966 from file David Bowie/Blackstar/02-'Tis a Pity She Was a Whore.aif
12:19:39.467 Thread-458: writing 16384 bytes: total=168631966
12:19:39.468 Thread-458: writing 16384 bytes: total=168631966
12:19:39.468 Thread-458: writing 16384 bytes: total=168631966
12:19:39.468 Thread-458: writing 16384 bytes: total=168631966
12:19:39.469 Thread-459: HTTPConnection: connection closed by client
12:19:39.469 Thread-459: ServerResourceBase: forced socket close: Socket[addr=/192.168.1.3,port=41180,localport=9790]
12:19:39.470 Thread-459: HTTPService: removing connection org.jminim.lib.HTTPConnection@1d5878e

So we ask ourselves - why is MPD closing the stream?? There's nothing in the log to indicate why... Is it Kinsky?

Trying VLC from my Mac, it has no problem playing the Bowie stuff through the ODAC... Here's the listing from the Media Info panel. That also says that the data is 32 bit, but the codec is Big Endian!

http://192.168.1.3:9790/minimserver/*/pi/David*20Bowie/Blackstar/02-*27Tis*20a*20Pity*20She*20Was*20a*20Whore.aif

Thomas Dolby 
David Bowie
Interesting! Someone has to fix this. I'm assuming that the DAC has to get it in the right order, and it expects S16_LE and S24_3LE, not BE. Maybe that's why??

Experimenting with play reveals all.

24 bit 48k LE works on raw hardware:
pi@raspberrypi:/media/pi/Thomas Dolby/Oceanea EP $ aplay -D hw:1,0 -f S24_3LE -r 48000 01\ Oceanea.wav 
Playing WAVE '01 Oceanea.wav' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Stereo

Declaring BE doesn't work on the hardware interface, because it doesn't support it: 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -D hw:1,0 -f S24_BE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Big Endian, Rate 96000 Hz, Mono
aplay: set_params:1233: Sample format non available
Available formats:
- S16_LE
- S24_3LE

This produces white noise!! 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -c 2 -D hw:1,0 -f S24_3LE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Little Endian in 3bytes, Rate 96000 Hz, Stereo

This produces white noise, because it's not LE input 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -c 2 -D plughw:1,0 -f S24_3LE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Little Endian in 3bytes, Rate 96000 Hz, Stereo

This produces white noise, presumably because the byte size is wrong 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -c 2 -D plughw:1,0 -f S24_BE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Big Endian, Rate 96000 Hz, Stereo

This works, because the plug interface converts the BE to LE... 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -c 2 -D plughw:1,0 -f S24_3BE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Big Endian in 3bytes, Rate 96000 Hz, Stereo

This doesn't work because there's no decompressor for the FLAC - more white noise!! 
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -c 2 -D plughw:1,0 -f S24_3BE -r 96000 01-Blackstar.flac 
Playing raw data '01-Blackstar.flac' : Signed 24 bit Big Endian in 3bytes, Rate 96000 Hz, Stereo

And you can see the plug plug-in doing its thing...
pi@raspberrypi:/media/pi/David Bowie/Blackstar $ aplay -v -c 2 -D plughw:1,0 -f S24_3BE -r 96000 02-\'Tis\ a\ Pity\ She\ Was\ a\ Whore.aif 
Playing raw data '02-'Tis a Pity She Was a Whore.aif' : Signed 24 bit Big Endian in 3bytes, Rate 96000 Hz, Stereo
Plug PCM: Linear conversion PCM (S24_3LE)
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S24_3BE
  subformat    : STD
  channels     : 2
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 24
  buffer_size  : 48000
  period_size  : 12000
  period_time  : 125000
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 12000
  period_event : 0
  start_threshold  : 48000
  stop_threshold   : 48000
  silence_threshold: 0
  silence_size : 0
  boundary     : 1572864000
Slave: Hardware PCM card 1 'ODAC-revB' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : MMAP_INTERLEAVED
  format       : S24_3LE
  subformat    : STD
  channels     : 2
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 24
  buffer_size  : 48000
  period_size  : 12000
  period_time  : 125000
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 12000
  period_event : 0
  start_threshold  : 48000
  stop_threshold   : 48000
  silence_threshold: 0
  silence_size : 0
  boundary     : 1572864000
  appl_ptr     : 0

  hw_ptr       : 0

I wonder if the HDTracks website is aware of this kind of thing? Can I convert BE to LE without any resampling - in principle it's easy, in fact I could write a program to do it! But I don't want to.

Spent a LOT of time reading the plug.c source, but not obvious where format conversion is done. I can't be arsed. However, although aplay -D plughw:1,0 works for the Bowie S24_3BE material, that same setting doesn't work in mpd!! How strange. Let's try mpd on its own, pointed to the material, rather than minimserver, and see if that works. 

[Update: haven't made that work yet - still looking at the file format stuff]

No comments:

Post a Comment