summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2019-08-08 16:49:16 -0400
committerSolomon Peachy <pizza@shaftnet.org>2019-08-13 17:07:07 +0200
commit22c63269749aa6471235f9547e53bc9d6f8ce41b (patch)
tree124f52e0a3341a88b44ac7bc6c4ca6731f49f1a7
parentc46147c6b2a70068e71f4baa34e4ca0892ca4f92 (diff)
downloadrockbox-22c63269749aa6471235f9547e53bc9d6f8ce41b.tar.gz
rockbox-22c63269749aa6471235f9547e53bc9d6f8ce41b.tar.bz2
rockbox-22c63269749aa6471235f9547e53bc9d6f8ce41b.zip
Improvements for vbrfix plugin:
* Properly account for ID3v1 tags * Play time computation fixes * Add speech feedback Patch by Igor Poretsky Change-Id: Ia6df8fb171882a88527cfa9d3b76b705f09becdd
-rw-r--r--apps/lang/english.lang28
-rw-r--r--apps/plugins/vbrfix.c22
-rw-r--r--lib/rbcodec/metadata/id3tags.c23
-rw-r--r--lib/rbcodec/metadata/metadata_parsers.h1
-rw-r--r--lib/rbcodec/metadata/mp3.c14
-rw-r--r--lib/rbcodec/metadata/mp3data.c26
6 files changed, 91 insertions, 23 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 23b5fa62a1..5b04b13bfa 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -16390,3 +16390,31 @@ id: VOICE_BAT_BENCH_KEYS
lcd_bitmap: "Error writing config"
</voice>
</phrase>
+<phrase>
+ id: LANG_NOT_A_VBR_FILE
+ desc: in vbrfix plugin
+ user: core
+ <source>
+ *: "Not a VBR file"
+ </source>
+ <dest>
+ *: "Not a VBR file"
+ </dest>
+ <voice>
+ *: "Not a VBR file"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FILE_ERROR
+ desc: in vbrfix plugin
+ user: core
+ <source>
+ *: "File error: %d"
+ </source>
+ <dest>
+ *: "File error: %d"
+ </dest>
+ <voice>
+ *: "File error"
+ </voice>
+</phrase>
diff --git a/apps/plugins/vbrfix.c b/apps/plugins/vbrfix.c
index af7b817002..768ec9d99f 100644
--- a/apps/plugins/vbrfix.c
+++ b/apps/plugins/vbrfix.c
@@ -26,11 +26,21 @@ static char *audiobuf;
static size_t audiobuflen;
unsigned char xingbuf[1500];
char tmpname[MAX_PATH];
+static long last_talk = 0;
static void xingupdate(int percent)
{
rb->lcd_putsf(0, 1, "%d%%", percent);
rb->lcd_update();
+ if (rb->global_settings->talk_menu)
+ {
+ long now = *(rb->current_tick) / HZ;
+ if (now - last_talk >= 5)
+ {
+ rb->talk_value(percent, UNIT_PERCENT, false);
+ last_talk = now;
+ }
+ }
}
static int insert_data_in_file(const char *fname, int fpos, char *buf, int num_bytes)
@@ -114,7 +124,7 @@ static int insert_data_in_file(const char *fname, int fpos, char *buf, int num_b
static void fileerror(int rc)
{
- rb->splashf(HZ*2, "File error: %d", rc);
+ rb->splashf(HZ*2, ID2P(LANG_FILE_ERROR), rc);
}
static const unsigned char empty_id3_header[] =
@@ -128,7 +138,6 @@ static bool vbr_fix(const char *selected_file)
struct mp3entry entry;
int fd;
int rc;
- int flen;
int num_frames;
int numbytes;
int framelen;
@@ -152,18 +161,16 @@ static bool vbr_fix(const char *selected_file)
return true;
}
- flen = rb->lseek(fd, 0, SEEK_END);
-
xingupdate(0);
num_frames = rb->count_mp3_frames(fd, entry.first_frame_offset,
- flen, xingupdate, audiobuf, audiobuflen);
+ entry.filesize, xingupdate, audiobuf, audiobuflen);
if(num_frames) {
/* Note: We don't need to pass a template header because it will be
taken from the mpeg stream */
framelen = rb->create_xing_header(fd, entry.first_frame_offset,
- flen, xingbuf, num_frames, 0,
+ entry.filesize, xingbuf, num_frames, 0,
0, xingupdate, true,
audiobuf, audiobuflen);
@@ -253,7 +260,7 @@ static bool vbr_fix(const char *selected_file)
{
/* Not a VBR file */
DEBUGF("Not a VBR file\n");
- rb->splash(HZ*2, "Not a VBR file");
+ rb->splash(HZ*2, ID2P(LANG_NOT_A_VBR_FILE));
}
return false;
@@ -261,6 +268,7 @@ static bool vbr_fix(const char *selected_file)
enum plugin_status plugin_start(const void *parameter)
{
+ last_talk = *(rb->current_tick) / HZ;
if (!parameter)
return PLUGIN_ERROR;
diff --git a/lib/rbcodec/metadata/id3tags.c b/lib/rbcodec/metadata/id3tags.c
index cda8ce3b7a..8236244d79 100644
--- a/lib/rbcodec/metadata/id3tags.c
+++ b/lib/rbcodec/metadata/id3tags.c
@@ -1135,6 +1135,29 @@ void setid3v2title(int fd, struct mp3entry *entry)
}
/*
+ * Calculates the size of the ID3v1 tag if any.
+ *
+ * Arguments: file - the file to search for a tag.
+ *
+ * Returns: the size of the tag or 0 if none was found
+ */
+int getid3v1len(int fd)
+{
+ char buf[4];
+
+ if (-1 == lseek(fd, -128, SEEK_END))
+ return 0;
+
+ if (read(fd, buf, 3) != 3)
+ return 0;
+
+ if (strncmp(buf, "TAG", 3))
+ return 0;
+
+ return 128;
+}
+
+/*
* Calculates the size of the ID3v2 tag.
*
* Arguments: file - the file to search for a tag.
diff --git a/lib/rbcodec/metadata/metadata_parsers.h b/lib/rbcodec/metadata/metadata_parsers.h
index 9f03c79bb5..45cf140012 100644
--- a/lib/rbcodec/metadata/metadata_parsers.h
+++ b/lib/rbcodec/metadata/metadata_parsers.h
@@ -22,6 +22,7 @@
#if CONFIG_CODEC == SWCODEC
char* id3_get_num_genre(unsigned int genre_num);
#endif
+int getid3v1len(int fd);
int getid3v2len(int fd);
bool setid3v1title(int fd, struct mp3entry *entry);
void setid3v2title(int fd, struct mp3entry *entry);
diff --git a/lib/rbcodec/metadata/mp3.c b/lib/rbcodec/metadata/mp3.c
index 661fea8e51..2096e70898 100644
--- a/lib/rbcodec/metadata/mp3.c
+++ b/lib/rbcodec/metadata/mp3.c
@@ -71,7 +71,9 @@ static int getsonglength(int fd, struct mp3entry *entry)
if(bytecount < 0)
return -1;
- bytecount += entry->id3v2len;
+ /* Subtract the meta information from the file size to get
+ the true size of the MP3 stream */
+ entry->filesize -= entry->id3v1len + entry->id3v2len;
/* Validate byte count, in case the file has been edited without
* updating the header.
@@ -99,6 +101,9 @@ static int getsonglength(int fd, struct mp3entry *entry)
}
}
+ entry->filesize -= bytecount;
+ bytecount += entry->id3v2len;
+
entry->bitrate = info.bitrate;
entry->frequency = info.frequency;
entry->layer = info.layer;
@@ -127,7 +132,7 @@ static int getsonglength(int fd, struct mp3entry *entry)
if (info.bitrate < 8)
filetime = 0;
else
- filetime = (entry->filesize - bytecount) / (info.bitrate / 8);
+ filetime = entry->filesize / (info.bitrate >> 3);
/* bitrate is in kbps so this delivers milliseconds. Doing bitrate / 8
* instead of filesize * 8 is exact, because mpeg audio bitrates are
* always multiples of 8, and it avoids overflows. */
@@ -163,6 +168,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry)
{
entry->title = NULL;
entry->filesize = filesize(fd);
+ entry->id3v1len = getid3v1len(fd);
entry->id3v2len = getid3v2len(fd);
entry->tracknum = 0;
entry->discnum = 0;
@@ -174,10 +180,6 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry)
return false;
entry->length = len;
- /* Subtract the meta information from the file size to get
- the true size of the MP3 stream */
- entry->filesize -= entry->first_frame_offset;
-
/* only seek to end of file if no id3v2 tags were found */
if (!entry->id3v2len) {
setid3v1title(fd, entry);
diff --git a/lib/rbcodec/metadata/mp3data.c b/lib/rbcodec/metadata/mp3data.c
index 8a134dd534..49f9786c29 100644
--- a/lib/rbcodec/metadata/mp3data.c
+++ b/lib/rbcodec/metadata/mp3data.c
@@ -39,6 +39,9 @@
#include "mp3data.h"
#include "platform.h"
+#include "metadata.h"
+#include "metadata/metadata_parsers.h"
+
//#define DEBUG_VERBOSE
#ifdef DEBUG_VERBOSE
@@ -340,7 +343,7 @@ static int buf_getbyte(int fd, unsigned char *c)
static int buf_seek(int fd, int len)
{
fnf_read_index += len;
- if(fnf_read_index > fnf_buf_len)
+ if(fnf_read_index >= fnf_buf_len)
{
len = fnf_read_index - fnf_buf_len;
@@ -348,23 +351,22 @@ static int buf_seek(int fd, int len)
if(fnf_buf_len < 0)
return -1;
- fnf_read_index = 0;
- fnf_read_index += len;
+ fnf_read_index = len;
}
- if(fnf_read_index > fnf_buf_len)
+ if(fnf_read_index >= fnf_buf_len)
{
return -1;
}
- else
- return 0;
+
+ return 0;
}
static void buf_init(unsigned char* buf, size_t buflen)
{
fnf_buf = buf;
fnf_buf_len = buflen;
- fnf_read_index = 0;
+ fnf_read_index = buflen;
}
static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset)
@@ -601,14 +603,18 @@ int get_mp3file_info(int fd, struct mp3info *info)
}
else
{
+ long offset;
+
VDEBUGF("-- No VBR header --\n");
/* There was no VBR header found. So, we seek back to beginning and
* search for the first MPEG frame header of the mp3 stream. */
- lseek(fd, -info->frame_size, SEEK_CUR);
+ offset = lseek(fd, -info->frame_size, SEEK_CUR);
result = get_next_header_info(fd, &bytecount, info, false);
if(result)
return result;
+
+ info->byte_count = filesize(fd) - getid3v1len(fd) - offset - bytecount;
}
return bytecount;
@@ -647,7 +653,7 @@ int count_mp3_frames(int fd, int startpos, int filesize,
num_frames = 0;
cnt = 0;
- while((header = buf_find_next_frame(fd, &bytes, header_template))) {
+ while((header = buf_find_next_frame(fd, &bytes, startpos + filesize))) {
mp3headerinfo(&info, header);
if(!header_template)
@@ -723,7 +729,7 @@ int create_xing_header(int fd, long startpos, long filesize,
/* Advance from the last seek point to this one */
for(j = 0;j < pos - last_pos;j++)
{
- header = buf_find_next_frame(fd, &bytes, header_template);
+ header = buf_find_next_frame(fd, &bytes, startpos + filesize);
filepos += bytes;
mp3headerinfo(&info, header);
buf_seek(fd, info.frame_size-4);