diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-01-06 17:36:52 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-01-06 17:36:52 +0000 |
commit | ef70c9f32c4d38a77b830d0a9f72e1188e97cc16 (patch) | |
tree | 7f50fa0209bc89601137d57ca27c9b8d76101399 | |
parent | f0f9f66319cb15622e25963b8d83ea63a1c1aa6d (diff) | |
download | rockbox-ef70c9f32c4d38a77b830d0a9f72e1188e97cc16.tar.gz rockbox-ef70c9f32c4d38a77b830d0a9f72e1188e97cc16.zip |
Finally fix FS#10678. Now the mp3 encoder plugin supports mono/stereo and the sampling rates 16/22.05/24/32/44.1/48 kHz.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28976 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/mp3_encoder.c | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c index 3cf2b642f0..4094b4c34f 100644 --- a/apps/plugins/mp3_encoder.c +++ b/apps/plugins/mp3_encoder.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "plugin.h" | 15 | #include "plugin.h" |
16 | 16 | ||
17 | 17 | ||
18 | #define SAMP_PER_FRAME 1152 | 18 | #define MAX_SAMP_PER_FRAME 1152 |
19 | #define SAMPL2 576 | 19 | #define SAMPL2 576 |
20 | #define SBLIMIT 32 | 20 | #define SBLIMIT 32 |
21 | #define HTN 16 | 21 | #define HTN 16 |
@@ -61,7 +61,7 @@ typedef struct { | |||
61 | int ResvSize; | 61 | int ResvSize; |
62 | int channels; | 62 | int channels; |
63 | int granules; | 63 | int granules; |
64 | int resample; | 64 | int smpl_per_frm; |
65 | uint16_t samplerate; | 65 | uint16_t samplerate; |
66 | } config_t; | 66 | } config_t; |
67 | 67 | ||
@@ -813,7 +813,7 @@ static char* mp3_enc_err[] = { | |||
813 | /* 6 */ "16 bit per sample required.", | 813 | /* 6 */ "16 bit per sample required.", |
814 | /* 7 */ "<=2 channels required.", | 814 | /* 7 */ "<=2 channels required.", |
815 | /* 8 */ "'data' missing.", | 815 | /* 8 */ "'data' missing.", |
816 | /* 9 */ "32/44.1/48 kHz required." | 816 | /* 9 */ "Samplerate not supported." |
817 | }; | 817 | }; |
818 | 818 | ||
819 | static const char* wav_filename; | 819 | static const char* wav_filename; |
@@ -897,13 +897,11 @@ int wave_open(void) | |||
897 | if(bits_per_samp != 16) return -6; /* 16 bps required */ | 897 | if(bits_per_samp != 16) return -6; /* 16 bps required */ |
898 | if(cfg.channels > 2) return -7; /* <=2 channels required */ | 898 | if(cfg.channels > 2) return -7; /* <=2 channels required */ |
899 | if(!checkString(wavfile,"data")) return -8; | 899 | if(!checkString(wavfile,"data")) return -8; |
900 | 900 | ||
901 | /* FIXME: sample rates != 32/44.1/48 kHz do not encode properly as those | 901 | /* Sample rates != 16/22.05/24/32/44.1/48 kHz are not supported. */ |
902 | * need MPEG2 format with different setup of the encoder. This MPEG2 setup | 902 | if((cfg.samplerate != 16000) && (cfg.samplerate != 22050) && |
903 | * is buggy. */ | 903 | (cfg.samplerate != 24000) && (cfg.samplerate != 32000) && |
904 | if((cfg.samplerate != 32000) && | 904 | (cfg.samplerate != 44100) && (cfg.samplerate != 48000)) return -9; |
905 | (cfg.samplerate != 44100) && | ||
906 | (cfg.samplerate != 48000)) return -9; | ||
907 | 905 | ||
908 | header_size = 0x28; | 906 | header_size = 0x28; |
909 | wav_size = rb->filesize(wavfile); | 907 | wav_size = rb->filesize(wavfile); |
@@ -914,7 +912,7 @@ int wave_open(void) | |||
914 | 912 | ||
915 | int read_samples(uint16_t *buffer, int num_samples) | 913 | int read_samples(uint16_t *buffer, int num_samples) |
916 | { | 914 | { |
917 | uint16_t tmpbuf[SAMP_PER_FRAME*2]; /* SAMP_PER_FRAME*MAX_CHANNELS */ | 915 | uint16_t tmpbuf[MAX_SAMP_PER_FRAME*2]; /* SAMP_PER_FRAME*MAX_CHANNELS */ |
918 | int byte_per_sample = cfg.channels * 2; /* requires bits_per_sample==16 */ | 916 | int byte_per_sample = cfg.channels * 2; /* requires bits_per_sample==16 */ |
919 | int s, samples = rb->read(wavfile, tmpbuf, byte_per_sample * num_samples) / byte_per_sample; | 917 | int s, samples = rb->read(wavfile, tmpbuf, byte_per_sample * num_samples) / byte_per_sample; |
920 | /* Pad last sample with zeros */ | 918 | /* Pad last sample with zeros */ |
@@ -2092,13 +2090,13 @@ void init_mp3_encoder_engine(bool stereo, int bitrate, uint16_t sample_rate) | |||
2092 | 2090 | ||
2093 | if(0 == cfg.mpg.type) | 2091 | if(0 == cfg.mpg.type) |
2094 | { /* use MPEG2 format */ | 2092 | { /* use MPEG2 format */ |
2095 | cfg.resample = 1; | 2093 | cfg.smpl_per_frm = MAX_SAMP_PER_FRAME/2; |
2096 | cfg.granules = 1; | 2094 | cfg.granules = 1; |
2097 | } | 2095 | } |
2098 | else | 2096 | else |
2099 | { /* use MPEG1 format */ | 2097 | { /* use MPEG1 format */ |
2100 | cfg.resample = 0; | 2098 | cfg.smpl_per_frm = MAX_SAMP_PER_FRAME; |
2101 | cfg.granules = 2; | 2099 | cfg.granules = 2; |
2102 | } | 2100 | } |
2103 | 2101 | ||
2104 | scalefac = sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type]; | 2102 | scalefac = sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type]; |
@@ -2172,7 +2170,8 @@ void compress(void) | |||
2172 | { | 2170 | { |
2173 | if((frames & 7) == 0) | 2171 | if((frames & 7) == 0) |
2174 | { rb->lcd_clear_display(); | 2172 | { rb->lcd_clear_display(); |
2175 | rb->lcd_putsxyf(4, 20, "Frame %d / %d", frames, wav_size/SAMPL2/8); | 2173 | rb->lcd_putsxyf(4, 20, "Frame %d / %d", frames, |
2174 | wav_size/cfg.smpl_per_frm/cfg.channels/2); | ||
2176 | rb->lcd_update(); | 2175 | rb->lcd_update(); |
2177 | } | 2176 | } |
2178 | /* encode one mp3 frame in this loop */ | 2177 | /* encode one mp3 frame in this loop */ |
@@ -2194,25 +2193,18 @@ void compress(void) | |||
2194 | memcpy(mfbuf, mfbuf + 2*cfg.granules*576, 4*512); | 2193 | memcpy(mfbuf, mfbuf + 2*cfg.granules*576, 4*512); |
2195 | 2194 | ||
2196 | /* read new samples to iram for further processing */ | 2195 | /* read new samples to iram for further processing */ |
2197 | if(read_samples((mfbuf + 2*512), SAMP_PER_FRAME) == 0) | 2196 | if(read_samples((mfbuf + 2*512), cfg.smpl_per_frm) == 0) |
2198 | break; | 2197 | break; |
2199 | 2198 | ||
2200 | /* swap bytes if neccessary */ | 2199 | /* swap bytes if neccessary */ |
2201 | if(cfg.byte_order == order_bigEndian) | 2200 | if(cfg.byte_order == order_bigEndian) |
2202 | for(i=0; i<SAMP_PER_FRAME; i++) | 2201 | for(i=0; i<cfg.smpl_per_frm; i++) |
2203 | { | 2202 | { |
2204 | uint32_t t = ((uint32_t*)mfbuf)[512 + i]; | 2203 | uint32_t t = ((uint32_t*)mfbuf)[512 + i]; |
2205 | t = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00); | 2204 | t = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00); |
2206 | ((uint32_t*)mfbuf)[512 + i] = t; | 2205 | ((uint32_t*)mfbuf)[512 + i] = t; |
2207 | } | 2206 | } |
2208 | 2207 | ||
2209 | if(cfg.resample) /* downsample to half of original */ | ||
2210 | for(i=2*512; i<2*512+2*SAMP_PER_FRAME; i+=4) | ||
2211 | { | ||
2212 | mfbuf[i/2+512] = (short)(((int)mfbuf[i+0] + mfbuf[i+2]) >> 1); | ||
2213 | mfbuf[i/2+513] = (short)(((int)mfbuf[i+1] + mfbuf[i+3]) >> 1); | ||
2214 | } | ||
2215 | |||
2216 | cfg.ResvSize = 0; | 2208 | cfg.ResvSize = 0; |
2217 | gr_cnt = cfg.granules * cfg.channels; | 2209 | gr_cnt = cfg.granules * cfg.channels; |
2218 | CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */ | 2210 | CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */ |
@@ -2612,7 +2604,7 @@ enum plugin_status plugin_start(const void* parameter) | |||
2612 | 2604 | ||
2613 | rb->lcd_clear_display(); | 2605 | rb->lcd_clear_display(); |
2614 | rb->lcd_putsxyf(0, 30, " Conversion: %ld.%02lds ", tim/100, tim%100); | 2606 | rb->lcd_putsxyf(0, 30, " Conversion: %ld.%02lds ", tim/100, tim%100); |
2615 | tim = frames * SAMP_PER_FRAME * 100 / cfg.samplerate; /* unit=.01s */ | 2607 | tim = frames * cfg.smpl_per_frm * 100 / cfg.samplerate; /* unit=.01s */ |
2616 | rb->lcd_putsxyf(0, 20, " WAV-Length: %ld.%02lds ", tim/100, tim%100); | 2608 | rb->lcd_putsxyf(0, 20, " WAV-Length: %ld.%02lds ", tim/100, tim%100); |
2617 | rb->lcd_update(); | 2609 | rb->lcd_update(); |
2618 | rb->sleep(5*HZ); | 2610 | rb->sleep(5*HZ); |