diff options
-rw-r--r-- | apps/onplay.c | 92 | ||||
-rw-r--r-- | firmware/export/mpeg.h | 1 | ||||
-rw-r--r-- | firmware/mpeg.c | 94 |
3 files changed, 84 insertions, 103 deletions
diff --git a/apps/onplay.c b/apps/onplay.c index 3814e2554b..232bda2694 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <stdbool.h> | 22 | #include <stdbool.h> |
23 | 23 | ||
24 | #include "debug.h" | ||
24 | #include "sprintf.h" | 25 | #include "sprintf.h" |
25 | #include "lcd.h" | 26 | #include "lcd.h" |
26 | #include "dir.h" | 27 | #include "dir.h" |
@@ -32,6 +33,9 @@ | |||
32 | #include "button.h" | 33 | #include "button.h" |
33 | #include "kernel.h" | 34 | #include "kernel.h" |
34 | #include "keyboard.h" | 35 | #include "keyboard.h" |
36 | #include "mp3data.h" | ||
37 | #include "id3.h" | ||
38 | #include "screens.h" | ||
35 | #include "tree.h" | 39 | #include "tree.h" |
36 | 40 | ||
37 | static char* selected_file = NULL; | 41 | static char* selected_file = NULL; |
@@ -99,41 +103,89 @@ static bool rename_file(void) | |||
99 | return false; | 103 | return false; |
100 | } | 104 | } |
101 | 105 | ||
102 | extern int d_1; | ||
103 | extern int d_2; | ||
104 | |||
105 | static void xingupdate(int percent) | 106 | static void xingupdate(int percent) |
106 | { | 107 | { |
107 | char buf[32]; | 108 | char buf[32]; |
108 | 109 | ||
109 | snprintf(buf, 32, "%d%%", percent); | 110 | snprintf(buf, 32, "%d%%", percent); |
110 | lcd_puts(0, 3, buf); | 111 | lcd_puts(0, 1, buf); |
111 | snprintf(buf, 32, "%x", d_1); | ||
112 | lcd_puts(0, 4, buf); | ||
113 | snprintf(buf, 32, "%x", d_2); | ||
114 | lcd_puts(0, 5, buf); | ||
115 | lcd_update(); | 112 | lcd_update(); |
116 | } | 113 | } |
117 | 114 | ||
118 | static bool vbr_fix(void) | 115 | static bool vbr_fix(void) |
119 | { | 116 | { |
120 | char buf[32]; | 117 | unsigned char xingbuf[417]; |
121 | unsigned long start_tick; | 118 | struct mp3entry entry; |
122 | unsigned long end_tick; | 119 | int fd; |
120 | int rc; | ||
121 | int flen; | ||
122 | int num_frames; | ||
123 | int fpos; | ||
124 | |||
123 | 125 | ||
124 | lcd_clear_display(); | 126 | lcd_clear_display(); |
125 | lcd_puts(0, 0, selected_file); | 127 | lcd_puts_scroll(0, 0, selected_file); |
126 | lcd_update(); | 128 | lcd_update(); |
127 | 129 | ||
128 | start_tick = current_tick; | 130 | xingupdate(0); |
129 | mpeg_create_xing_header(selected_file, xingupdate); | ||
130 | end_tick = current_tick; | ||
131 | 131 | ||
132 | snprintf(buf, 32, "%d ticks", (int)(end_tick - start_tick)); | 132 | rc = mp3info(&entry, selected_file); |
133 | lcd_puts(0, 1, buf); | 133 | if(rc < 0) |
134 | snprintf(buf, 32, "%d seconds", (int)(end_tick - start_tick)/HZ); | 134 | return rc * 10 - 1; |
135 | lcd_puts(0, 2, buf); | 135 | |
136 | lcd_update(); | 136 | fd = open(selected_file, O_RDWR); |
137 | if(fd < 0) | ||
138 | return fd * 10 - 2; | ||
139 | |||
140 | flen = lseek(fd, 0, SEEK_END); | ||
141 | |||
142 | xingupdate(0); | ||
143 | |||
144 | num_frames = count_mp3_frames(fd, entry.first_frame_offset, | ||
145 | flen, xingupdate); | ||
146 | |||
147 | if(num_frames) | ||
148 | { | ||
149 | create_xing_header(fd, entry.first_frame_offset, | ||
150 | flen, xingbuf, num_frames, xingupdate, true); | ||
151 | |||
152 | /* Try to fit the Xing header first in the stream. Replace the existing | ||
153 | Xing header if there is one, else see if there is room between the | ||
154 | ID3 tag and the first MP3 frame. */ | ||
155 | if(entry.vbr_header_pos) | ||
156 | { | ||
157 | /* Reuse existing Xing header */ | ||
158 | fpos = entry.vbr_header_pos; | ||
159 | |||
160 | DEBUGF("Reusing Xing header at %d\n", fpos); | ||
161 | } | ||
162 | else | ||
163 | { | ||
164 | /* Any room between ID3 tag and first MP3 frame? */ | ||
165 | if(entry.first_frame_offset - entry.id3v2len > 417) | ||
166 | { | ||
167 | fpos = entry.first_frame_offset - 417; | ||
168 | } | ||
169 | else | ||
170 | { | ||
171 | close(fd); | ||
172 | splash(HZ*2, 0, true, "No room for header"); | ||
173 | return -3; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | lseek(fd, fpos, SEEK_SET); | ||
178 | write(fd, xingbuf, 417); | ||
179 | close(fd); | ||
180 | |||
181 | xingupdate(100); | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | /* Not a VBR file */ | ||
186 | DEBUGF("Not a VBR file\n"); | ||
187 | splash(HZ*2, 0, true, "Not a VBR file"); | ||
188 | } | ||
137 | 189 | ||
138 | return false; | 190 | return false; |
139 | } | 191 | } |
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h index 9ce03daa7d..6b44363f8f 100644 --- a/firmware/export/mpeg.h +++ b/firmware/export/mpeg.h | |||
@@ -90,7 +90,6 @@ unsigned long mpeg_num_recorded_bytes(void); | |||
90 | #endif | 90 | #endif |
91 | void mpeg_get_debugdata(struct mpeg_debug *dbgdata); | 91 | void mpeg_get_debugdata(struct mpeg_debug *dbgdata); |
92 | void mpeg_set_buffer_margin(int seconds); | 92 | void mpeg_set_buffer_margin(int seconds); |
93 | int mpeg_create_xing_header(char *filename, void (*progressfunc)(int)); | ||
94 | 93 | ||
95 | #define SOUND_VOLUME 0 | 94 | #define SOUND_VOLUME 0 |
96 | #define SOUND_BASS 1 | 95 | #define SOUND_BASS 1 |
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index bd90e9f1d6..15d531ea1f 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -715,6 +715,7 @@ static long timing_info[1024]; | |||
715 | #endif | 715 | #endif |
716 | static bool inverted_pr; | 716 | static bool inverted_pr; |
717 | static unsigned long num_rec_bytes; | 717 | static unsigned long num_rec_bytes; |
718 | static unsigned long num_recorded_frames; | ||
718 | 719 | ||
719 | void drain_dma_buffer(void) | 720 | void drain_dma_buffer(void) |
720 | { | 721 | { |
@@ -1851,7 +1852,7 @@ static void mpeg_thread(void) | |||
1851 | panicf("recfile: %d", mpeg_file); | 1852 | panicf("recfile: %d", mpeg_file); |
1852 | 1853 | ||
1853 | break; | 1854 | break; |
1854 | 1855 | ||
1855 | case MPEG_STOP: | 1856 | case MPEG_STOP: |
1856 | DEBUGF("MPEG_STOP\n"); | 1857 | DEBUGF("MPEG_STOP\n"); |
1857 | demand_irq_enable(false); | 1858 | demand_irq_enable(false); |
@@ -1872,8 +1873,9 @@ static void mpeg_thread(void) | |||
1872 | if(mpeg_file < 0) | 1873 | if(mpeg_file < 0) |
1873 | panicf("rec upd: %d", mpeg_file); | 1874 | panicf("rec upd: %d", mpeg_file); |
1874 | 1875 | ||
1875 | create_xing_header(mpeg_file, 0, mpeg_num_recorded_bytes(), | 1876 | create_xing_header(mpeg_file, 0, num_rec_bytes, |
1876 | xingbuf, 0, NULL, false); | 1877 | xingbuf, num_recorded_frames, NULL, |
1878 | false); | ||
1877 | 1879 | ||
1878 | lseek(mpeg_file, 4096, SEEK_SET); | 1880 | lseek(mpeg_file, 4096, SEEK_SET); |
1879 | write(mpeg_file, xingbuf, 417); | 1881 | write(mpeg_file, xingbuf, 417); |
@@ -2209,6 +2211,8 @@ static void start_recording(void) | |||
2209 | { | 2211 | { |
2210 | unsigned long val; | 2212 | unsigned long val; |
2211 | 2213 | ||
2214 | num_recorded_frames = 0; | ||
2215 | |||
2212 | /* Stop monitoring and record for real */ | 2216 | /* Stop monitoring and record for real */ |
2213 | mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); | 2217 | mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); |
2214 | val &= ~(1 << 10); | 2218 | val &= ~(1 << 10); |
@@ -2236,6 +2240,9 @@ static void stop_recording(void) | |||
2236 | unsigned long val; | 2240 | unsigned long val; |
2237 | 2241 | ||
2238 | is_recording = false; | 2242 | is_recording = false; |
2243 | |||
2244 | /* Read the number of frames recorded */ | ||
2245 | mas_readmem(MAS_BANK_D0, 0xfd0, &num_recorded_frames, 1); | ||
2239 | 2246 | ||
2240 | /* Start monitoring */ | 2247 | /* Start monitoring */ |
2241 | mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); | 2248 | mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); |
@@ -2266,6 +2273,7 @@ unsigned long mpeg_num_recorded_bytes(void) | |||
2266 | else | 2273 | else |
2267 | return 0; | 2274 | return 0; |
2268 | } | 2275 | } |
2276 | |||
2269 | #endif | 2277 | #endif |
2270 | 2278 | ||
2271 | void mpeg_play(int offset) | 2279 | void mpeg_play(int offset) |
@@ -2853,6 +2861,7 @@ void mpeg_set_recording_gain(int left, int right, int mic) | |||
2853 | (mic?0x0008:0) | /* Connect left A/D to mic */ | 2861 | (mic?0x0008:0) | /* Connect left A/D to mic */ |
2854 | 0x0007); | 2862 | 0x0007); |
2855 | } | 2863 | } |
2864 | |||
2856 | #endif | 2865 | #endif |
2857 | 2866 | ||
2858 | #ifdef SIMULATOR | 2867 | #ifdef SIMULATOR |
@@ -2999,82 +3008,3 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness, | |||
2999 | dbg_cnt2us(0); | 3008 | dbg_cnt2us(0); |
3000 | #endif | 3009 | #endif |
3001 | } | 3010 | } |
3002 | |||
3003 | int d_1; | ||
3004 | int d_2; | ||
3005 | |||
3006 | int mpeg_create_xing_header(char *filename, void (*progressfunc)(int)) | ||
3007 | { | ||
3008 | struct mp3entry entry; | ||
3009 | int fd; | ||
3010 | int rc; | ||
3011 | int flen; | ||
3012 | int num_frames; | ||
3013 | int fpos; | ||
3014 | |||
3015 | if(progressfunc) | ||
3016 | progressfunc(0); | ||
3017 | |||
3018 | rc = mp3info(&entry, filename); | ||
3019 | if(rc < 0) | ||
3020 | return rc * 10 - 1; | ||
3021 | |||
3022 | fd = open(filename, O_RDWR); | ||
3023 | if(fd < 0) | ||
3024 | return fd * 10 - 2; | ||
3025 | |||
3026 | flen = lseek(fd, 0, SEEK_END); | ||
3027 | |||
3028 | d_1 = entry.first_frame_offset; | ||
3029 | d_2 = entry.filesize; | ||
3030 | |||
3031 | if(progressfunc) | ||
3032 | progressfunc(0); | ||
3033 | |||
3034 | num_frames = count_mp3_frames(fd, entry.first_frame_offset, | ||
3035 | flen, progressfunc); | ||
3036 | |||
3037 | if(num_frames) | ||
3038 | { | ||
3039 | create_xing_header(fd, entry.first_frame_offset, | ||
3040 | flen, xingbuf, num_frames, progressfunc, true); | ||
3041 | |||
3042 | /* Try to fit the Xing header first in the stream. Replace the existing | ||
3043 | Xing header if there is one, else see if there is room between the | ||
3044 | ID3 tag and the first MP3 frame. */ | ||
3045 | if(entry.vbr_header_pos) | ||
3046 | { | ||
3047 | /* Reuse existing Xing header */ | ||
3048 | fpos = entry.vbr_header_pos; | ||
3049 | |||
3050 | DEBUGF("Reusing Xing header at %d\n", fpos); | ||
3051 | } | ||
3052 | else | ||
3053 | { | ||
3054 | /* Any room between ID3 tag and first MP3 frame? */ | ||
3055 | if(entry.first_frame_offset - entry.id3v2len > 417) | ||
3056 | { | ||
3057 | fpos = entry.first_frame_offset - 417; | ||
3058 | } | ||
3059 | else | ||
3060 | { | ||
3061 | close(fd); | ||
3062 | return -3; | ||
3063 | } | ||
3064 | } | ||
3065 | |||
3066 | lseek(fd, fpos, SEEK_SET); | ||
3067 | write(fd, xingbuf, 417); | ||
3068 | close(fd); | ||
3069 | |||
3070 | if(progressfunc) | ||
3071 | progressfunc(100); | ||
3072 | return 0; | ||
3073 | } | ||
3074 | else | ||
3075 | { | ||
3076 | /* Not a VBR file */ | ||
3077 | DEBUGF("Not a VBR file\n"); | ||
3078 | return -9; | ||
3079 | } | ||
3080 | } | ||