diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/libasf/asf.h | 3 | ||||
-rw-r--r-- | apps/codecs/libwmavoice/SOURCES | 17 | ||||
-rw-r--r-- | apps/codecs/libwmavoice/libwmavoice.make | 37 | ||||
-rw-r--r-- | apps/codecs/libwmavoice/wmavoice.c | 33 | ||||
-rw-r--r-- | apps/codecs/libwmavoice/wmavoice.h | 7 | ||||
-rw-r--r-- | apps/codecs/wmavoice.c | 195 | ||||
-rw-r--r-- | apps/metadata.c | 5 | ||||
-rw-r--r-- | apps/metadata.h | 1 | ||||
-rw-r--r-- | apps/metadata/asf.c | 5 |
9 files changed, 296 insertions, 7 deletions
diff --git a/apps/codecs/libasf/asf.h b/apps/codecs/libasf/asf.h index b0adb7dfc7..a7d384cf3d 100644 --- a/apps/codecs/libasf/asf.h +++ b/apps/codecs/libasf/asf.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define ASF_CODEC_ID_WMAV1 0x160 | 7 | #define ASF_CODEC_ID_WMAV1 0x160 |
8 | #define ASF_CODEC_ID_WMAV2 0x161 | 8 | #define ASF_CODEC_ID_WMAV2 0x161 |
9 | #define ASF_CODEC_ID_WMAPRO 0x162 | 9 | #define ASF_CODEC_ID_WMAPRO 0x162 |
10 | #define ASF_CODEC_ID_WMAVOICE 0x00A | ||
10 | 11 | ||
11 | enum asf_error_e { | 12 | enum asf_error_e { |
12 | ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ | 13 | ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ |
@@ -33,7 +34,7 @@ struct asf_waveformatex_s { | |||
33 | uint16_t bitspersample; | 34 | uint16_t bitspersample; |
34 | uint16_t datalen; | 35 | uint16_t datalen; |
35 | uint16_t numpackets; | 36 | uint16_t numpackets; |
36 | uint8_t data[18]; | 37 | uint8_t data[46]; |
37 | }; | 38 | }; |
38 | typedef struct asf_waveformatex_s asf_waveformatex_t; | 39 | typedef struct asf_waveformatex_s asf_waveformatex_t; |
39 | 40 | ||
diff --git a/apps/codecs/libwmavoice/SOURCES b/apps/codecs/libwmavoice/SOURCES new file mode 100644 index 0000000000..c98821c42a --- /dev/null +++ b/apps/codecs/libwmavoice/SOURCES | |||
@@ -0,0 +1,17 @@ | |||
1 | acelp_filters.c | ||
2 | acelp_vectors.c | ||
3 | avfft.c | ||
4 | bitstream.c | ||
5 | celp_filters.c | ||
6 | celp_math.c | ||
7 | dct.c | ||
8 | fft.c | ||
9 | lsp.c | ||
10 | mdct.c | ||
11 | rdft.c | ||
12 | utils.c | ||
13 | wmavoice.c | ||
14 | libavutil/log.c | ||
15 | libavutil/lzo.c | ||
16 | libavutil/mem.c | ||
17 | libavutil/mathematics.c | ||
diff --git a/apps/codecs/libwmavoice/libwmavoice.make b/apps/codecs/libwmavoice/libwmavoice.make new file mode 100644 index 0000000000..0497e18e1b --- /dev/null +++ b/apps/codecs/libwmavoice/libwmavoice.make | |||
@@ -0,0 +1,37 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id: libwmavoice.make 27586 2010-07-27 06:48:15Z nls $ | ||
8 | # | ||
9 | |||
10 | # libwmavoice | ||
11 | WMAVOICELIB := $(CODECDIR)/libwmavoice.a | ||
12 | WMAVOICELIB_SRC := $(call preprocess, $(APPSDIR)/codecs/libwmavoice/SOURCES) | ||
13 | WMAVOICELIB_OBJ := $(call c2obj, $(WMAVOICELIB_SRC)) | ||
14 | OTHER_SRC += $(WMAVOICELIB_SRC) | ||
15 | |||
16 | $(WMAVOICELIB): $(WMAVOICELIB_OBJ) | ||
17 | $(SILENT)$(shell rm -f $@) | ||
18 | $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null | ||
19 | |||
20 | WMAVOICEFLAGS = -I$(APPSDIR)/codecs/libwmavoice $(filter-out -O%,$(CODECFLAGS)) | ||
21 | |||
22 | ifeq ($(CPU),coldfire) | ||
23 | WMAVOICEFLAGS += -O2 | ||
24 | else | ||
25 | WMAVOICEFLAGS += -O1 | ||
26 | endif | ||
27 | |||
28 | ifeq ($(APP_TYPE),sdl-sim) | ||
29 | # wmavoice needs libm in the simulator | ||
30 | $(CODECDIR)/wmavoice.codec: $(CODECDIR)/wmavoice.o | ||
31 | $(call PRINTS,LD $(@F))$(CC) $(CODECFLAGS) -o $(CODECDIR)/wmavoice.elf \ | ||
32 | $(filter %.o, $^) \ | ||
33 | $(filter %.a, $+) \ | ||
34 | -lgcc -lm $(CODECLDFLAGS) | ||
35 | $(SILENT)cp $(CODECDIR)/wmavoice.elf $@ | ||
36 | endif | ||
37 | |||
diff --git a/apps/codecs/libwmavoice/wmavoice.c b/apps/codecs/libwmavoice/wmavoice.c index 39bcb0e04e..f8bd6d656e 100644 --- a/apps/codecs/libwmavoice/wmavoice.c +++ b/apps/codecs/libwmavoice/wmavoice.c | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <math.h> | 28 | #include <math.h> |
29 | #include "avcodec.h" | 29 | #include "wmavoice.h" |
30 | #include "get_bits.h" | 30 | #include "get_bits.h" |
31 | #include "put_bits.h" | 31 | #include "put_bits.h" |
32 | #include "wmavoice_data.h" | 32 | #include "wmavoice_data.h" |
@@ -286,6 +286,10 @@ typedef struct { | |||
286 | */ | 286 | */ |
287 | } WMAVoiceContext; | 287 | } WMAVoiceContext; |
288 | 288 | ||
289 | /* global decode context */ | ||
290 | static WMAVoiceContext globWMAVoiceCtx; | ||
291 | |||
292 | |||
289 | /** | 293 | /** |
290 | * Set up the variable bit mode (VBM) tree from container extradata. | 294 | * Set up the variable bit mode (VBM) tree from container extradata. |
291 | * @param gb bit I/O context. | 295 | * @param gb bit I/O context. |
@@ -330,9 +334,10 @@ static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25]) | |||
330 | /** | 334 | /** |
331 | * Set up decoder with parameters from demuxer (extradata etc.). | 335 | * Set up decoder with parameters from demuxer (extradata etc.). |
332 | */ | 336 | */ |
333 | static av_cold int wmavoice_decode_init(AVCodecContext *ctx) | 337 | av_cold int wmavoice_decode_init(AVCodecContext *ctx) |
334 | { | 338 | { |
335 | int n, flags, pitch_range, lsp16_flag; | 339 | int n, flags, pitch_range, lsp16_flag; |
340 | ctx->priv_data = &globWMAVoiceCtx; | ||
336 | WMAVoiceContext *s = ctx->priv_data; | 341 | WMAVoiceContext *s = ctx->priv_data; |
337 | 342 | ||
338 | /** | 343 | /** |
@@ -1743,7 +1748,7 @@ static int synth_superframe(AVCodecContext *ctx, | |||
1743 | * the wild yet. */ | 1748 | * the wild yet. */ |
1744 | if (!get_bits1(gb)) { | 1749 | if (!get_bits1(gb)) { |
1745 | av_log_missing_feature(ctx, "WMAPro-in-WMAVoice support", 1); | 1750 | av_log_missing_feature(ctx, "WMAPro-in-WMAVoice support", 1); |
1746 | return -1; | 1751 | return ERROR_WMAPRO_IN_WMAVOICE; |
1747 | } | 1752 | } |
1748 | 1753 | ||
1749 | /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */ | 1754 | /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */ |
@@ -1893,7 +1898,7 @@ static void copy_bits(PutBitContext *pb, | |||
1893 | * | 1898 | * |
1894 | * For more information about frames, see #synth_superframe(). | 1899 | * For more information about frames, see #synth_superframe(). |
1895 | */ | 1900 | */ |
1896 | static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, | 1901 | int wmavoice_decode_packet(AVCodecContext *ctx, void *data, |
1897 | int *data_size, AVPacket *avpkt) | 1902 | int *data_size, AVPacket *avpkt) |
1898 | { | 1903 | { |
1899 | WMAVoiceContext *s = ctx->priv_data; | 1904 | WMAVoiceContext *s = ctx->priv_data; |
@@ -1936,6 +1941,15 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, | |||
1936 | s->sframe_cache_size += s->spillover_nbits; | 1941 | s->sframe_cache_size += s->spillover_nbits; |
1937 | if ((res = synth_superframe(ctx, data, data_size)) == 0 && | 1942 | if ((res = synth_superframe(ctx, data, data_size)) == 0 && |
1938 | *data_size > 0) { | 1943 | *data_size > 0) { |
1944 | /* convert the float values to int32 for rockbox */ | ||
1945 | int i; | ||
1946 | int32_t *iptr = data; | ||
1947 | float *fptr = data; | ||
1948 | for(i = 0; i < *data_size/sizeof(float); i++) | ||
1949 | { | ||
1950 | fptr[i] *= (float)(INT32_MAX); | ||
1951 | iptr[i] = (int32_t)fptr[i]; | ||
1952 | } | ||
1939 | cnt += s->spillover_nbits; | 1953 | cnt += s->spillover_nbits; |
1940 | s->skip_bits_next = cnt & 7; | 1954 | s->skip_bits_next = cnt & 7; |
1941 | return cnt >> 3; | 1955 | return cnt >> 3; |
@@ -1957,12 +1971,21 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, | |||
1957 | } else if (*data_size > 0) { | 1971 | } else if (*data_size > 0) { |
1958 | int cnt = get_bits_count(gb); | 1972 | int cnt = get_bits_count(gb); |
1959 | s->skip_bits_next = cnt & 7; | 1973 | s->skip_bits_next = cnt & 7; |
1974 | /* convert the float values to int32 for rockbox */ | ||
1975 | int i; | ||
1976 | int32_t *iptr = data; | ||
1977 | float *fptr = data; | ||
1978 | for(i = 0; i < *data_size/sizeof(float); i++) | ||
1979 | { | ||
1980 | fptr[i] *= (float)(INT32_MAX); | ||
1981 | iptr[i] = (int32_t)fptr[i]; | ||
1982 | } | ||
1960 | return cnt >> 3; | 1983 | return cnt >> 3; |
1961 | } else if ((s->sframe_cache_size = pos) > 0) { | 1984 | } else if ((s->sframe_cache_size = pos) > 0) { |
1962 | /* rewind bit reader to start of last (incomplete) superframe... */ | 1985 | /* rewind bit reader to start of last (incomplete) superframe... */ |
1963 | init_get_bits(gb, avpkt->data, size << 3); | 1986 | init_get_bits(gb, avpkt->data, size << 3); |
1964 | skip_bits_long(gb, (size << 3) - pos); | 1987 | skip_bits_long(gb, (size << 3) - pos); |
1965 | assert(get_bits_left(gb) == pos); | 1988 | //assert(get_bits_left(gb) == pos); |
1966 | 1989 | ||
1967 | /* ...and cache it for spillover in next packet */ | 1990 | /* ...and cache it for spillover in next packet */ |
1968 | init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE); | 1991 | init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE); |
diff --git a/apps/codecs/libwmavoice/wmavoice.h b/apps/codecs/libwmavoice/wmavoice.h new file mode 100644 index 0000000000..33ec72b4e2 --- /dev/null +++ b/apps/codecs/libwmavoice/wmavoice.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #include "avcodec.h" | ||
2 | |||
3 | #define ERROR_WMAPRO_IN_WMAVOICE -0x162 | ||
4 | |||
5 | av_cold int wmavoice_decode_init(AVCodecContext *ctx); | ||
6 | int wmavoice_decode_packet(AVCodecContext *ctx, void *data, | ||
7 | int *data_size, AVPacket *avpkt); | ||
diff --git a/apps/codecs/wmavoice.c b/apps/codecs/wmavoice.c new file mode 100644 index 0000000000..904af23b99 --- /dev/null +++ b/apps/codecs/wmavoice.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Mohamed Tarek | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "codeclib.h" | ||
23 | #include "libasf/asf.h" | ||
24 | #include "libwmavoice/wmavoice.h" | ||
25 | |||
26 | CODEC_HEADER | ||
27 | |||
28 | static AVCodecContext avctx; | ||
29 | static AVPacket avpkt; | ||
30 | |||
31 | #define MAX_FRAMES 3 /*maximum number of frames per superframe*/ | ||
32 | #define MAX_FRAMESIZE 160 /* maximum number of samples per frame */ | ||
33 | #define BUFSIZE MAX_FRAMES*MAX_FRAMESIZE | ||
34 | static int32_t decoded[BUFSIZE] IBSS_ATTR; | ||
35 | |||
36 | |||
37 | /* This function initialises AVCodecContext with the data needed for the wmapro | ||
38 | * decoder to work. The required data is taken from asf_waveformatex_t because that's | ||
39 | * what the rockbox asf metadata parser fill/work with. In the future, when the | ||
40 | * codec is being optimised for on-target playback this function should not be needed. */ | ||
41 | static void init_codec_ctx(AVCodecContext *avctx, asf_waveformatex_t *wfx) | ||
42 | { | ||
43 | /* Copy the extra-data */ | ||
44 | avctx->extradata_size = wfx->datalen; | ||
45 | avctx->extradata = (uint8_t *)malloc(wfx->datalen*sizeof(uint8_t)); | ||
46 | memcpy(avctx->extradata, wfx->data, wfx->datalen*sizeof(uint8_t)); | ||
47 | |||
48 | avctx->block_align = wfx->blockalign; | ||
49 | avctx->sample_rate = wfx->rate; | ||
50 | avctx->channels = wfx->channels; | ||
51 | |||
52 | } | ||
53 | |||
54 | /* this is the codec entry point */ | ||
55 | enum codec_status codec_main(void) | ||
56 | { | ||
57 | uint32_t elapsedtime; | ||
58 | int retval; | ||
59 | asf_waveformatex_t wfx; /* Holds the stream properties */ | ||
60 | size_t resume_offset; | ||
61 | int res; /* Return values from asf_read_packet() and decode_packet() */ | ||
62 | uint8_t* audiobuf; /* Pointer to the payload of one wma pro packet */ | ||
63 | int audiobufsize; /* Payload size */ | ||
64 | int packetlength = 0; /* Logical packet size (minus the header size) */ | ||
65 | int outlen = 0; /* Number of bytes written to the output buffer */ | ||
66 | int pktcnt = 0; /* Count of the packets played */ | ||
67 | |||
68 | /* Generic codec initialisation */ | ||
69 | ci->configure(DSP_SET_SAMPLE_DEPTH, 31); | ||
70 | |||
71 | |||
72 | next_track: | ||
73 | |||
74 | /* Wait for the metadata to be read */ | ||
75 | while (!*ci->taginfo_ready && !ci->stop_codec) | ||
76 | ci->sleep(1); | ||
77 | |||
78 | retval = CODEC_OK; | ||
79 | |||
80 | /* Remember the resume position */ | ||
81 | resume_offset = ci->id3->offset; | ||
82 | restart_track: | ||
83 | if (codec_init()) { | ||
84 | LOGF("(WMA Voice) Error: Error initialising codec\n"); | ||
85 | retval = CODEC_ERROR; | ||
86 | goto done; | ||
87 | } | ||
88 | |||
89 | /* Copy the format metadata we've stored in the id3 TOC field. This | ||
90 | saves us from parsing it again here. */ | ||
91 | memcpy(&wfx, ci->id3->toc, sizeof(wfx)); | ||
92 | memset(&avctx, 0, sizeof(AVCodecContext)); | ||
93 | memset(&avpkt, 0, sizeof(AVPacket)); | ||
94 | |||
95 | ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate); | ||
96 | ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ? | ||
97 | STEREO_MONO : STEREO_INTERLEAVED); | ||
98 | codec_set_replaygain(ci->id3); | ||
99 | |||
100 | /* Initialise the AVCodecContext */ | ||
101 | init_codec_ctx(&avctx, &wfx); | ||
102 | |||
103 | if (wmavoice_decode_init(&avctx) < 0) { | ||
104 | LOGF("(WMA Voice) Error: Unsupported or corrupt file\n"); | ||
105 | retval = CODEC_ERROR; | ||
106 | goto done; | ||
107 | } | ||
108 | |||
109 | /* Now advance the file position to the first frame */ | ||
110 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
111 | |||
112 | elapsedtime = 0; | ||
113 | resume_offset = 0; | ||
114 | |||
115 | /* The main decoding loop */ | ||
116 | |||
117 | while (pktcnt < wfx.numpackets) | ||
118 | { | ||
119 | ci->yield(); | ||
120 | if (ci->stop_codec || ci->new_track) { | ||
121 | goto done; | ||
122 | } | ||
123 | |||
124 | /* Deal with any pending seek requests */ | ||
125 | if (ci->seek_time){ | ||
126 | |||
127 | if (ci->seek_time == 1) { | ||
128 | ci->seek_complete(); | ||
129 | goto restart_track; /* Pretend you never saw this... */ | ||
130 | } | ||
131 | |||
132 | elapsedtime = asf_seek(ci->seek_time, &wfx); | ||
133 | if (elapsedtime < 1){ | ||
134 | ci->seek_complete(); | ||
135 | goto next_track; | ||
136 | } | ||
137 | |||
138 | ci->set_elapsed(elapsedtime); | ||
139 | ci->seek_complete(); | ||
140 | } | ||
141 | |||
142 | new_packet: | ||
143 | res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &wfx); | ||
144 | |||
145 | if (res < 0) { | ||
146 | LOGF("(WMA Voice) read_packet error %d\n",res); | ||
147 | goto done; | ||
148 | } else { | ||
149 | avpkt.data = audiobuf; | ||
150 | avpkt.size = audiobufsize; | ||
151 | pktcnt++; | ||
152 | |||
153 | while(avpkt.size > 0) | ||
154 | { | ||
155 | /* wmavoice_decode_packet checks for the output buffer size to | ||
156 | avoid overflows */ | ||
157 | outlen = BUFSIZE*sizeof(int32_t); | ||
158 | |||
159 | res = wmavoice_decode_packet(&avctx, decoded, &outlen, &avpkt); | ||
160 | if(res < 0) { | ||
161 | LOGF("(WMA Voice) Error: decode_packet returned %d", res); | ||
162 | if(res == ERROR_WMAPRO_IN_WMAVOICE){ | ||
163 | /* Just skip this packet */ | ||
164 | ci->advance_buffer(packetlength); | ||
165 | goto new_packet; | ||
166 | } | ||
167 | else | ||
168 | goto done; | ||
169 | } | ||
170 | avpkt.data += res; | ||
171 | avpkt.size -= res; | ||
172 | if(outlen) { | ||
173 | ci->yield (); | ||
174 | outlen /= sizeof(int32_t); | ||
175 | ci->pcmbuf_insert(decoded, NULL, outlen); | ||
176 | elapsedtime += outlen*10/(wfx.rate/100); | ||
177 | ci->set_elapsed(elapsedtime); | ||
178 | ci->yield (); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | } | ||
183 | |||
184 | /* Advance to the next logical packet */ | ||
185 | ci->advance_buffer(packetlength); | ||
186 | } | ||
187 | retval = CODEC_OK; | ||
188 | |||
189 | done: | ||
190 | if (ci->request_next_track()) | ||
191 | goto next_track; | ||
192 | |||
193 | return retval; | ||
194 | } | ||
195 | |||
diff --git a/apps/metadata.c b/apps/metadata.c index 076b753958..15b7d9f72b 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -182,6 +182,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = | |||
182 | /* True Audio */ | 182 | /* True Audio */ |
183 | [AFMT_TTA] = | 183 | [AFMT_TTA] = |
184 | AFMT_ENTRY("TTA", "tta", NULL, "tta\0" ), | 184 | AFMT_ENTRY("TTA", "tta", NULL, "tta\0" ), |
185 | /* WMA Voice in ASF */ | ||
186 | [AFMT_WMAVOICE] = | ||
187 | AFMT_ENTRY("WMAVoice", "wmavoice", NULL, "wma\0wmv\0asf\0" ), | ||
185 | #endif | 188 | #endif |
186 | }; | 189 | }; |
187 | 190 | ||
@@ -297,7 +300,7 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname) | |||
297 | } | 300 | } |
298 | 301 | ||
299 | break; | 302 | break; |
300 | 303 | ||
301 | case AFMT_WMA: | 304 | case AFMT_WMA: |
302 | if (!get_asf_metadata(fd, id3)) | 305 | if (!get_asf_metadata(fd, id3)) |
303 | { | 306 | { |
diff --git a/apps/metadata.h b/apps/metadata.h index 6b15f6dead..b73d92b83f 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -84,6 +84,7 @@ enum | |||
84 | AFMT_VOX, /* VOX */ | 84 | AFMT_VOX, /* VOX */ |
85 | AFMT_WAVE64, /* Wave64 */ | 85 | AFMT_WAVE64, /* Wave64 */ |
86 | AFMT_TTA, /* True Audio */ | 86 | AFMT_TTA, /* True Audio */ |
87 | AFMT_WMAVOICE, /* WMA Voice in ASF */ | ||
87 | #endif | 88 | #endif |
88 | 89 | ||
89 | /* add new formats at any index above this line to have a sensible order - | 90 | /* add new formats at any index above this line to have a sensible order - |
diff --git a/apps/metadata/asf.c b/apps/metadata/asf.c index ba1b8972af..c445e485a2 100644 --- a/apps/metadata/asf.c +++ b/apps/metadata/asf.c | |||
@@ -357,6 +357,11 @@ static int asf_parse_header(int fd, struct mp3entry* id3, | |||
357 | wfx->audiostream = flags&0x7f; | 357 | wfx->audiostream = flags&0x7f; |
358 | /* Correct codectype to redirect playback to the proper .codec */ | 358 | /* Correct codectype to redirect playback to the proper .codec */ |
359 | id3->codectype = AFMT_WMAPRO; | 359 | id3->codectype = AFMT_WMAPRO; |
360 | } else if (wfx->codec_id == ASF_CODEC_ID_WMAVOICE) { | ||
361 | read(fd, wfx->data, wfx->datalen); | ||
362 | lseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR); | ||
363 | wfx->audiostream = flags&0x7f; | ||
364 | id3->codectype = AFMT_WMAVOICE; | ||
360 | } else { | 365 | } else { |
361 | DEBUGF("Unsupported WMA codec (Lossless, Voice, etc)\n"); | 366 | DEBUGF("Unsupported WMA codec (Lossless, Voice, etc)\n"); |
362 | lseek(fd,current.size - 24 - 72,SEEK_CUR); | 367 | lseek(fd,current.size - 24 - 72,SEEK_CUR); |