Recording in FM screen, USB mode possible in FM and recording screen

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4046 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Linus Nielsen Feltzing 2003-11-20 00:33:43 +00:00
parent 577e571958
commit aaa99e70ba
9 changed files with 265 additions and 91 deletions

View file

@ -1817,3 +1817,13 @@ id: LANG_FM_NO_FREE_PRESETS
desc: in radio screen desc: in radio screen
eng: "The preset list is full" eng: "The preset list is full"
new: new:
id: LANG_FM_RADIO
desc: in main menu
eng: "FM Radio"
new:
id: LANG_FM_BUTTONBAR_RECORD
desc: in main menu
eng: "Record"
new:

View file

@ -252,6 +252,11 @@ static bool plugin_browse(void)
return rockbox_browse(PLUGIN_DIR, SHOW_PLUGINS); return rockbox_browse(PLUGIN_DIR, SHOW_PLUGINS);
} }
static bool recording_settings(void)
{
return recording_menu(false);
}
bool main_menu(void) bool main_menu(void)
{ {
int m; int m;
@ -262,11 +267,11 @@ bool main_menu(void)
{ str(LANG_SOUND_SETTINGS), sound_menu }, { str(LANG_SOUND_SETTINGS), sound_menu },
{ str(LANG_GENERAL_SETTINGS), settings_menu }, { str(LANG_GENERAL_SETTINGS), settings_menu },
#ifdef HAVE_FMRADIO #ifdef HAVE_FMRADIO
{ "FM Radio", radio_screen }, { str(LANG_FM_RADIO), radio_screen },
#endif #endif
#ifdef HAVE_MAS3587F #ifdef HAVE_MAS3587F
{ str(LANG_RECORDING), recording_screen }, { str(LANG_RECORDING), recording_screen },
{ str(LANG_RECORDING_SETTINGS), recording_menu }, { str(LANG_RECORDING_SETTINGS), recording_settings},
#endif #endif
{ str(LANG_PLAYLIST_MENU), playlist_menu }, { str(LANG_PLAYLIST_MENU), playlist_menu },
{ str(LANG_MENU_SHOW_ID3_INFO), browse_id3 }, { str(LANG_MENU_SHOW_ID3_INFO), browse_id3 },

View file

@ -43,6 +43,8 @@
#include "peakmeter.h" #include "peakmeter.h"
#include "lang.h" #include "lang.h"
#include "font.h" #include "font.h"
#include "sound_menu.h"
#include "recording.h"
#ifdef HAVE_FMRADIO #ifdef HAVE_FMRADIO
@ -116,6 +118,11 @@ bool radio_screen(void)
bool update_screen = true; bool update_screen = true;
int timeout = current_tick + HZ/10; int timeout = current_tick + HZ/10;
bool screen_freeze = false; bool screen_freeze = false;
bool have_recorded = false;
unsigned int seconds;
unsigned int last_seconds = 0;
int hours, minutes;
bool keep_playing = false;
lcd_clear_display(); lcd_clear_display();
lcd_setmargins(0, 8); lcd_setmargins(0, 8);
@ -133,10 +140,26 @@ bool radio_screen(void)
mpeg_stop(); mpeg_stop();
/* Enable the Left and right A/D Converter */ mpeg_init_recording();
mas_codec_writereg(0x0, 0x2227);
mas_codec_writereg(6, 0x4000); mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
status_set_playmode(STATUS_STOP);
/* Yes, we use the D/A for monitoring */
peak_meter_playback(true);
peak_meter_enabled = true;
mpeg_set_recording_options(global_settings.rec_frequency,
global_settings.rec_quality,
1 /* Line In */,
global_settings.rec_channels,
global_settings.rec_editable);
mpeg_set_recording_gain(mpeg_sound_default(SOUND_LEFT_GAIN),
mpeg_sound_default(SOUND_RIGHT_GAIN), false);
fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */ fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */
radio_set_frequency(curr_freq); radio_set_frequency(curr_freq);
@ -147,7 +170,7 @@ bool radio_screen(void)
peak_meter_enabled = true; peak_meter_enabled = true;
buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS),
NULL); str(LANG_FM_BUTTONBAR_RECORD));
while(!done) while(!done)
{ {
@ -188,16 +211,39 @@ bool radio_screen(void)
switch(button) switch(button)
{ {
case BUTTON_OFF: case BUTTON_OFF:
radio_stop(); if(mpeg_status())
{
mpeg_stop();
status_set_playmode(STATUS_STOP);
}
else
{
radio_stop();
done = true;
}
update_screen = true;
break;
/* Turn off the ADC gain */ case BUTTON_F3:
mas_codec_writereg(6, 0x0000); /* Only act if the mpeg is stopped */
if(!mpeg_status())
done = true; {
have_recorded = true;
mpeg_record(rec_create_filename());
status_set_playmode(STATUS_RECORD);
update_screen = true;
}
else
{
mpeg_new_file(rec_create_filename());
update_screen = true;
}
last_seconds = 0;
break; break;
case BUTTON_ON | BUTTON_REL: case BUTTON_ON | BUTTON_REL:
done = true; done = true;
keep_playing = true;
break; break;
case BUTTON_LEFT: case BUTTON_LEFT:
@ -257,7 +303,7 @@ bool radio_screen(void)
lcd_setmargins(0, 8); lcd_setmargins(0, 8);
buttonbar_set(str(LANG_BUTTONBAR_MENU), buttonbar_set(str(LANG_BUTTONBAR_MENU),
str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_PRESETS),
NULL); str(LANG_FM_BUTTONBAR_RECORD));
update_screen = true; update_screen = true;
break; break;
@ -268,11 +314,11 @@ bool radio_screen(void)
lcd_setmargins(0, 8); lcd_setmargins(0, 8);
buttonbar_set(str(LANG_BUTTONBAR_MENU), buttonbar_set(str(LANG_BUTTONBAR_MENU),
str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_PRESETS),
NULL); str(LANG_FM_BUTTONBAR_RECORD));
update_screen = true; update_screen = true;
break; break;
case BUTTON_F3: case BUTTON_PLAY:
if(!screen_freeze) if(!screen_freeze)
{ {
splash(0, 0, true, "Screen frozen"); splash(0, 0, true, "Screen frozen");
@ -287,9 +333,15 @@ bool radio_screen(void)
break; break;
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
usb_screen(); /* Only accept USB connection when not recording */
fmradio_set_status(0); if(!mpeg_status())
return true; {
usb_screen();
fmradio_set_status(0);
have_recorded = true; /* Refreshes the browser later on */
done = true;
}
break;
} }
peak_meter_peek(); peak_meter_peek();
@ -297,9 +349,12 @@ bool radio_screen(void)
if(!screen_freeze) if(!screen_freeze)
{ {
lcd_setmargins(0, 8); lcd_setmargins(0, 8);
lcd_clearrect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh); if(!mpeg_status())
peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh); {
lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh); lcd_clearrect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
peak_meter_draw(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
lcd_update_rect(0, 8 + fh*(top_of_screen + 3), LCD_WIDTH, fh);
}
if(TIME_AFTER(current_tick, timeout)) if(TIME_AFTER(current_tick, timeout))
{ {
@ -314,8 +369,12 @@ bool radio_screen(void)
} }
} }
if(update_screen) seconds = mpeg_recorded_time() / HZ;
if(update_screen || seconds > last_seconds)
{ {
last_seconds = seconds;
lcd_setfont(FONT_UI); lcd_setfont(FONT_UI);
if(curr_preset >= 0) if(curr_preset >= 0)
@ -337,6 +396,16 @@ bool radio_screen(void)
str(LANG_CHANNEL_MONO)); str(LANG_CHANNEL_MONO));
lcd_puts(0, top_of_screen + 2, buf); lcd_puts(0, top_of_screen + 2, buf);
if(mpeg_status())
{
hours = seconds / 3600;
minutes = (seconds - (hours * 3600)) / 60;
snprintf(buf, 32, "%s %02d:%02d:%02d",
str(LANG_RECORDING_TIME),
hours, minutes, seconds%60);
lcd_puts(0, top_of_screen + 3, buf);
}
/* Only force the redraw if update_screen is true */ /* Only force the redraw if update_screen is true */
status_draw(update_screen); status_draw(update_screen);
@ -347,10 +416,51 @@ bool radio_screen(void)
update_screen = false; update_screen = false;
} }
} }
if(mpeg_status() & MPEG_STATUS_ERROR)
{
done = true;
}
} }
if(mpeg_status() & MPEG_STATUS_ERROR)
{
status_set_playmode(STATUS_STOP);
splash(0, 0, true, str(LANG_DISK_FULL));
status_draw(true);
lcd_update();
mpeg_error_clear();
while(1)
{
button = button_get(true);
if(button == (BUTTON_OFF | BUTTON_REL))
break;
}
}
mpeg_init_playback();
mpeg_sound_channel_config(global_settings.channel_config);
mpeg_sound_set(SOUND_BASS, global_settings.bass);
mpeg_sound_set(SOUND_TREBLE, global_settings.treble);
mpeg_sound_set(SOUND_BALANCE, global_settings.balance);
mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
mpeg_sound_set(SOUND_LOUDNESS, global_settings.loudness);
mpeg_sound_set(SOUND_SUPERBASS, global_settings.bass_boost);
mpeg_sound_set(SOUND_AVC, global_settings.avc);
fmradio_set_status(0); fmradio_set_status(0);
return false;
if(keep_playing)
{
/* Enable the Left and right A/D Converter */
mpeg_set_recording_gain(mpeg_sound_default(SOUND_LEFT_GAIN),
mpeg_sound_default(SOUND_RIGHT_GAIN), false);
mas_codec_writereg(6, 0x4000);
}
return have_recorded;
} }
static bool parseline(char* line, char** freq, char** name) static bool parseline(char* line, char** freq, char** name)
@ -556,11 +666,17 @@ bool radio_delete_preset(void)
return reload_dir; return reload_dir;
} }
static bool fm_recording_settings(void)
{
return recording_menu(true);
}
bool radio_menu(void) bool radio_menu(void)
{ {
struct menu_items radio_menu_items[] = { struct menu_items radio_menu_items[] = {
{ str(LANG_FM_SAVE_PRESET), radio_add_preset }, { str(LANG_FM_SAVE_PRESET), radio_add_preset },
{ str(LANG_FM_DELETE_PRESET), radio_delete_preset } { str(LANG_FM_DELETE_PRESET), radio_delete_preset },
{ str(LANG_RECORDING_SETTINGS), fm_recording_settings }
}; };
int m; int m;
bool result; bool result;

View file

@ -45,16 +45,6 @@
bool f2_rec_screen(void); bool f2_rec_screen(void);
bool f3_rec_screen(void); bool f3_rec_screen(void);
extern int recording_peak_left;
extern int recording_peak_right;
extern int mp3buf_write;
extern int mp3buf_read;
extern bool recording;
extern unsigned long record_start_frame; /* Frame number where
recording started */
#define SOURCE_MIC 0 #define SOURCE_MIC 0
#define SOURCE_LINE 1 #define SOURCE_LINE 1
#define SOURCE_SPDIF 2 #define SOURCE_SPDIF 2
@ -89,25 +79,6 @@ static char *fmtstr[] =
"%d.%02d %s " /* 2 decimals */ "%d.%02d %s " /* 2 decimals */
}; };
/* This array holds the record timer interval lengths, in seconds */
static unsigned long rec_timer_seconds[] =
{
0, /* off */
5*60, /* 00:05 */
10*60, /* 00:10 */
15*60, /* 00:15 */
30*60, /* 00:30 */
60*60, /* 01:00 */
2*60*60, /* 02:00 */
4*60*60, /* 04:00 */
6*60*60, /* 06:00 */
8*60*60, /* 08:00 */
10*60*60, /* 10:00 */
12*60*60, /* 12:00 */
18*60*60, /* 18:00 */
24*60*60 /* 24:00 */
};
char *fmt_gain(int snd, int val, char *str, int len) char *fmt_gain(int snd, int val, char *str, int len)
{ {
int tmp, i, d, numdec; int tmp, i, d, numdec;
@ -169,8 +140,8 @@ bool recording_screen(void)
int w, h; int w, h;
int update_countdown = 1; int update_countdown = 1;
bool have_recorded = false; bool have_recorded = false;
unsigned long seconds; unsigned int seconds;
unsigned long last_seconds = 0; unsigned int last_seconds = 0;
int hours, minutes; int hours, minutes;
cursor = 0; cursor = 0;
@ -225,13 +196,13 @@ bool recording_screen(void)
mpeg_record(rec_create_filename()); mpeg_record(rec_create_filename());
status_set_playmode(STATUS_RECORD); status_set_playmode(STATUS_RECORD);
update_countdown = 1; /* Update immediately */ update_countdown = 1; /* Update immediately */
last_seconds = 0;
} }
else else
{ {
mpeg_new_file(rec_create_filename()); mpeg_new_file(rec_create_filename());
update_countdown = 1; /* Update immediately */ update_countdown = 1; /* Update immediately */
} }
last_seconds = 0;
break; break;
case BUTTON_UP: case BUTTON_UP:
@ -331,7 +302,7 @@ bool recording_screen(void)
break; break;
case BUTTON_F1: case BUTTON_F1:
if (recording_menu()) if (recording_menu(false))
return SYS_USB_CONNECTED; return SYS_USB_CONNECTED;
settings_save(); settings_save();
mpeg_set_recording_options(global_settings.rec_frequency, mpeg_set_recording_options(global_settings.rec_frequency,
@ -348,8 +319,12 @@ bool recording_screen(void)
if(!mpeg_status()) if(!mpeg_status())
{ {
if (f2_rec_screen()) if (f2_rec_screen())
return SYS_USB_CONNECTED; {
update_countdown = 1; /* Update immediately */ have_recorded = true;
done = true;
}
else
update_countdown = 1; /* Update immediately */
} }
break; break;
@ -357,11 +332,24 @@ bool recording_screen(void)
if(!mpeg_status()) if(!mpeg_status())
{ {
if (f3_rec_screen()) if (f3_rec_screen())
return SYS_USB_CONNECTED; {
update_countdown = 1; /* Update immediately */ have_recorded = true;
done = true;
}
else
update_countdown = 1; /* Update immediately */
} }
break; break;
case SYS_USB_CONNECTED:
/* Only accept USB connection when not recording */
if(!mpeg_status())
{
usb_screen();
have_recorded = true; /* Refreshes the browser later on */
done = true;
}
break;
} }
peak_meter_peek(); peak_meter_peek();
@ -377,6 +365,7 @@ bool recording_screen(void)
update_countdown--; update_countdown--;
if(update_countdown == 0 || seconds > last_seconds) if(update_countdown == 0 || seconds > last_seconds)
{ {
unsigned int dseconds, dhours, dminutes;
int pos = 0; int pos = 0;
update_countdown = 5; update_countdown = 5;
@ -391,20 +380,12 @@ bool recording_screen(void)
hours, minutes, seconds%60); hours, minutes, seconds%60);
lcd_puts(0, 0, buf); lcd_puts(0, 0, buf);
/* if the record timesplit is active */ dseconds = rec_timesplit_seconds();
/* Display the split interval if the record timesplit
is active */
if (global_settings.rec_timesplit) if (global_settings.rec_timesplit)
{ {
unsigned long dseconds, dhours, dminutes;
int rti = global_settings.rec_timesplit;
dseconds = rec_timer_seconds[rti];
if (mpeg_status() && (seconds >= dseconds))
{
mpeg_new_file(rec_create_filename());
update_countdown = 1;
last_seconds = 0;
}
/* Display the record timesplit interval rather than /* Display the record timesplit interval rather than
the file size if the record timer is active */ the file size if the record timer is active */
dhours = dseconds / 3600; dhours = dseconds / 3600;
@ -418,6 +399,16 @@ bool recording_screen(void)
num2max5(mpeg_num_recorded_bytes(), buf2)); num2max5(mpeg_num_recorded_bytes(), buf2));
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
/* We will do file splitting regardless, since the OFF
setting really means 24 hours. This is to make sure
that the recorded files don't get too big. */
if (mpeg_status() && (seconds >= dseconds))
{
mpeg_new_file(rec_create_filename());
update_countdown = 1;
last_seconds = 0;
}
peak_meter_draw(0, 8 + h*2, LCD_WIDTH, h); peak_meter_draw(0, 8 + h*2, LCD_WIDTH, h);
/* Show mic gain if input source is Mic */ /* Show mic gain if input source is Mic */
@ -518,12 +509,10 @@ bool recording_screen(void)
mpeg_sound_set(SOUND_TREBLE, global_settings.treble); mpeg_sound_set(SOUND_TREBLE, global_settings.treble);
mpeg_sound_set(SOUND_BALANCE, global_settings.balance); mpeg_sound_set(SOUND_BALANCE, global_settings.balance);
mpeg_sound_set(SOUND_VOLUME, global_settings.volume); mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
#ifdef HAVE_MAS3587F
mpeg_sound_set(SOUND_LOUDNESS, global_settings.loudness); mpeg_sound_set(SOUND_LOUDNESS, global_settings.loudness);
mpeg_sound_set(SOUND_SUPERBASS, global_settings.bass_boost); mpeg_sound_set(SOUND_SUPERBASS, global_settings.bass_boost);
mpeg_sound_set(SOUND_AVC, global_settings.avc); mpeg_sound_set(SOUND_AVC, global_settings.avc);
#endif
lcd_setfont(FONT_UI); lcd_setfont(FONT_UI);
return have_recorded; return have_recorded;
} }

View file

@ -1988,3 +1988,29 @@ bool set_time(char* string, int timedate[])
return false; return false;
} }
#endif #endif
#ifdef HAVE_MAS3587F
/* This array holds the record timer interval lengths, in seconds */
static unsigned long rec_timer_seconds[] =
{
24*60*60, /* OFF really means 24 hours, to avoid >2Gbyte files */
5*60, /* 00:05 */
10*60, /* 00:10 */
15*60, /* 00:15 */
30*60, /* 00:30 */
60*60, /* 01:00 */
2*60*60, /* 02:00 */
4*60*60, /* 04:00 */
6*60*60, /* 06:00 */
8*60*60, /* 08:00 */
10*60*60, /* 10:00 */
12*60*60, /* 12:00 */
18*60*60, /* 18:00 */
24*60*60 /* 24:00 */
};
unsigned int rec_timesplit_seconds(void)
{
return rec_timer_seconds[global_settings.rec_timesplit];
}
#endif

View file

@ -199,6 +199,10 @@ bool set_int(char* string, char* unit, int* variable,
bool set_time(char* string, int timedate[]); bool set_time(char* string, int timedate[]);
void set_file(char* filename, char* setting, int maxlen); void set_file(char* filename, char* setting, int maxlen);
#ifdef HAVE_MAS3587F
unsigned int rec_timesplit_seconds(void);
#endif
/* global settings */ /* global settings */
extern struct user_settings global_settings; extern struct user_settings global_settings;
/* name of directory where configuration, fonts and other data /* name of directory where configuration, fonts and other data

View file

@ -290,20 +290,29 @@ bool sound_menu(void)
} }
#ifdef HAVE_MAS3587F #ifdef HAVE_MAS3587F
bool recording_menu(void) bool recording_menu(bool no_source)
{ {
int m; int m;
int i = 0;
struct menu_items menu[6];
bool result; bool result;
struct menu_items items[] = {
{ str(LANG_RECORDING_QUALITY), recquality },
{ str(LANG_RECORDING_FREQUENCY), recfrequency },
{ str(LANG_RECORDING_SOURCE), recsource },
{ str(LANG_RECORDING_CHANNELS), recchannels },
{ str(LANG_RECORDING_EDITABLE), receditable },
{ str(LANG_RECORD_TIMESPLIT), rectimesplit },
};
m=menu_init( items, sizeof items / sizeof(struct menu_items) ); menu[i].desc = str(LANG_RECORDING_QUALITY);
menu[i++].function = recquality;
menu[i].desc = str(LANG_RECORDING_FREQUENCY);
menu[i++].function = recfrequency;
if(!no_source) {
menu[i].desc = str(LANG_RECORDING_SOURCE);
menu[i++].function = recsource;
}
menu[i].desc = str(LANG_RECORDING_CHANNELS);
menu[i++].function = recchannels;
menu[i].desc = str(LANG_RECORDING_EDITABLE);
menu[i++].function = receditable;
menu[i].desc = str(LANG_RECORD_TIMESPLIT);
menu[i++].function = rectimesplit;
m=menu_init( menu, i );
result = menu_run(m); result = menu_run(m);
menu_exit(m); menu_exit(m);

View file

@ -22,6 +22,6 @@
#include "menu.h" #include "menu.h"
bool sound_menu(void); bool sound_menu(void);
bool recording_menu(void); bool recording_menu(bool no_source);
#endif #endif

View file

@ -167,7 +167,7 @@ static int defaultval[] =
0, /* AVC */ 0, /* AVC */
0, /* Channels */ 0, /* Channels */
8, /* Left gain */ 8, /* Left gain */
2, /* Right gain */ 8, /* Right gain */
2, /* Mic gain */ 2, /* Mic gain */
}; };
@ -2157,6 +2157,21 @@ static void mpeg_thread(void)
init_playback(); init_playback();
init_playback_done = true; init_playback_done = true;
break; break;
case SYS_USB_CONNECTED:
is_playing = false;
paused = false;
stop_playing();
#ifndef SIMULATOR
/* Tell the USB thread that we are safe */
DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
usb_acknowledge(SYS_USB_CONNECTED_ACK);
/* Wait until the USB cable is extracted again */
usb_wait_for_disconnect(&mpeg_queue);
#endif
break;
} }
} }
#endif #endif