summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/onplay.c92
-rw-r--r--firmware/export/mpeg.h1
-rw-r--r--firmware/mpeg.c94
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
37static char* selected_file = NULL; 41static char* selected_file = NULL;
@@ -99,41 +103,89 @@ static bool rename_file(void)
99 return false; 103 return false;
100} 104}
101 105
102extern int d_1;
103extern int d_2;
104
105static void xingupdate(int percent) 106static 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
118static bool vbr_fix(void) 115static 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
91void mpeg_get_debugdata(struct mpeg_debug *dbgdata); 91void mpeg_get_debugdata(struct mpeg_debug *dbgdata);
92void mpeg_set_buffer_margin(int seconds); 92void mpeg_set_buffer_margin(int seconds);
93int 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
716static bool inverted_pr; 716static bool inverted_pr;
717static unsigned long num_rec_bytes; 717static unsigned long num_rec_bytes;
718static unsigned long num_recorded_frames;
718 719
719void drain_dma_buffer(void) 720void 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
2271void mpeg_play(int offset) 2279void 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
3003int d_1;
3004int d_2;
3005
3006int 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}