FU Logo
  • Startseite
  • Kontakt
  • Impressum
  • Home
  • Listenauswahl
  • Anleitungen

Re: [linux-minidisc] netmd/netmdcli: download support for any .wav file containing pcm audio

<-- thread -->
<-- date -->
  • From: Thomas Arp <manner.moe@gmx.de>
  • To: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • Date: Thu, 02 Jan 2014 22:59:08 +0100
  • Cc: "linux-minidisc@lists.fu-berlin.de" <linux-minidisc@lists.fu-berlin.de>
  • Subject: Re: [linux-minidisc] netmd/netmdcli: download support for any .wav file containing pcm audio

Am 01.01.2014 23:30, schrieb Michael Karcher:
The only valid combinations are
PCM -> SP
LP2 -> LP2
LP4 -> LP4
I don't remember whether PCM -> SP Mono support is consistently
implemented in all NetMD devices.

Regards,
   Michael Karcher

O.K., i added a function examining the fmt chunk and set correct wireformat/diskformat values btw. if byte order conversion is needed.
Netmd download should work now for all supported audio files.

I also added pcm mono (8 bit)  -> Atrac SP mono.
I don't know if this works, needs some testing.
I do not have any LP4 tracks, this needs some testing, too.

Thomas

P.S.: Apply this patch after the other 2.


>From c0380ed5bb6dc01b3e6930a4d65d45e04ecad609 Mon Sep 17 00:00:00 2001
From: Thomas Arp <manner.moe@gmx.de>
Date: Thu, 2 Jan 2014 22:40:08 +0100
Subject: [PATCH 3/3] netmdcli: implemented netmd download for all supported
 audio formats

---
 netmdcli/netmdcli.c |   78 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 65 insertions(+), 13 deletions(-)

diff --git a/netmdcli/netmdcli.c b/netmdcli/netmdcli.c
index fb54289..e58c35e 100644
--- a/netmdcli/netmdcli.c
+++ b/netmdcli/netmdcli.c
@@ -173,6 +173,11 @@ static inline unsigned int leword32(const unsigned char * c)
     return c[3]*16777216+c[2]*65536+c[1]*256+c[0];
 }
 
+static inline unsigned int leword16(const unsigned char * c)
+{
+    return c[1]*256+c[0];
+}
+
 static int wav_data_position(const char * data, size_t len)
 {
     int pos = -1, i = 0;
@@ -181,13 +186,55 @@ static int wav_data_position(const char * data, size_t len)
         if(i >= len-4) // break at end of data
             break;
 
-        if(strcmp("data", data+i) == 0)
+        if(strncmp("data", data+i, 4) == 0)
             pos = i;
         i+=2;
     }
     return pos;
 }
 
+static int audio_supported(const char * file, netmd_wireformat * wireformat, unsigned int * discformat, int * conversion)
+{
+    if(strncmp("RIFF", file, 4) != 0 || strncmp("WAVE", file+8, 4) != 0 || strncmp("fmt ", file+12, 4) != 0)
+        return 0;    /* no valid WAVE file or fmt chunk missing*/
+
+    if(leword16(file+20) == 1)                                      /* PCM */
+    {
+        *conversion = 1;                                             /* need byte order conversion for pcm raw data*/
+        *wireformat = NETMD_WIREFORMAT_PCM;
+        if(leword32(file+24) != 44100)                               /* sample rate */
+            return 0;
+        if(leword16(file+22) == 1 && leword16(file+34) == 8)         /* mono, 8bit */
+            *discformat = NETMD_DISKFORMAT_SP_MONO;
+        else if(leword16(file+22) == 2 && leword16(file+34) == 16)   /* stereo, 16 bit */
+            *discformat = NETMD_DISKFORMAT_SP_STEREO;
+        else
+            return 0;
+        return 1;
+    }
+
+    if(leword16(file+20) == NETMD_RIFF_FORMAT_TAG_ATRAC3)   /* ATRAC3 */
+    {
+        *conversion = 0;                                     /* byte order conversion not needed */
+        if(leword32(file+24) != 44100)                       /* sample rate */
+            return 0;
+        if(leword16(file+32) == 384)                         /* data block size LP2 */
+        {
+            *wireformat = NETMD_WIREFORMAT_LP2;
+            *discformat = NETMD_DISKFORMAT_LP2;
+        }
+        else if(leword16(file+32) == 192)                    /* data block size LP4 */
+        {
+            *wireformat = NETMD_WIREFORMAT_LP4;
+            *discformat = NETMD_DISKFORMAT_LP4;
+        }
+        else
+            return 0;
+        return 1;
+    }
+    return 0;
+}
+
 int main(int argc, char* argv[])
 {
     netmd_dev_handle* devh;
@@ -467,10 +514,10 @@ int main(int argc, char* argv[])
             char title[256] = {0};
 
             size_t frames;
-            int data_position, audio_data_position, audio_data_size, i, file_valid = 0;
+            int data_position, audio_data_position, audio_data_size, i, need_conversion = 1, file_valid = 0;
             unsigned char * audio_data;
-            netmd_wireformat wireformat = NETMD_WIREFORMAT_PCM;
-            unsigned char discformat = NETMD_DISKFORMAT_SP_STEREO;
+            netmd_wireformat wireformat;
+            unsigned char discformat;
 
             /* read source */
             stat(argv[2], &stat_buf);
@@ -480,18 +527,20 @@ int main(int argc, char* argv[])
             fread(data, data_size, 1, f);
             fclose(f);
 
-            /* TODO: check file for codec, PCM (16 bit, 44100 Hz, stereo) should work correctly*/
-            if((data_position = wav_data_position((char *)data, data_size)) <= 0)
+            file_valid = audio_supported(data, &wireformat, &discformat, &need_conversion);
+            data_position = wav_data_position(data, data_size);
+
+            if(!file_valid || !data_position)
             {
-                puts("Error: invalid audio file, cannot find data header position");
+                puts("Error: audio file not supported");
                 free(data);
+                file_valid = 0;
             }
             else
             {
                 audio_data_position = data_position+8;
                 audio_data = data+audio_data_position;
                 audio_data_size = leword32(data+(data_position+4));
-                file_valid = 1;
             }
 
             if(file_valid)
@@ -554,12 +603,15 @@ int main(int argc, char* argv[])
                 error = netmd_secure_setup_download(devh, contentid, kek, sessionkey);
                 puts(netmd_strerror(error));
 
-                /* audio data byte order conversion, .wav files are little endian, need big endian for pcm raw data*/
-                for(i = 0; i < audio_data_size; i+=2)
+                /* audio data byte order conversion */
+                if(need_conversion)
                 {
-                    unsigned char first = audio_data[i];
-                    audio_data[i] = audio_data[i+1];
-                    audio_data[i+1] = first;
+                    for(i = 0; i < audio_data_size; i+=2)
+                    {
+                        unsigned char first = audio_data[i];
+                        audio_data[i] = audio_data[i+1];
+                        audio_data[i+1] = first;
+                    }
                 }
 
                 /* netmd_prepare_packets() sets correct number of frames depending on the wire format */
-- 
1.7.10.4

<-- thread -->
<-- date -->
  • References:
    • [linux-minidisc] netmd/netmdcli: download support for any .wav file containing pcm audio
      • From: Thomas Arp <manner.moe@gmx.de>
    • Re: [linux-minidisc] netmd/netmdcli: download support for any .wav file containing pcm audio
      • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • linux-minidisc - January 2014 - Archives indexes sorted by:
    [ thread ] [ subject ] [ author ] [ date ]
  • Complete archive of the linux-minidisc mailing list
  • More info on this list...

Hilfe

  • FAQ
  • Dienstbeschreibung
  • ZEDAT Beratung
  • postmaster@lists.fu-berlin.de

Service-Navigation

  • Startseite
  • Listenauswahl

Einrichtung Mailingliste

  • ZEDAT-Portal
  • Mailinglisten Portal