📄 radio.c
字号:
/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: radio.c,v 1.22 2004/03/11 11:00:38 linusnielsen Exp $ * * Copyright (C) 2003 Linus Nielsen Feltzing * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/#include "config.h"#include <stdio.h>#include <stdbool.h>#include "sprintf.h"#include "lcd.h"#include "mas.h"#include "settings.h"#include "button.h"#include "fmradio.h"#include "status.h"#include "kernel.h"#include "mpeg.h"#include "mp3_playback.h"#include "ctype.h"#include "file.h"#include "errno.h"#include "atoi.h"#include "string.h"#include "system.h"#include "radio.h"#include "menu.h"#include "misc.h"#include "keyboard.h"#include "screens.h"#include "peakmeter.h"#include "lang.h"#include "font.h"#include "sound_menu.h"#include "recording.h"#ifdef HAVE_FMRADIO#define MAX_FREQ (108000000)#define MIN_FREQ (87500000)#define PLL_FREQ_STEP 10000#define FREQ_STEP 100000static int curr_preset = -1;static int curr_freq = 99400000;static int pll_cnt;#define MAX_PRESETS 32static bool presets_loaded = false;static struct fmstation presets[MAX_PRESETS];static char default_filename[] = "/.rockbox/fm-presets-default.fmr";int debug_fm_detection;void radio_load_presets(void);bool radio_preset_select(void);bool radio_menu(void);void radio_stop(void){ /* Mute the FM radio */ fmradio_set(1, 0x100003);}bool radio_hardware_present(void){ int val; fmradio_set(2, 0x140885); /* 5kHz, 7.2MHz crystal, test mode 1 */ val = fmradio_read(0); debug_fm_detection = val; if(val == 0x140885) return true; else return false;}void radio_set_frequency(int freq){ /* We add the standard Intermediate Frequency 10.7MHz before calculating ** the divisor ** The reference frequency is set to 50kHz, and the VCO output is prescaled ** by 2. */ pll_cnt = (freq + 10700000) / (PLL_FREQ_STEP/2) / 2; /* 0x100000 == FM mode ** 0x000002 == Microprocessor controlled Mute */ fmradio_set(1, 0x100002 | pll_cnt << 3);}static int find_preset(int freq){ int i; for(i = 0;i < MAX_PRESETS;i++) { if(freq == presets[i].frequency) return i; } return -1;}bool radio_screen(void){ char buf[MAX_PATH]; bool done = false; int button; int val; int freq; int i_freq; bool stereo = false; int search_dir = 0; int fw, fh; int last_stereo_status = false; int top_of_screen = 0; bool update_screen = true; int timeout = current_tick + HZ/10; 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_setmargins(0, 8); status_draw(true); fmradio_set_status(FMRADIO_PLAYING); font_get(FONT_UI); lcd_getstringsize("M", &fw, &fh); /* Adjust for font size, trying to center the information vertically */ if(fh < 10) top_of_screen = 1; radio_load_presets(); mpeg_stop(); mpeg_init_recording(); 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); 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, global_settings.rec_prerecord_time); 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 */ radio_set_frequency(curr_freq); curr_preset = find_preset(curr_freq); /* We use the A/D pseudo peak */ peak_meter_playback(false); peak_meter_enabled = true; buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); while(!done) { if(search_dir) { curr_freq += search_dir * FREQ_STEP; if(curr_freq < MIN_FREQ) curr_freq = MAX_FREQ; if(curr_freq > MAX_FREQ) curr_freq = MIN_FREQ; /* Tune in and delay */ radio_set_frequency(curr_freq); sleep(1); /* Start IF measurement */ fmradio_set(1, 0x100006 | pll_cnt << 3); sleep(1); /* Now check how close to the IF frequency we are */ val = fmradio_read(3); i_freq = (val & 0x7ffff) / 80; /* Stop searching if the IF frequency is close to 10.7MHz */ if(i_freq > 1065 && i_freq < 1075) { search_dir = 0; curr_preset = find_preset(curr_freq); } update_screen = true; } if(search_dir) button = button_get(false); else button = button_get_w_tmo(HZ / peak_meter_fps); switch(button) { case BUTTON_OFF: if(mpeg_status() == MPEG_STATUS_RECORD) { mpeg_stop(); status_set_playmode(STATUS_STOP); } else { radio_stop(); done = true; } update_screen = true; break; case BUTTON_F3: if(mpeg_status() == MPEG_STATUS_RECORD) { mpeg_new_file(rec_create_filename(buf)); update_screen = true; } else { have_recorded = true; mpeg_record(rec_create_filename(buf)); status_set_playmode(STATUS_RECORD); update_screen = true; } last_seconds = 0; break; case BUTTON_ON | BUTTON_REL: done = true; keep_playing = true; break; case BUTTON_LEFT: curr_freq -= FREQ_STEP; if(curr_freq < MIN_FREQ) curr_freq = MIN_FREQ; radio_set_frequency(curr_freq); curr_preset = find_preset(curr_freq); search_dir = 0; update_screen = true; break; case BUTTON_RIGHT: curr_freq += FREQ_STEP; if(curr_freq > MAX_FREQ) curr_freq = MAX_FREQ; radio_set_frequency(curr_freq); curr_preset = find_preset(curr_freq); search_dir = 0; update_screen = true; break; case BUTTON_LEFT | BUTTON_REPEAT: search_dir = -1; break; case BUTTON_RIGHT | BUTTON_REPEAT: search_dir = 1; break; case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: global_settings.volume++; if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME)) global_settings.volume = mpeg_sound_max(SOUND_VOLUME); mpeg_sound_set(SOUND_VOLUME, global_settings.volume); update_screen = true; settings_save(); break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: global_settings.volume--; if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME)) global_settings.volume = mpeg_sound_min(SOUND_VOLUME); mpeg_sound_set(SOUND_VOLUME, global_settings.volume); update_screen = true; settings_save(); break; case BUTTON_F1: radio_menu(); curr_preset = find_preset(curr_freq); lcd_clear_display(); lcd_setmargins(0, 8); buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); update_screen = true; break; case BUTTON_F2: radio_preset_select(); curr_preset = find_preset(curr_freq); lcd_clear_display(); lcd_setmargins(0, 8); buttonbar_set(str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); update_screen = true; break; case BUTTON_PLAY: if(!screen_freeze) { splash(0, true, "Screen frozen"); lcd_update(); screen_freeze = true; } else { update_screen = true; screen_freeze = false; } break; case SYS_USB_CONNECTED: /* Only accept USB connection when not recording */ if(mpeg_status() != MPEG_STATUS_RECORD) { usb_screen(); fmradio_set_status(0); screen_freeze = true; /* Cosmetic: makes sure the radio screen doesn't redraw */ done = true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -