1.1 --- a/music_mad.c Tue Nov 26 14:37:01 2019 +0300
1.2 +++ b/music_mad.c Sat Dec 07 14:10:02 2019 +0300
1.3 @@ -170,7 +170,7 @@
1.4 }
1.5 return SDL_TRUE;
1.6 }
1.7 -static __inline__ int get_id3v2_len(const unsigned char *data, long length)
1.8 +static __inline__ int get_id3v2_len(const unsigned char *data, int length)
1.9 {
1.10 /* size is a 'synchsafe' integer (see above) */
1.11 int size = (int)((data[6]<<21) + (data[7]<<14) + (data[8]<<7) + data[9]);
1.12 @@ -207,11 +207,14 @@
1.13 }
1.14 return SDL_TRUE;
1.15 }
1.16 -static __inline__ int get_ape_len(const unsigned char *data, int datalen, Uint32 *version)
1.17 +static __inline__ int get_ape_len(const unsigned char *data)
1.18 {
1.19 + Uint32 flags, version;
1.20 int size = (int)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]);
1.21 - *version = (data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8];
1.22 - return size; /* caller will handle the additional v2 header length */
1.23 + version = (data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8];
1.24 + flags = (data[23]<<24) | (data[22]<<16) | (data[21]<<8) | data[20];
1.25 + if (version == 2000U && (flags & (1U<<31))) size += 32; /* header present. */
1.26 + return size;
1.27 }
1.28
1.29 static int skip_tags(mad_data *music)
1.30 @@ -229,11 +232,10 @@
1.31 music->length -= len;
1.32 MAD_RWseek(music, 0, RW_SEEK_SET);
1.33 }
1.34 - /* APE tag _might_ be at the start: read the header */
1.35 + /* APE tag _might_ be at the start (discouraged
1.36 + * but not forbidden, either.) read the header. */
1.37 else if (is_apetag(music->input_buffer, readsize)) {
1.38 - Uint32 v;
1.39 - len = get_ape_len(music->input_buffer, readsize, &v);
1.40 - len += 32; /* we're at top: have a header. */
1.41 + len = get_ape_len(music->input_buffer);
1.42 if (len >= music->length) return -1;
1.43 music->start += len;
1.44 music->length -= len;
1.45 @@ -249,29 +251,10 @@
1.46 if (is_id3v1(music->input_buffer, 128)) {
1.47 music->length -= 128;
1.48
1.49 - /* APE tag may be before the ID3v1: read the footer */
1.50 - if (music->length < 32) goto end;
1.51 - MAD_RWseek(music, -32, RW_SEEK_END);
1.52 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.53 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.54 - if (readsize != 32) return -1;
1.55 - if (is_apetag(music->input_buffer, 32)) {
1.56 - Uint32 v;
1.57 - len = get_ape_len(music->input_buffer, readsize, &v);
1.58 - if (v == 2000U) len += 32; /* header */
1.59 - if (len >= music->length) return -1;
1.60 - if (v == 2000U) { /* verify header : */
1.61 - MAD_RWseek(music, -len, RW_SEEK_END);
1.62 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.63 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.64 - if (readsize != 32) return -1;
1.65 - if (!is_apetag(music->input_buffer, 32)) return -1;
1.66 - }
1.67 - music->length -= len;
1.68 - goto end;
1.69 - }
1.70 - /* extended ID3v1 just before the ID3v1 tag? (unlikely) */
1.71 - if (music->length < 227) goto end;
1.72 + /* extended ID3v1 just before the ID3v1 tag? (unlikely)
1.73 + * if found, assume no additional tags: this stupidity
1.74 + * is non-standard.. */
1.75 + if (music->length < 227) goto ape;
1.76 MAD_RWseek(music, -227, RW_SEEK_END);
1.77 readsize = MAD_RWread(music, music->input_buffer, 1, 227);
1.78 MAD_RWseek(music, 0, RW_SEEK_SET);
1.79 @@ -280,7 +263,10 @@
1.80 music->length -= 227;
1.81 goto end;
1.82 }
1.83 +
1.84 + /* FIXME: handle possible double-ID3v1 tags? */
1.85 }
1.86 +
1.87 ape: /* APE tag may be at the end: read the footer */
1.88 if (music->length >= 32) {
1.89 MAD_RWseek(music, -32, RW_SEEK_END);
1.90 @@ -288,17 +274,8 @@
1.91 MAD_RWseek(music, 0, RW_SEEK_SET);
1.92 if (readsize != 32) return -1;
1.93 if (is_apetag(music->input_buffer, 32)) {
1.94 - Uint32 v;
1.95 - len = get_ape_len(music->input_buffer, readsize, &v);
1.96 - if (v == 2000U) len += 32; /* header */
1.97 + len = get_ape_len(music->input_buffer);
1.98 if (len >= music->length) return -1;
1.99 - if (v == 2000U) { /* verify header : */
1.100 - MAD_RWseek(music, -len, RW_SEEK_END);
1.101 - readsize = MAD_RWread(music, music->input_buffer, 1, 32);
1.102 - MAD_RWseek(music, 0, RW_SEEK_SET);
1.103 - if (readsize != 32) return -1;
1.104 - if (!is_apetag(music->input_buffer, 32)) return -1;
1.105 - }
1.106 music->length -= len;
1.107 }
1.108 }
1.109 @@ -325,7 +302,7 @@
1.110 memmove(mp3_mad->input_buffer, mp3_mad->stream.next_frame, remaining);
1.111 read_start = mp3_mad->input_buffer + remaining;
1.112 read_size = MAD_INPUT_BUFFER_SIZE - remaining;
1.113 -
1.114 +
1.115 } else {
1.116 read_size = MAD_INPUT_BUFFER_SIZE;
1.117 read_start = mp3_mad->input_buffer;
1.118 @@ -334,7 +311,7 @@
1.119
1.120 /* Now read additional bytes from the input file. */
1.121 read_size = MAD_RWread(mp3_mad, read_start, 1, read_size);
1.122 -
1.123 +
1.124 if (read_size <= 0) {
1.125 if ((mp3_mad->status & (MS_input_eof | MS_input_error)) == 0) {
1.126 if (read_size == 0) {
1.127 @@ -342,14 +319,14 @@
1.128 } else {
1.129 mp3_mad->status |= MS_input_error;
1.130 }
1.131 -
1.132 +
1.133 /* At the end of the file, we must stuff MAD_BUFFER_GUARD
1.134 number of 0 bytes. */
1.135 memset(read_start + read_size, 0, MAD_BUFFER_GUARD);
1.136 read_size += MAD_BUFFER_GUARD;
1.137 }
1.138 }
1.139 -
1.140 +
1.141 /* Now feed those bytes into the libmad stream. */
1.142 mad_stream_buffer(&mp3_mad->stream, mp3_mad->input_buffer,
1.143 read_size + remaining);
1.144 @@ -362,10 +339,10 @@
1.145 if (MAD_RECOVERABLE(mp3_mad->stream.error)) {
1.146 mad_stream_sync(&mp3_mad->stream); /* to frame seek mode */
1.147 return 0;
1.148 -
1.149 +
1.150 } else if (mp3_mad->stream.error == MAD_ERROR_BUFLEN) {
1.151 return 0;
1.152 -
1.153 +
1.154 } else {
1.155 mp3_mad->status |= MS_decode_error;
1.156 return 0;
1.157 @@ -402,7 +379,6 @@
1.158 unsigned int nchannels, nsamples;
1.159 mad_fixed_t const *left_ch, *right_ch;
1.160 unsigned char *out;
1.161 - int ret;
1.162
1.163 mad_synth_frame(&mp3_mad->synth, &mp3_mad->frame);
1.164 pcm = &mp3_mad->synth.pcm;