| @@ -5,6 +5,7 @@ · 4 unmodified lines |
| 5 | 5 | #include <math.h> |
| 6 | 6 | #include <string.h> |
| 7 | 7 | |
| 8 | +#ifndef MINIMP3_NO_WAV |
| 8 | 9 | static char *wav_header(int hz, int ch, int bips, int data_bytes) |
| 9 | 10 | { |
| 10 | 11 | static char hdr[44] = "RIFFsizeWAVEfmt \x10\0\0\0\1\0ch_hz_abpsbabsdatasize"; |
| @@ -21,45 +22,62 @@ static char *wav_header(int hz, int ch, int bips, int data_bytes) · 10 unmodified lines |
| 21 | 22 | *(int * )(hdr + 0x28) = data_bytes; |
| 22 | 23 | return hdr; |
| 23 | 24 | } |
| 25 | +#endif |
| 26 | + |
| 27 | +static unsigned char *preload(FILE *file, int *data_size) |
| 28 | +{ |
| 29 | + unsigned char *data; |
| 30 | + *data_size = 0; |
| 31 | + if (!file) |
| 32 | + return 0; |
| 33 | + fseek(file, 0, SEEK_END); |
| 34 | + *data_size = (int)ftell(file); |
| 35 | + fseek(file, 0, SEEK_SET); |
| 36 | + data = (unsigned char*)malloc(*data_size); |
| 37 | + if (!data) |
| 38 | + return 0; |
| 39 | + if ((int)fread(data, 1, *data_size, file) != *data_size) |
| 40 | + exit(1); |
| 41 | + return data; |
| 42 | +} |
| 24 | 43 | |
| 25 | 44 | static void decode_file(FILE *file_mp3, FILE *file_ref, FILE *file_out, const int wave_out) |
| 26 | 45 | { |
| 27 | 46 | static mp3dec_t mp3d; |
| 28 | 47 | mp3dec_frame_info_t info; |
| 29 | | − int i, data_bytes, samples, total_samples = 0, nbuf = 0, maxdiff = 0; |
| 48 | + int i, data_bytes, samples, total_samples = 0, maxdiff = 0, mp3_size, ref_size; |
| 30 | 49 | double MSE = 0.0, psnr; |
| 31 | | − unsigned char buf[4096]; |
| 50 | + unsigned char *buf_mp3 = preload(file_mp3, &mp3_size), *buf_ref = preload(file_ref, &ref_size); |
| 32 | 51 | |
| 33 | 52 | mp3dec_init(&mp3d); |
| 34 | | − |
| 53 | +#ifndef MINIMP3_NO_WAV |
| 35 | 54 | if (wave_out) |
| 36 | 55 | fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out); |
| 37 | | − |
| 56 | +#endif |
| 38 | 57 | do |
| 39 | 58 | { |
| 40 | | − short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME], pcm2[MINIMP3_MAX_SAMPLES_PER_FRAME]; |
| 41 | | − nbuf += fread(buf + nbuf, 1, sizeof(buf) - nbuf, file_mp3); |
| 42 | | − samples = mp3dec_decode_frame(&mp3d, buf, nbuf, pcm, &info); |
| 59 | + short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; |
| 60 | + samples = mp3dec_decode_frame(&mp3d, buf_mp3, mp3_size, pcm, &info); |
| 43 | 61 | if (samples) |
| 44 | 62 | { |
| 45 | | − if (file_ref) |
| 63 | + if (buf_ref && ref_size >= samples*info.channels*2) |
| 46 | 64 | { |
| 47 | | − int readed = fread(pcm2, 1, 2*info.channels*samples, file_ref); |
| 48 | | − if (readed < 0) |
| 49 | | − exit(1); |
| 50 | 65 | total_samples += samples*info.channels; |
| 51 | 66 | for (i = 0; i < samples*info.channels; i++) |
| 52 | 67 | { |
| 53 | | − int MSEtemp = abs((int)pcm[i] - (int)pcm2[i]); |
| 68 | + int MSEtemp = abs((int)pcm[i] - (int)(((short*)buf_ref)[i])); |
| 54 | 69 | if (MSEtemp > maxdiff) |
| 55 | 70 | maxdiff = MSEtemp; |
| 56 | 71 | MSE += MSEtemp*MSEtemp; |
| 57 | 72 | } |
| 73 | + buf_ref += samples*info.channels*2; |
| 74 | + ref_size -= samples*info.channels*2; |
| 58 | 75 | } |
| 59 | 76 | if (file_out) |
| 60 | 77 | fwrite(pcm, samples, 2*info.channels, file_out); |
| 61 | 78 | } |
| 62 | | − memmove(buf, buf + info.frame_bytes, nbuf -= info.frame_bytes); |
| 79 | + buf_mp3 += info.frame_bytes; |
| 80 | + mp3_size -= info.frame_bytes; |
| 63 | 81 | } while (info.frame_bytes); |
| 64 | 82 | |
| 65 | 83 | MSE /= total_samples ? total_samples : 1; |
| @@ -73,13 +91,14 @@ static void decode_file(FILE *file_mp3, FILE *file_ref, FILE *file_out, const in · 7 unmodified lines |
| 73 | 91 | printf("PSNR compliance failed\n"); |
| 74 | 92 | exit(1); |
| 75 | 93 | } |
| 76 | | − |
| 94 | +#ifndef MINIMP3_NO_WAV |
| 77 | 95 | if (wave_out) |
| 78 | 96 | { |
| 79 | 97 | data_bytes = ftell(file_out) - 44; |
| 80 | 98 | rewind(file_out); |
| 81 | 99 | fwrite(wav_header(info.hz, info.channels, 16, data_bytes), 1, 44, file_out); |
| 82 | 100 | } |
| 101 | +#endif |
| 83 | 102 | fclose(file_mp3); |
| 84 | 103 | if (file_ref) |
| 85 | 104 | fclose(file_ref); |
| @@ -93,14 +112,14 @@ int main(int argc, char *argv[]) · 7 unmodified lines |
| 93 | 112 | char *ref_file_name = (argc > 2) ? argv[2] : NULL; |
| 94 | 113 | char *output_file_name = (argc > 3) ? argv[3] : NULL; |
| 95 | 114 | int wave_out = 0; |
| 96 | | − |
| 115 | +#ifndef MINIMP3_NO_WAV |
| 97 | 116 | if (output_file_name) |
| 98 | 117 | { |
| 99 | 118 | char *ext = strrchr(output_file_name, '.'); |
| 100 | 119 | if (ext && !strcasecmp(ext+1, "wav")) |
| 101 | 120 | wave_out = 1; |
| 102 | 121 | } |
| 103 | | − |
| 122 | +#endif |
| 104 | 123 | if (!input_file_name) |
| 105 | 124 | { |
| 106 | 125 | printf("error: no file names given\n"); |