mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Xing headers now support mono better, added the 'editable files' option
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3572 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
c6fb565dd9
commit
478da628f0
10 changed files with 153 additions and 91 deletions
|
|
@ -1467,3 +1467,8 @@ id: LANG_INVERT_CURSOR
|
||||||
desc: in settings_menu
|
desc: in settings_menu
|
||||||
eng: "Invert cursor"
|
eng: "Invert cursor"
|
||||||
new:
|
new:
|
||||||
|
|
||||||
|
id: LANG_RECORDING_EDITABLE
|
||||||
|
desc: Editable recordings setting
|
||||||
|
eng: "Editable files"
|
||||||
|
new:
|
||||||
|
|
|
||||||
|
|
@ -251,11 +251,11 @@ static bool vbr_fix(void)
|
||||||
flen, xingupdate);
|
flen, xingupdate);
|
||||||
|
|
||||||
if(num_frames) {
|
if(num_frames) {
|
||||||
/* Note: We don't need to pass any values for mpeg_version and
|
/* Note: We don't need to pass a template header because it will be
|
||||||
sample_rate because they will be extracted from the mpeg stream */
|
taken from the mpeg stream */
|
||||||
framelen = create_xing_header(fd, entry.first_frame_offset,
|
framelen = create_xing_header(fd, entry.first_frame_offset,
|
||||||
flen, xingbuf, num_frames,
|
flen, xingbuf, num_frames,
|
||||||
0, 0, xingupdate, true);
|
0, xingupdate, true);
|
||||||
|
|
||||||
/* Try to fit the Xing header first in the stream. Replace the existing
|
/* Try to fit the Xing header first in the stream. Replace the existing
|
||||||
VBR header if there is one, else see if there is room between the
|
VBR header if there is one, else see if there is room between the
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,8 @@ bool recording_screen(void)
|
||||||
mpeg_set_recording_options(global_settings.rec_frequency,
|
mpeg_set_recording_options(global_settings.rec_frequency,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_quality,
|
||||||
global_settings.rec_source,
|
global_settings.rec_source,
|
||||||
global_settings.rec_channels);
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable);
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
|
|
@ -312,22 +313,29 @@ bool recording_screen(void)
|
||||||
mpeg_set_recording_options(global_settings.rec_frequency,
|
mpeg_set_recording_options(global_settings.rec_frequency,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_quality,
|
||||||
global_settings.rec_source,
|
global_settings.rec_source,
|
||||||
global_settings.rec_channels);
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable);
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
update_countdown = 1; /* Update immediately */
|
update_countdown = 1; /* Update immediately */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_F2:
|
case BUTTON_F2:
|
||||||
|
if(mpeg_status())
|
||||||
|
{
|
||||||
if (f2_rec_screen())
|
if (f2_rec_screen())
|
||||||
return SYS_USB_CONNECTED;
|
return SYS_USB_CONNECTED;
|
||||||
update_countdown = 1; /* Update immediately */
|
update_countdown = 1; /* Update immediately */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_F3:
|
case BUTTON_F3:
|
||||||
|
if(mpeg_status())
|
||||||
|
{
|
||||||
if (f3_rec_screen())
|
if (f3_rec_screen())
|
||||||
return SYS_USB_CONNECTED;
|
return SYS_USB_CONNECTED;
|
||||||
update_countdown = 1; /* Update immediately */
|
update_countdown = 1; /* Update immediately */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -537,7 +545,8 @@ bool f2_rec_screen(void)
|
||||||
mpeg_set_recording_options(global_settings.rec_frequency,
|
mpeg_set_recording_options(global_settings.rec_frequency,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_quality,
|
||||||
global_settings.rec_source,
|
global_settings.rec_source,
|
||||||
global_settings.rec_channels);
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable);
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
|
|
@ -621,7 +630,8 @@ bool f3_rec_screen(void)
|
||||||
mpeg_set_recording_options(global_settings.rec_frequency,
|
mpeg_set_recording_options(global_settings.rec_frequency,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_quality,
|
||||||
global_settings.rec_source,
|
global_settings.rec_source,
|
||||||
global_settings.rec_channels);
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable);
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ offset abs
|
||||||
0x16 0x2a <(int) Byte offset into resume file>
|
0x16 0x2a <(int) Byte offset into resume file>
|
||||||
0x1a 0x2e <time until disk spindown>
|
0x1a 0x2e <time until disk spindown>
|
||||||
0x1b 0x2f <browse current, play selected, queue_resume>
|
0x1b 0x2f <browse current, play selected, queue_resume>
|
||||||
0x1c 0x30 <peak meter hold timeout (bit 0-4)>,
|
0x1c 0x30 <peak meter hold timeout (bit 0-4),
|
||||||
peak_meter_performance (bit 7)
|
rec_editable (bit 7)>
|
||||||
0x1d 0x31 <(int) queue resume index>
|
0x1d 0x31 <(int) queue resume index>
|
||||||
0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2),
|
0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2),
|
||||||
mic gain (bit 4-7)>
|
mic gain (bit 4-7)>
|
||||||
|
|
@ -125,7 +125,7 @@ modified unless the header & checksum test fails.
|
||||||
|
|
||||||
Rest of config block, only saved to disk:
|
Rest of config block, only saved to disk:
|
||||||
0xAE fade on pause/unpause/stop setting (bit 0)
|
0xAE fade on pause/unpause/stop setting (bit 0)
|
||||||
0xB0 peak meter clip hold timeout (bit 0-4)
|
0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7)
|
||||||
0xB1 peak meter release step size, peak_meter_dbfs (bit 7)
|
0xB1 peak meter release step size, peak_meter_dbfs (bit 7)
|
||||||
0xB2 peak meter min either in -db or in percent
|
0xB2 peak meter min either in -db or in percent
|
||||||
0xB3 peak meter max either in -db or in percent
|
0xB3 peak meter max either in -db or in percent
|
||||||
|
|
@ -341,7 +341,8 @@ int settings_save( void )
|
||||||
((global_settings.play_selected & 1) << 1) |
|
((global_settings.play_selected & 1) << 1) |
|
||||||
((global_settings.queue_resume & 3) << 2));
|
((global_settings.queue_resume & 3) << 2));
|
||||||
|
|
||||||
config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold;
|
config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold |
|
||||||
|
(global_settings.rec_editable?0x80:0);
|
||||||
|
|
||||||
memcpy(&config_block[0x1d], &global_settings.queue_resume_index, 4);
|
memcpy(&config_block[0x1d], &global_settings.queue_resume_index, 4);
|
||||||
|
|
||||||
|
|
@ -617,8 +618,11 @@ void settings_load(void)
|
||||||
global_settings.queue_resume = (config_block[0x1b] >> 2) & 3;
|
global_settings.queue_resume = (config_block[0x1b] >> 2) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_block[0x1c] != 0xFF)
|
if (config_block[0x1c] != 0xFF) {
|
||||||
global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f;
|
global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f;
|
||||||
|
global_settings.rec_editable =
|
||||||
|
config_block[0x1c]?true:false;
|
||||||
|
}
|
||||||
|
|
||||||
if (config_block[0x1d] != 0xFF)
|
if (config_block[0x1d] != 0xFF)
|
||||||
memcpy(&global_settings.queue_resume_index, &config_block[0x1d],
|
memcpy(&global_settings.queue_resume_index, &config_block[0x1d],
|
||||||
|
|
@ -1029,6 +1033,9 @@ bool settings_load_config(char* file)
|
||||||
static char* options[] = {"stereo", "mono"};
|
static char* options[] = {"stereo", "mono"};
|
||||||
set_cfg_option(&global_settings.rec_channels, value, options, 2);
|
set_cfg_option(&global_settings.rec_channels, value, options, 2);
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "editable recordings")) {
|
||||||
|
set_cfg_bool(&global_settings.rec_editable, value);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (!strcasecmp(name, "idle poweroff")) {
|
else if (!strcasecmp(name, "idle poweroff")) {
|
||||||
static char* options[] = {"off","1","2","3","4","5","6","7","8",
|
static char* options[] = {"off","1","2","3","4","5","6","7","8",
|
||||||
|
|
@ -1434,6 +1441,14 @@ bool settings_save_config(void)
|
||||||
global_settings.rec_left_gain,
|
global_settings.rec_left_gain,
|
||||||
global_settings.rec_right_gain);
|
global_settings.rec_right_gain);
|
||||||
write(fd, buf, strlen(buf));
|
write(fd, buf, strlen(buf));
|
||||||
|
|
||||||
|
{
|
||||||
|
static char* options[] = {"off", "on"};
|
||||||
|
snprintf(buf, sizeof(buf), "editable recordings: %s\r\n",
|
||||||
|
options[global_settings.rec_editable]);
|
||||||
|
write(fd, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
|
@ -1467,6 +1482,7 @@ void settings_reset(void) {
|
||||||
global_settings.rec_mic_gain = 8;
|
global_settings.rec_mic_gain = 8;
|
||||||
global_settings.rec_left_gain = 2; /* 0dB */
|
global_settings.rec_left_gain = 2; /* 0dB */
|
||||||
global_settings.rec_right_gain = 2; /* 0dB */
|
global_settings.rec_right_gain = 2; /* 0dB */
|
||||||
|
global_settings.rec_editable = false;
|
||||||
global_settings.resume = RESUME_ASK;
|
global_settings.resume = RESUME_ASK;
|
||||||
global_settings.contrast = DEFAULT_CONTRAST_SETTING;
|
global_settings.contrast = DEFAULT_CONTRAST_SETTING;
|
||||||
global_settings.invert = DEFAULT_INVERT_SETTING;
|
global_settings.invert = DEFAULT_INVERT_SETTING;
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ struct user_settings
|
||||||
int rec_mic_gain; /* 0-15 */
|
int rec_mic_gain; /* 0-15 */
|
||||||
int rec_left_gain; /* 0-15 */
|
int rec_left_gain; /* 0-15 */
|
||||||
int rec_right_gain; /* 0-15 */
|
int rec_right_gain; /* 0-15 */
|
||||||
|
bool rec_editable; /* true means that the bit reservoir is off */
|
||||||
|
|
||||||
/* device settings */
|
/* device settings */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,12 @@ static bool recquality(void)
|
||||||
&global_settings.rec_quality,
|
&global_settings.rec_quality,
|
||||||
NULL, 1, 0, 7 );
|
NULL, 1, 0, 7 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool receditable(void)
|
||||||
|
{
|
||||||
|
return set_bool(str(LANG_RECORDING_EDITABLE),
|
||||||
|
&global_settings.rec_editable);
|
||||||
|
}
|
||||||
#endif /* HAVE_MAS3587F */
|
#endif /* HAVE_MAS3587F */
|
||||||
|
|
||||||
static void set_chanconf(int val)
|
static void set_chanconf(int val)
|
||||||
|
|
@ -275,6 +281,7 @@ bool recording_menu(void)
|
||||||
{ str(LANG_RECORDING_FREQUENCY), recfrequency },
|
{ str(LANG_RECORDING_FREQUENCY), recfrequency },
|
||||||
{ str(LANG_RECORDING_SOURCE), recsource },
|
{ str(LANG_RECORDING_SOURCE), recsource },
|
||||||
{ str(LANG_RECORDING_CHANNELS), recchannels },
|
{ str(LANG_RECORDING_CHANNELS), recchannels },
|
||||||
|
{ str(LANG_RECORDING_EDITABLE), receditable },
|
||||||
};
|
};
|
||||||
|
|
||||||
m=menu_init( items, sizeof items / sizeof(struct menu_items) );
|
m=menu_init( items, sizeof items / sizeof(struct menu_items) );
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ int count_mp3_frames(int fd, int startpos, int filesize,
|
||||||
void (*progressfunc)(int));
|
void (*progressfunc)(int));
|
||||||
int create_xing_header(int fd, int startpos, int filesize,
|
int create_xing_header(int fd, int startpos, int filesize,
|
||||||
unsigned char *buf, int num_frames,
|
unsigned char *buf, int num_frames,
|
||||||
int mpeg_version, int sample_rate,
|
unsigned long header_template,
|
||||||
void (*progressfunc)(int), bool generate_toc);
|
void (*progressfunc)(int), bool generate_toc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@
|
||||||
#define MPEG_PLAY_PENDING_THRESHOLD 0x10000
|
#define MPEG_PLAY_PENDING_THRESHOLD 0x10000
|
||||||
#define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
|
#define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
|
||||||
|
|
||||||
|
/* For ID3 info and VBR header */
|
||||||
|
#define MPEG_RESERVED_HEADER_SPACE (4096 + 1500)
|
||||||
|
|
||||||
struct mpeg_debug
|
struct mpeg_debug
|
||||||
{
|
{
|
||||||
int mp3buflen;
|
int mp3buflen;
|
||||||
|
|
@ -84,7 +87,8 @@ void mpeg_init_recording(void);
|
||||||
void mpeg_init_playback(void);
|
void mpeg_init_playback(void);
|
||||||
void mpeg_record(char *filename);
|
void mpeg_record(char *filename);
|
||||||
void mpeg_set_recording_options(int frequency, int quality,
|
void mpeg_set_recording_options(int frequency, int quality,
|
||||||
int source, int channel_mode);
|
int source, int channel_mode,
|
||||||
|
bool editable);
|
||||||
void mpeg_set_recording_gain(int left, int right, int mic);
|
void mpeg_set_recording_gain(int left, int right, int mic);
|
||||||
unsigned long mpeg_recorded_time(void);
|
unsigned long mpeg_recorded_time(void);
|
||||||
unsigned long mpeg_num_recorded_bytes(void);
|
unsigned long mpeg_num_recorded_bytes(void);
|
||||||
|
|
|
||||||
|
|
@ -530,14 +530,6 @@ int get_mp3file_info(int fd, struct mp3info *info)
|
||||||
return bytecount;
|
return bytecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an MP3 header, 128kbit/s, with silence
|
|
||||||
MPEG version and sample frequency are not set */
|
|
||||||
static const unsigned char xing_frame_header[] = {
|
|
||||||
0xff, 0xe2, 0x90, 0x64, 0x86, 0x1f
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char cooltext[] = "Rockbox rocks";
|
|
||||||
|
|
||||||
static void int2bytes(unsigned char *buf, int val)
|
static void int2bytes(unsigned char *buf, int val)
|
||||||
{
|
{
|
||||||
buf[0] = (val >> 24) & 0xff;
|
buf[0] = (val >> 24) & 0xff;
|
||||||
|
|
@ -602,55 +594,30 @@ int count_mp3_frames(int fd, int startpos, int filesize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: mpeg_version and sample_rate are 2-bit values, as specified by the
|
static const char cooltext[] = "Rockbox - rocks your box";
|
||||||
MPEG frame standard. See the tables above. */
|
|
||||||
int create_xing_header(int fd, int startpos, int filesize,
|
int create_xing_header(int fd, int startpos, int filesize,
|
||||||
unsigned char *buf, int num_frames,
|
unsigned char *buf, int num_frames,
|
||||||
int mpeg_version, int sample_rate,
|
unsigned long header_template,
|
||||||
void (*progressfunc)(int), bool generate_toc)
|
void (*progressfunc)(int), bool generate_toc)
|
||||||
{
|
{
|
||||||
unsigned long header = 0;
|
unsigned long header = 0;
|
||||||
unsigned long saved_header = 0;
|
|
||||||
struct mp3info info;
|
struct mp3info info;
|
||||||
int pos, last_pos;
|
int pos, last_pos;
|
||||||
int i, j;
|
int i, j;
|
||||||
int bytes;
|
int bytes;
|
||||||
int filepos;
|
int filepos;
|
||||||
int tocentry;
|
|
||||||
int x;
|
int x;
|
||||||
int index;
|
int index;
|
||||||
|
unsigned char toc[100];
|
||||||
|
|
||||||
DEBUGF("create_xing_header()\n");
|
DEBUGF("create_xing_header()\n");
|
||||||
|
|
||||||
/* Create the frame header */
|
if(generate_toc)
|
||||||
memset(buf, 0, 1500);
|
{
|
||||||
memcpy(buf, xing_frame_header, 6);
|
|
||||||
|
|
||||||
lseek(fd, startpos, SEEK_SET);
|
lseek(fd, startpos, SEEK_SET);
|
||||||
buf_init();
|
buf_init();
|
||||||
|
|
||||||
buf[36] = 'X';
|
|
||||||
buf[36+1] = 'i';
|
|
||||||
buf[36+2] = 'n';
|
|
||||||
buf[36+3] = 'g';
|
|
||||||
int2bytes(&buf[36+4], ((num_frames?VBR_FRAMES_FLAG:0) |
|
|
||||||
(filesize?VBR_BYTES_FLAG:0) |
|
|
||||||
(generate_toc?VBR_TOC_FLAG:0)));
|
|
||||||
index = 36+8;
|
|
||||||
if(num_frames)
|
|
||||||
{
|
|
||||||
int2bytes(&buf[index], num_frames);
|
|
||||||
index += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(filesize)
|
|
||||||
{
|
|
||||||
int2bytes(&buf[index], filesize - startpos);
|
|
||||||
index += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(generate_toc)
|
|
||||||
{
|
|
||||||
/* Generate filepos table */
|
/* Generate filepos table */
|
||||||
last_pos = 0;
|
last_pos = 0;
|
||||||
filepos = 0;
|
filepos = 0;
|
||||||
|
|
@ -670,48 +637,90 @@ int create_xing_header(int fd, int startpos, int filesize,
|
||||||
filepos += info.frame_size;
|
filepos += info.frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save one header for later use */
|
/* Save a header for later use. Yes, we may be passed a header
|
||||||
|
template in the header_template argument, but since we are
|
||||||
|
reading headers from the stream anyway, we might as well
|
||||||
|
use the ones we find. However, we only save one header, and
|
||||||
|
we want to save one in te middle of the stream, just in case
|
||||||
|
the first and the last headers are corrupt. */
|
||||||
if(i == 1)
|
if(i == 1)
|
||||||
saved_header = header;
|
header_template = header;
|
||||||
|
|
||||||
if(progressfunc)
|
if(progressfunc)
|
||||||
{
|
{
|
||||||
progressfunc(50 + i/2);
|
progressfunc(50 + i/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
tocentry = filepos * 256 / filesize;
|
/* Fill in the TOC entry */
|
||||||
|
toc[i] = filepos * 256 / filesize;
|
||||||
|
|
||||||
DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
|
DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
|
||||||
i, pos, pos-last_pos, filepos, tocentry);
|
i, pos, pos-last_pos, filepos, toc[i]);
|
||||||
|
|
||||||
/* Fill in the TOC entry */
|
|
||||||
buf[index + i] = tocentry;
|
|
||||||
|
|
||||||
last_pos = pos;
|
last_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the MPEG version and sample rate from the mpeg stream into
|
|
||||||
the Xing header */
|
|
||||||
saved_header &= (VERSION_MASK | SAMPLERATE_MASK);
|
|
||||||
|
|
||||||
buf[1] |= (saved_header >> 16) & 0xff;
|
|
||||||
buf[2] |= (saved_header >> 8) & 0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the frame */
|
||||||
|
memset(buf, 0, 1500);
|
||||||
|
|
||||||
|
/* Use the template header and create a new one */
|
||||||
|
mp3headerinfo(&info, header_template);
|
||||||
|
|
||||||
|
/* calculate position of VBR header */
|
||||||
|
if ( info.version == MPEG_VERSION1 ) {
|
||||||
|
if (info.channel_mode == 3) /* mono */
|
||||||
|
index = 21;
|
||||||
else
|
else
|
||||||
{
|
index = 36;
|
||||||
/* Fill in the MPEG version and sample rate into the Xing header */
|
}
|
||||||
buf[1] |= mpeg_version << 3;
|
else {
|
||||||
buf[2] |= sample_rate << 2;
|
if (info.channel_mode == 3) /* mono */
|
||||||
|
index = 13;
|
||||||
|
else
|
||||||
|
index = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf + index + 100, cooltext, sizeof(cooltext));
|
/* We ignore the Protection bit even if the rest of the stream is
|
||||||
|
protected. (fixme?) */
|
||||||
|
header = header_template & ~(BITRATE_MASK | PROTECTION_MASK);
|
||||||
|
header |= 8 << 12; /* This gives us plenty of space, at least 192 bytes */
|
||||||
|
|
||||||
|
/* Write the header to the buffer */
|
||||||
|
int2bytes(buf, header);
|
||||||
|
|
||||||
/* Now get the length of the newly created frame */
|
/* Now get the length of the newly created frame */
|
||||||
header = BYTES2INT(buf[0], buf[1], buf[2], buf[3]);
|
|
||||||
mp3headerinfo(&info, header);
|
mp3headerinfo(&info, header);
|
||||||
|
|
||||||
|
/* Create the Xing data */
|
||||||
|
buf[index] = 'X';
|
||||||
|
buf[index+1] = 'i';
|
||||||
|
buf[index+2] = 'n';
|
||||||
|
buf[index+3] = 'g';
|
||||||
|
int2bytes(&buf[index+4], ((num_frames?VBR_FRAMES_FLAG:0) |
|
||||||
|
(filesize?VBR_BYTES_FLAG:0) |
|
||||||
|
(generate_toc?VBR_TOC_FLAG:0)));
|
||||||
|
index = index+8;
|
||||||
|
if(num_frames)
|
||||||
|
{
|
||||||
|
int2bytes(&buf[index], num_frames);
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filesize)
|
||||||
|
{
|
||||||
|
int2bytes(&buf[index], filesize - startpos);
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the TOC */
|
||||||
|
memcpy(buf + index, toc, 100);
|
||||||
|
|
||||||
|
/* And some extra cool info */
|
||||||
|
memcpy(buf + index + 100, cooltext, sizeof(cooltext));
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for(i = 0;i < 417;i++)
|
for(i = 0;i < info.framesize;i++)
|
||||||
{
|
{
|
||||||
if(i && !(i % 16))
|
if(i && !(i % 16))
|
||||||
DEBUGF("\n");
|
DEBUGF("\n");
|
||||||
|
|
|
||||||
|
|
@ -1266,6 +1266,7 @@ static void mpeg_thread(void)
|
||||||
int amount_to_save;
|
int amount_to_save;
|
||||||
int writelen;
|
int writelen;
|
||||||
int framelen;
|
int framelen;
|
||||||
|
unsigned long saved_header;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
is_playing = false;
|
is_playing = false;
|
||||||
|
|
@ -1840,10 +1841,10 @@ static void mpeg_thread(void)
|
||||||
DEBUGF("Recording...\n");
|
DEBUGF("Recording...\n");
|
||||||
reset_mp3_buffer();
|
reset_mp3_buffer();
|
||||||
|
|
||||||
/* Advance the write pointer 4096+1500 bytes to make
|
/* Advance the write pointer to make
|
||||||
room for an ID3 tag plus a VBR header */
|
room for an ID3 tag plus a VBR header */
|
||||||
mp3buf_write = 4096+1500;
|
mp3buf_write = MPEG_RESERVED_HEADER_SPACE;
|
||||||
memset(mp3buf, 0, 4096+1500);
|
memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE);
|
||||||
|
|
||||||
/* Insert the ID3 header */
|
/* Insert the ID3 header */
|
||||||
memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header));
|
memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header));
|
||||||
|
|
@ -1884,13 +1885,16 @@ static void mpeg_thread(void)
|
||||||
if(num_recorded_frames == 0x7ffff)
|
if(num_recorded_frames == 0x7ffff)
|
||||||
num_recorded_frames = 0;
|
num_recorded_frames = 0;
|
||||||
|
|
||||||
|
/* Read the first MP3 frame from the recorded stream */
|
||||||
|
lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE, SEEK_SET);
|
||||||
|
read(mpeg_file, &saved_header, 4);
|
||||||
|
|
||||||
framelen = create_xing_header(mpeg_file, 0, num_rec_bytes,
|
framelen = create_xing_header(mpeg_file, 0, num_rec_bytes,
|
||||||
mp3buf, num_recorded_frames,
|
mp3buf, num_recorded_frames,
|
||||||
rec_version_index,
|
saved_header, NULL, false);
|
||||||
rec_frequency_index,
|
|
||||||
NULL, false);
|
|
||||||
|
|
||||||
lseek(mpeg_file, 4096+1500-framelen, SEEK_SET);
|
lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen,
|
||||||
|
SEEK_SET);
|
||||||
write(mpeg_file, mp3buf, framelen);
|
write(mpeg_file, mp3buf, framelen);
|
||||||
close(mpeg_file);
|
close(mpeg_file);
|
||||||
|
|
||||||
|
|
@ -2823,7 +2827,8 @@ void mpeg_set_pitch(int pitch)
|
||||||
|
|
||||||
#ifdef HAVE_MAS3587F
|
#ifdef HAVE_MAS3587F
|
||||||
void mpeg_set_recording_options(int frequency, int quality,
|
void mpeg_set_recording_options(int frequency, int quality,
|
||||||
int source, int channel_mode)
|
int source, int channel_mode,
|
||||||
|
bool editable)
|
||||||
{
|
{
|
||||||
bool is_mpeg1;
|
bool is_mpeg1;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
|
@ -2844,6 +2849,11 @@ void mpeg_set_recording_options(int frequency, int quality,
|
||||||
|
|
||||||
DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f0, %x)\n", val);
|
DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f0, %x)\n", val);
|
||||||
|
|
||||||
|
val = editable?4:0;
|
||||||
|
mas_writemem(MAS_BANK_D0, 0x7f9, &val,1);
|
||||||
|
|
||||||
|
DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f9, %x)\n", val);
|
||||||
|
|
||||||
val = ((!is_recording << 10) | /* Monitoring */
|
val = ((!is_recording << 10) | /* Monitoring */
|
||||||
((source < 2)?1:2) << 8) | /* Input select */
|
((source < 2)?1:2) << 8) | /* Input select */
|
||||||
(1 << 5) | /* SDO strobe invert */
|
(1 << 5) | /* SDO strobe invert */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue