summaryrefslogtreecommitdiff
path: root/apps/metadata/au.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/metadata/au.c')
-rw-r--r--apps/metadata/au.c73
1 files changed, 27 insertions, 46 deletions
diff --git a/apps/metadata/au.c b/apps/metadata/au.c
index 0639bd11e6..94e7453644 100644
--- a/apps/metadata/au.c
+++ b/apps/metadata/au.c
@@ -20,8 +20,6 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdio.h> 21#include <stdio.h>
22#include <string.h> 22#include <string.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include <inttypes.h> 23#include <inttypes.h>
26 24
27#include "system.h" 25#include "system.h"
@@ -30,62 +28,42 @@
30#include "metadata_parsers.h" 28#include "metadata_parsers.h"
31#include "logf.h" 29#include "logf.h"
32 30
33/* table of bits per sample / 8 */ 31static const unsigned char bitspersamples[9] = {
34static const unsigned char bitspersamples[28] = { 32 0, /* encoding */
35 0, 33 8, /* 1: G.711 MULAW */
36 1, /* G.711 MULAW */ 34 8, /* 2: Linear PCM 8bit */
37 1, /* 8bit */ 35 16, /* 3: Linear PCM 16bit */
38 2, /* 16bit */ 36 24, /* 4: Linear PCM 24bit */
39 3, /* 24bit */ 37 32, /* 5: Linear PCM 32bit */
40 4, /* 32bit */ 38 32, /* 6: IEEE float 32bit */
41 4, /* 32bit */ 39 64, /* 7: IEEE float 64bit */
42 8, /* 64bit */ 40 /* encoding 8 - 26 unsupported. */
43 0, /* Fragmented sample data */ 41 8, /* 27: G.711 ALAW */
44 0, /* DSP program */
45 0, /* 8bit fixed point */
46 0, /* 16bit fixed point */
47 0, /* 24bit fixed point */
48 0, /* 32bit fixed point */
49 0,
50 0,
51 0,
52 0,
53 0, /* 16bit linear with emphasis */
54 0, /* 16bit linear compressed */
55 0, /* 16bit linear with emphasis and compression */
56 0, /* Music kit DSP commands */
57 0,
58 0, /* G.721 MULAW */
59 0, /* G.722 */
60 0, /* G.723 3bit */
61 0, /* G.723 5bit */
62 1, /* G.711 ALAW */
63}; 42};
64 43
65static inline unsigned char get_au_bitspersample(unsigned int encoding) 44static inline unsigned char get_au_bitspersample(unsigned int encoding)
66{ 45{
67 if (encoding > 27) 46 if (encoding < 8)
68 return 0; 47 return bitspersamples[encoding];
69 return bitspersamples[encoding]; 48 else if (encoding == 27)
49 return bitspersamples[8];
50
51 return 0;
70} 52}
71 53
72bool get_au_metadata(int fd, struct mp3entry* id3) 54bool get_au_metadata(int fd, struct mp3entry* id3)
73{ 55{
74 /* Use the trackname part of the id3 structure as a temporary buffer */ 56 /* temporary buffer */
75 unsigned char* buf = (unsigned char *)id3->path; 57 unsigned char* buf = (unsigned char *)id3->path;
76 unsigned long numbytes = 0; 58 unsigned long numbytes = 0;
77 int read_bytes;
78 int offset; 59 int offset;
79 unsigned char bits_ch; /* bitspersample * channels */
80 60
81 id3->vbr = false; /* All Sun audio files are CBR */ 61 id3->vbr = false; /* All Sun audio files are CBR */
82 id3->filesize = filesize(fd); 62 id3->filesize = filesize(fd);
83 id3->length = 0; 63 id3->length = 0;
84 64
85 if ((lseek(fd, 0, SEEK_SET) < 0) || ((read_bytes = read(fd, buf, 24)) < 0)) 65 lseek(fd, 0, SEEK_SET);
86 return false; 66 if ((read(fd, buf, 24) < 24) || (memcmp(buf, ".snd", 4) != 0))
87
88 if (read_bytes < 24 || (memcmp(buf, ".snd", 4) != 0))
89 { 67 {
90 /* 68 /*
91 * no header 69 * no header
@@ -96,10 +74,12 @@ bool get_au_metadata(int fd, struct mp3entry* id3)
96 */ 74 */
97 numbytes = id3->filesize; 75 numbytes = id3->filesize;
98 id3->frequency = 8000; 76 id3->frequency = 8000;
99 bits_ch = 1; 77 id3->bitrate = 8;
100 } 78 }
101 else 79 else
102 { 80 {
81 /* parse header */
82
103 /* data offset */ 83 /* data offset */
104 offset = get_long_be(buf + 4); 84 offset = get_long_be(buf + 4);
105 if (offset < 24) 85 if (offset < 24)
@@ -112,13 +92,14 @@ bool get_au_metadata(int fd, struct mp3entry* id3)
112 if (numbytes == (uint32_t)0xffffffff) 92 if (numbytes == (uint32_t)0xffffffff)
113 numbytes = id3->filesize - offset; 93 numbytes = id3->filesize - offset;
114 94
115 bits_ch = get_au_bitspersample(get_long_be(buf + 12)) * get_long_be(buf + 20);
116 id3->frequency = get_long_be(buf + 16); 95 id3->frequency = get_long_be(buf + 16);
96 id3->bitrate = get_au_bitspersample(get_long_be(buf + 12)) * get_long_be(buf + 20)
97 * id3->frequency / 1000;
117 } 98 }
118 99
119 /* Calculate track length [ms] */ 100 /* Calculate track length [ms] */
120 if (bits_ch) 101 if (id3->bitrate)
121 id3->length = ((int64_t)numbytes * 1000LL) / (bits_ch * id3->frequency); 102 id3->length = (numbytes << 3) / id3->bitrate;
122 103
123 return true; 104 return true;
124} 105}