diff options
-rw-r--r-- | apps/codecs/au.c | 63 | ||||
-rw-r--r-- | apps/codecs/libpcm/ieee_float.c | 10 | ||||
-rw-r--r-- | apps/codecs/libpcm/itut_g711.c | 17 | ||||
-rw-r--r-- | apps/codecs/libpcm/linear_pcm.c | 16 | ||||
-rw-r--r-- | apps/metadata/au.c | 73 |
5 files changed, 81 insertions, 98 deletions
diff --git a/apps/codecs/au.c b/apps/codecs/au.c index cf2a799be6..19348bc299 100644 --- a/apps/codecs/au.c +++ b/apps/codecs/au.c | |||
@@ -45,35 +45,17 @@ enum | |||
45 | AU_FORMAT_ALAW, /* G.711 ALAW */ | 45 | AU_FORMAT_ALAW, /* G.711 ALAW */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static int support_formats[28][2] = { | 48 | static const char support_formats[9][2] = { |
49 | { AU_FORMAT_UNSUPPORT, 0 }, | 49 | { AU_FORMAT_UNSUPPORT, 0 }, /* encoding */ |
50 | { AU_FORMAT_MULAW, 8 }, /* G.711 MULAW */ | 50 | { AU_FORMAT_MULAW, 8 }, /* 1: G.711 MULAW */ |
51 | { AU_FORMAT_PCM, 8 }, /* Linear PCM 8bit (signed) */ | 51 | { AU_FORMAT_PCM, 8 }, /* 2: Linear PCM 8bit (signed) */ |
52 | { AU_FORMAT_PCM, 16 }, /* Linear PCM 16bit (signed, big endian) */ | 52 | { AU_FORMAT_PCM, 16 }, /* 3: Linear PCM 16bit (signed, big endian) */ |
53 | { AU_FORMAT_PCM, 24 }, /* Linear PCM 24bit (signed, big endian) */ | 53 | { AU_FORMAT_PCM, 24 }, /* 4: Linear PCM 24bit (signed, big endian) */ |
54 | { AU_FORMAT_PCM, 32 }, /* Linear PCM 32bit (signed, big endian) */ | 54 | { AU_FORMAT_PCM, 32 }, /* 5: Linear PCM 32bit (signed, big endian) */ |
55 | { AU_FORMAT_IEEE_FLOAT, 32 }, /* Linear PCM float 32bit (signed, big endian) */ | 55 | { AU_FORMAT_IEEE_FLOAT, 32 }, /* 6: Linear PCM float 32bit (signed, big endian) */ |
56 | { AU_FORMAT_IEEE_FLOAT, 64 }, /* Linear PCM float 64bit (signed, big endian) */ | 56 | { AU_FORMAT_IEEE_FLOAT, 64 }, /* 7: Linear PCM float 64bit (signed, big endian) */ |
57 | { AU_FORMAT_UNSUPPORT, 0 }, /* Fragmented sample data */ | 57 | /* encoding 8 - 26 unsupported. */ |
58 | { AU_FORMAT_UNSUPPORT, 0 }, /* DSP program */ | 58 | { AU_FORMAT_ALAW, 8 }, /* 27: G.711 ALAW */ |
59 | { AU_FORMAT_UNSUPPORT, 0 }, /* 8bit fixed point */ | ||
60 | { AU_FORMAT_UNSUPPORT, 0 }, /* 16bit fixed point */ | ||
61 | { AU_FORMAT_UNSUPPORT, 0 }, /* 24bit fixed point */ | ||
62 | { AU_FORMAT_UNSUPPORT, 0 }, /* 32bit fixed point */ | ||
63 | { AU_FORMAT_UNSUPPORT, 0 }, | ||
64 | { AU_FORMAT_UNSUPPORT, 0 }, | ||
65 | { AU_FORMAT_UNSUPPORT, 0 }, | ||
66 | { AU_FORMAT_UNSUPPORT, 0 }, | ||
67 | { AU_FORMAT_UNSUPPORT, 0 }, /* 16bit linear with emphasis */ | ||
68 | { AU_FORMAT_UNSUPPORT, 0 }, /* 16bit linear compressed */ | ||
69 | { AU_FORMAT_UNSUPPORT, 0 }, /* 16bit linear with emphasis and compression */ | ||
70 | { AU_FORMAT_UNSUPPORT, 0 }, /* Music kit DSP commands */ | ||
71 | { AU_FORMAT_UNSUPPORT, 0 }, | ||
72 | { AU_FORMAT_UNSUPPORT, 0 }, /* G.721 MULAW */ | ||
73 | { AU_FORMAT_UNSUPPORT, 0 }, /* G.722 */ | ||
74 | { AU_FORMAT_UNSUPPORT, 0 }, /* G.723 3bit */ | ||
75 | { AU_FORMAT_UNSUPPORT, 0 }, /* G.723 5bit */ | ||
76 | { AU_FORMAT_ALAW, 8 }, /* G.711 ALAW */ | ||
77 | }; | 59 | }; |
78 | 60 | ||
79 | const struct pcm_entry au_codecs[] = { | 61 | const struct pcm_entry au_codecs[] = { |
@@ -108,16 +90,17 @@ static unsigned int get_be32(uint8_t *buf) | |||
108 | 90 | ||
109 | static int convert_au_format(unsigned int encoding, struct pcm_format *fmt) | 91 | static int convert_au_format(unsigned int encoding, struct pcm_format *fmt) |
110 | { | 92 | { |
111 | if (encoding > 27) | 93 | fmt->formattag = AU_FORMAT_UNSUPPORT; |
112 | { | 94 | if (encoding < 8) |
113 | fmt->formattag = AU_FORMAT_UNSUPPORT; | ||
114 | fmt->bitspersample = 0; | ||
115 | } | ||
116 | else | ||
117 | { | 95 | { |
118 | fmt->formattag = support_formats[encoding][0]; | 96 | fmt->formattag = support_formats[encoding][0]; |
119 | fmt->bitspersample = support_formats[encoding][1]; | 97 | fmt->bitspersample = support_formats[encoding][1]; |
120 | } | 98 | } |
99 | else if (encoding == 27) | ||
100 | { | ||
101 | fmt->formattag = support_formats[8][0]; | ||
102 | fmt->bitspersample = support_formats[8][1]; | ||
103 | } | ||
121 | 104 | ||
122 | return fmt->formattag; | 105 | return fmt->formattag; |
123 | } | 106 | } |
@@ -138,7 +121,7 @@ enum codec_status codec_main(void) | |||
138 | int offset = 0; | 121 | int offset = 0; |
139 | 122 | ||
140 | /* Generic codec initialisation */ | 123 | /* Generic codec initialisation */ |
141 | ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH); | 124 | ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1); |
142 | 125 | ||
143 | next_track: | 126 | next_track: |
144 | if (codec_init()) { | 127 | if (codec_init()) { |
@@ -199,11 +182,6 @@ next_track: | |||
199 | } | 182 | } |
200 | /* skip sample rate */ | 183 | /* skip sample rate */ |
201 | format.channels = get_be32(buf + 20); | 184 | format.channels = get_be32(buf + 20); |
202 | if (format.channels == 0) { | ||
203 | DEBUGF("CODEC_ERROR: sun audio 0-channels file\n"); | ||
204 | status = CODEC_ERROR; | ||
205 | goto done; | ||
206 | } | ||
207 | } | 185 | } |
208 | 186 | ||
209 | /* advance to first WAVE chunk */ | 187 | /* advance to first WAVE chunk */ |
@@ -215,9 +193,6 @@ next_track: | |||
215 | codec = 0; | 193 | codec = 0; |
216 | bytesdone = 0; | 194 | bytesdone = 0; |
217 | 195 | ||
218 | /* blockalign = 1 sample */ | ||
219 | format.blockalign = format.bitspersample * format.channels >> 3; | ||
220 | |||
221 | /* get codec */ | 196 | /* get codec */ |
222 | codec = get_au_codec(format.formattag); | 197 | codec = get_au_codec(format.formattag); |
223 | if (!codec) | 198 | if (!codec) |
diff --git a/apps/codecs/libpcm/ieee_float.c b/apps/codecs/libpcm/ieee_float.c index 0530993f31..7e3498edcb 100644 --- a/apps/codecs/libpcm/ieee_float.c +++ b/apps/codecs/libpcm/ieee_float.c | |||
@@ -32,6 +32,12 @@ static bool set_format(struct pcm_format *format) | |||
32 | { | 32 | { |
33 | fmt = format; | 33 | fmt = format; |
34 | 34 | ||
35 | if (fmt->channels == 0) | ||
36 | { | ||
37 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
38 | return false; | ||
39 | } | ||
40 | |||
35 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) | 41 | if (fmt->bitspersample != 32 && fmt->bitspersample != 64) |
36 | { | 42 | { |
37 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample: %d\n", | 43 | DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample: %d\n", |
@@ -40,6 +46,10 @@ static bool set_format(struct pcm_format *format) | |||
40 | } | 46 | } |
41 | 47 | ||
42 | fmt->bytespersample = fmt->bitspersample >> 3; | 48 | fmt->bytespersample = fmt->bitspersample >> 3; |
49 | |||
50 | if (fmt->blockalign == 0) | ||
51 | fmt->blockalign = fmt->bytespersample * fmt->channels; | ||
52 | |||
43 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); | 53 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); |
44 | 54 | ||
45 | /* chunksize = about 1/50[sec] data */ | 55 | /* chunksize = about 1/50[sec] data */ |
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c index 4644a9c694..097dd5cc25 100644 --- a/apps/codecs/libpcm/itut_g711.c +++ b/apps/codecs/libpcm/itut_g711.c | |||
@@ -112,6 +112,12 @@ static bool set_format(struct pcm_format *format) | |||
112 | { | 112 | { |
113 | fmt = format; | 113 | fmt = format; |
114 | 114 | ||
115 | if (fmt->channels == 0) | ||
116 | { | ||
117 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
118 | return false; | ||
119 | } | ||
120 | |||
115 | if (fmt->bitspersample != 8) | 121 | if (fmt->bitspersample != 8) |
116 | { | 122 | { |
117 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n", | 123 | DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n", |
@@ -119,13 +125,12 @@ static bool set_format(struct pcm_format *format) | |||
119 | return false; | 125 | return false; |
120 | } | 126 | } |
121 | 127 | ||
122 | if (fmt->totalsamples == 0) | 128 | fmt->bytespersample = 1; |
123 | { | 129 | |
124 | fmt->bytespersample = 1; | 130 | if (fmt->blockalign == 0) |
125 | fmt->totalsamples = fmt->numbytes / (fmt->bytespersample * fmt->channels); | 131 | fmt->blockalign = fmt->channels; |
126 | } | ||
127 | 132 | ||
128 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); | 133 | fmt->samplesperblock = fmt->blockalign / fmt->channels; |
129 | 134 | ||
130 | /* chunksize = about 1/50[sec] data */ | 135 | /* chunksize = about 1/50[sec] data */ |
131 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) | 136 | fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock)) |
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c index 82c70eb3b6..e58856efe8 100644 --- a/apps/codecs/libpcm/linear_pcm.c +++ b/apps/codecs/libpcm/linear_pcm.c | |||
@@ -38,6 +38,18 @@ static bool set_format(struct pcm_format *format) | |||
38 | { | 38 | { |
39 | fmt = format; | 39 | fmt = format; |
40 | 40 | ||
41 | if (fmt->channels == 0) | ||
42 | { | ||
43 | DEBUGF("CODEC_ERROR: channels is 0\n"); | ||
44 | return false; | ||
45 | } | ||
46 | |||
47 | if (fmt->bitspersample == 0) | ||
48 | { | ||
49 | DEBUGF("CODEC_ERROR: bitspersample is 0\n"); | ||
50 | return false; | ||
51 | } | ||
52 | |||
41 | if (fmt->bitspersample > 32) | 53 | if (fmt->bitspersample > 32) |
42 | { | 54 | { |
43 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " | 55 | DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " |
@@ -47,8 +59,8 @@ static bool set_format(struct pcm_format *format) | |||
47 | 59 | ||
48 | fmt->bytespersample = fmt->bitspersample >> 3; | 60 | fmt->bytespersample = fmt->bitspersample >> 3; |
49 | 61 | ||
50 | if (fmt->totalsamples == 0) | 62 | if (fmt->blockalign == 0) |
51 | fmt->totalsamples = fmt->numbytes/fmt->bytespersample; | 63 | fmt->blockalign = fmt->bytespersample * fmt->channels; |
52 | 64 | ||
53 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); | 65 | fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels); |
54 | 66 | ||
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 */ | 31 | static const unsigned char bitspersamples[9] = { |
34 | static 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 | ||
65 | static inline unsigned char get_au_bitspersample(unsigned int encoding) | 44 | static 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 | ||
72 | bool get_au_metadata(int fd, struct mp3entry* id3) | 54 | bool 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 | } |