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