Discussion:
[PATCH 2/4] nomad: remove non-fast mode
Johannes Weißl
2011-04-12 15:23:06 UTC
Permalink
we never use it, it is far too slow!
---
mad.c | 5 ++---
nomad.c | 58 +++++++++++++++++-----------------------------------------
nomad.h | 6 +++---
3 files changed, 22 insertions(+), 47 deletions(-)

diff --git a/mad.c b/mad.c
index 51bd5f3..d2ea26f 100644
--- a/mad.c
+++ b/mad.c
@@ -69,10 +69,9 @@ static int mad_open(struct input_plugin_data *ip_data)
{
struct nomad *nomad;
struct nomad_info info;
- int rc, fast;
+ int rc;

- fast = 1;
- rc = nomad_open_callbacks(&nomad, ip_data, fast, &callbacks);
+ rc = nomad_open_callbacks(&nomad, ip_data, &callbacks);
switch (rc) {
case -NOMAD_ERROR_ERRNO:
return -1;
diff --git a/nomad.c b/nomad.c
index 593e7d1..162d514 100644
--- a/nomad.c
+++ b/nomad.c
@@ -60,7 +60,6 @@ struct nomad {
ref: http://www.mars.org/mailman/public/mad-dev/2001-May/000262.html */
unsigned char input_buffer[INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD];
int i;
- unsigned int fast : 1;
unsigned int has_xing : 1;
unsigned int has_lame : 1;
unsigned int seen_first_frame : 1;
@@ -433,16 +432,12 @@ static void calc_bitrate_fast(struct nomad *nomad)
* fields
* nomad->info.avg_bitrate and
* nomad->info.vbr
- * are only estimated if fast = 1
+ * are only estimated
*/
static int scan(struct nomad *nomad)
{
struct mad_header *header = &nomad->frame.header;
- int old_bitrate = 0;
- unsigned long long int bitrate_sum = 0;

- nomad->info.nr_frames = 0;
- nomad->info.vbr = 0;
while (1) {
int rc;

@@ -465,39 +460,24 @@ static int scan(struct nomad *nomad)
}

build_seek_index(nomad);
- bitrate_sum += header->bitrate;
- nomad->info.nr_frames++;
-
- if (nomad->info.nr_frames == 1) {
- // first valid frame
- nomad->info.sample_rate = header->samplerate;
- nomad->info.channels = MAD_NCHANNELS(header);
- nomad->info.layer = header->layer;
- nomad->info.dual_channel = header->mode == MAD_MODE_DUAL_CHANNEL;
- nomad->info.joint_stereo = header->mode == MAD_MODE_JOINT_STEREO;
-
- xing_parse(nomad);
-
- if (nomad->fast) {
- calc_frames_fast(nomad);
- break;
- }
- } else {
- if (old_bitrate != header->bitrate)
- nomad->info.vbr = 1;
- }
- old_bitrate = header->bitrate;
+
+ // first valid frame
+ nomad->info.sample_rate = header->samplerate;
+ nomad->info.channels = MAD_NCHANNELS(header);
+ nomad->info.layer = header->layer;
+ nomad->info.dual_channel = header->mode == MAD_MODE_DUAL_CHANNEL;
+ nomad->info.joint_stereo = header->mode == MAD_MODE_JOINT_STEREO;
+
+ xing_parse(nomad);
+ calc_frames_fast(nomad);
+ break;
}
if (nomad->info.nr_frames == 0) {
d_print("error: not an mp3 file!\n");
return -NOMAD_ERROR_FILE_FORMAT;
}
nomad->info.duration = timer_to_seconds(nomad->timer);
- if (!nomad->fast)
- nomad->info.avg_bitrate = bitrate_sum / nomad->info.nr_frames;
- else {
- calc_bitrate_fast(nomad);
- }
+ calc_bitrate_fast(nomad);
nomad->cur_frame = 0;
nomad->cbs.lseek(nomad->datasource, 0, SEEK_SET);
nomad->input_offset = 0;
@@ -557,18 +537,14 @@ static void free_mad(struct nomad *nomad)
mad_synth_finish(nomad->synth);
}

-static int do_open(struct nomad *nomad, int fast)
+static int do_open(struct nomad *nomad)
{
int rc;

init_mad(nomad);
nomad->info.filesize = nomad->cbs.lseek(nomad->datasource, 0, SEEK_END);
- if (nomad->info.filesize == -1) {
- nomad->fast = 1;
- } else {
- nomad->fast = fast != 0;
+ if (nomad->info.filesize != -1)
nomad->cbs.lseek(nomad->datasource, 0, SEEK_SET);
- }
if (nomad->info.filesize == -1) {
rc = decode(nomad);
if (rc < 0)
@@ -620,7 +596,7 @@ eof:
return -NOMAD_ERROR_FILE_FORMAT;
}

-int nomad_open_callbacks(struct nomad **nomadp, void *datasource, int fast, struct nomad_callbacks *cbs)
+int nomad_open_callbacks(struct nomad **nomadp, void *datasource, struct nomad_callbacks *cbs)
{
struct nomad *nomad;

@@ -630,7 +606,7 @@ int nomad_open_callbacks(struct nomad **nomadp, void *datasource, int fast, stru
nomad->lame.peak = nomad->lame.trackGain = nomad->lame.albumGain = strtof("NAN", NULL);
*nomadp = nomad;
/* on error do_open calls nomad_close */
- return do_open(nomad, fast);
+ return do_open(nomad);
}

void nomad_close(struct nomad *nomad)
diff --git a/nomad.h b/nomad.h
index 4a01c81..dcb1a89 100644
--- a/nomad.h
+++ b/nomad.h
@@ -45,9 +45,9 @@ struct nomad_info {
int channels;
int nr_frames;
int layer;
- /* -1 if fast = 1 */
+ /* guessed */
int vbr;
- /* -1 if fast = 1 */
+ /* guessed */
int avg_bitrate;
/* -1 if file not seekable */
int filesize;
@@ -64,7 +64,7 @@ enum {
struct nomad;

/* -NOMAD_ERROR_ERRNO -NOMAD_ERROR_FILE_FORMAT */
-int nomad_open_callbacks(struct nomad **nomadp, void *datasource, int fast,
+int nomad_open_callbacks(struct nomad **nomadp, void *datasource,
struct nomad_callbacks *cbs);

void nomad_close(struct nomad *nomad);
--
1.7.4.1
Johannes Weißl
2011-04-12 15:23:08 UTC
Permalink
mad.c does not need this information.
---
nomad.c | 6 ++++--
nomad.h | 5 -----
2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/nomad.c b/nomad.c
index c8cf1fd..89f6b23 100644
--- a/nomad.c
+++ b/nomad.c
@@ -40,9 +40,11 @@
#include <string.h>
#include <errno.h>

-/* the number of samples of silence the decoder inserts at start */
-#define DECODERDELAY 529
+#define INPUT_BUFFER_SIZE (5 * 8192)
+#define SEEK_IDX_INTERVAL 15

+/* the number of samples of silence the decoder inserts at start */
+#define DECODERDELAY 529

struct seek_idx_entry {
off_t offset;
diff --git a/nomad.h b/nomad.h
index 8ddabfc..52602a6 100644
--- a/nomad.h
+++ b/nomad.h
@@ -20,17 +20,12 @@
#ifndef _NOMAD_H
#define _NOMAD_H

-#include <mad.h>
#include <sys/types.h>

#ifndef __GNUC__
#include <unistd.h>
#endif

-#define INPUT_BUFFER_SIZE (5 * 8192)
-
-#define SEEK_IDX_INTERVAL 15
-
/* default callbacks use read, lseek, close */
struct nomad_callbacks {
ssize_t (*read)(void *datasource, void *buffer, size_t count);
--
1.7.4.1
Johannes Weißl
2011-04-13 20:48:09 UTC
Permalink
---
wavpack.c | 66 ++++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/wavpack.c b/wavpack.c
index 2408cc6..8df3461 100644
--- a/wavpack.c
+++ b/wavpack.c
@@ -37,20 +37,27 @@

#define WV_CHANNEL_MAX 2

+struct wavpack_file {
+ int fd;
+ off_t len;
+};
+
struct wavpack_private {
WavpackContext *wpc;
- off_t len;
int32_t samples[CHUNK_SIZE * WV_CHANNEL_MAX];
+ struct wavpack_file wv_file;
+ struct wavpack_file wvc_file;
+ unsigned int has_wvc : 1;
};

/* http://www.wavpack.com/lib_use.txt */

static int32_t read_bytes(void *data, void *ptr, int32_t count)
{
- struct input_plugin_data *ip_data = data;
+ struct wavpack_file *file = data;
int rc;

- rc = read_wrapper(ip_data, ptr, count);
+ rc = read(file->fd, ptr, count);
if (rc == -1) {
d_print("error: %s\n", strerror(errno));
return 0;
@@ -64,25 +71,23 @@ static int32_t read_bytes(void *data, void *ptr, int32_t count)

static uint32_t get_pos(void *data)
{
- struct input_plugin_data *ip_data = data;
+ struct wavpack_file *file = data;

- return lseek(ip_data->fd, 0, SEEK_CUR);
+ return lseek(file->fd, 0, SEEK_CUR);
}

static int set_pos_abs(void *data, uint32_t pos)
{
- struct input_plugin_data *ip_data = data;
+ struct wavpack_file *file = data;

- lseek(ip_data->fd, pos, SEEK_SET);
- return errno;
+ return (lseek(file->fd, pos, SEEK_SET) == -1) ? -1 : 0;
}

static int set_pos_rel(void *data, int32_t delta, int mode)
{
- struct input_plugin_data *ip_data = data;
+ struct wavpack_file *file = data;

- lseek(ip_data->fd, delta, mode);
- return errno;
+ return (lseek(file->fd, delta, mode) == -1) ? -1 : 0;
}

static int push_back_byte(void *data, int c)
@@ -94,15 +99,14 @@ static int push_back_byte(void *data, int c)

static uint32_t get_length(void *data)
{
- struct input_plugin_data *ip_data = data;
- struct wavpack_private *priv = ip_data->private;
- return priv->len;
+ struct wavpack_file *file = data;
+ return file->len;
}

static int can_seek(void *data)
{
- struct input_plugin_data *ip_data = data;
- return !ip_data->remote;
+ struct wavpack_file *file = data;
+ return file->len != (off_t) -1;
}

static int32_t write_bytes(void *data, void *ptr, int32_t count)
@@ -143,16 +147,32 @@ static int wavpack_open(struct input_plugin_data *ip_data)
struct stat st;
char msg[80];

- priv = xnew(struct wavpack_private, 1);
- priv->wpc = NULL;
- priv->len = 0;
- if (!ip_data->remote && !fstat(ip_data->fd, &st))
- priv->len = st.st_size;
+ priv = xnew0(struct wavpack_private, 1);
+ priv->wv_file.fd = ip_data->fd;
+ if (!ip_data->remote && fstat(ip_data->fd, &st) == 0) {
+ char *filename_wvc;
+
+ priv->wv_file.len = st.st_size;
+
+ filename_wvc = xnew(char, strlen(ip_data->filename) + 2);
+ sprintf(filename_wvc, "%sc", ip_data->filename);
+ if (stat(filename_wvc, &st) == 0) {
+ priv->wvc_file.fd = open(filename_wvc, O_RDONLY);
+ if (priv->wvc_file.fd != -1) {
+ priv->wvc_file.len = st.st_size;
+ priv->has_wvc = 1;
+ d_print("use correction file: %s\n", filename_wvc);
+ }
+ }
+ free(filename_wvc);
+ } else
+ priv->wv_file.len = (off_t) -1;
ip_data->private = priv;

*msg = '\0';

- priv->wpc = WavpackOpenFileInputEx(&callbacks, ip_data, NULL, msg,
+ priv->wpc = WavpackOpenFileInputEx(&callbacks, &priv->wv_file,
+ priv->has_wvc ? &priv->wvc_file : NULL, msg,
OPEN_2CH_MAX | OPEN_NORMALIZE, 0);

if (!priv->wpc) {
@@ -174,6 +194,8 @@ static int wavpack_close(struct input_plugin_data *ip_data)

priv = ip_data->private;
priv->wpc = WavpackCloseFile(priv->wpc);
+ if (priv->has_wvc)
+ close(priv->wvc_file.fd);
free(priv);
ip_data->private = NULL;
return 0;
--
1.7.4.1
Johannes Weißl
2011-04-13 20:48:10 UTC
Permalink
Otherwise WavpackGetMode() doesn't work (needed in next commit).
---
wavpack.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/wavpack.c b/wavpack.c
index 8df3461..b5631a1 100644
--- a/wavpack.c
+++ b/wavpack.c
@@ -40,6 +40,7 @@
struct wavpack_file {
int fd;
off_t len;
+ int push_back_byte;
};

struct wavpack_private {
@@ -55,7 +56,16 @@ struct wavpack_private {
static int32_t read_bytes(void *data, void *ptr, int32_t count)
{
struct wavpack_file *file = data;
- int rc;
+ int32_t rc, n = 0;
+
+ if (file->push_back_byte != EOF) {
+ char *p = ptr;
+ *p = (char) file->push_back_byte;
+ ptr = p + 1;
+ file->push_back_byte = EOF;
+ count--;
+ n++;
+ }

rc = read(file->fd, ptr, count);
if (rc == -1) {
@@ -66,7 +76,7 @@ static int32_t read_bytes(void *data, void *ptr, int32_t count)
errno = 0;
return 0;
}
- return rc;
+ return rc + n;
}

static uint32_t get_pos(void *data)
@@ -92,9 +102,14 @@ static int set_pos_rel(void *data, int32_t delta, int mode)

static int push_back_byte(void *data, int c)
{
- /* not possible? */
- d_print("NOT POSSIBLE\n");
- return EOF;
+ struct wavpack_file *file = data;
+
+ if (file->push_back_byte != EOF) {
+ d_print("error: only one byte push back possible!\n");
+ return EOF;
+ }
+ file->push_back_byte = c;
+ return c;
}

static uint32_t get_length(void *data)
@@ -149,6 +164,7 @@ static int wavpack_open(struct input_plugin_data *ip_data)

priv = xnew0(struct wavpack_private, 1);
priv->wv_file.fd = ip_data->fd;
+ priv->wv_file.push_back_byte = EOF;
if (!ip_data->remote && fstat(ip_data->fd, &st) == 0) {
char *filename_wvc;

@@ -160,6 +176,7 @@ static int wavpack_open(struct input_plugin_data *ip_data)
priv->wvc_file.fd = open(filename_wvc, O_RDONLY);
if (priv->wvc_file.fd != -1) {
priv->wvc_file.len = st.st_size;
+ priv->wvc_file.push_back_byte = EOF;
priv->has_wvc = 1;
d_print("use correction file: %s\n", filename_wvc);
}
--
1.7.4.1
Johannes Weißl
2011-04-13 20:48:11 UTC
Permalink
More details about the profile (main type of encoder settings).
---
Doc/cmus.txt | 8 +++++---
aac.c | 32 +++++++++++++++++++++++++++++++-
cache.c | 16 +++++++++++-----
expr.c | 3 +++
ffmpeg.c | 30 +++++++++++++++++++++++++++++-
flac.c | 9 ++++++++-
input.c | 12 ++++++++++++
input.h | 1 +
ip.h | 1 +
mad.c | 34 ++++++++++++++++++++++++++++++++--
mikmod.c | 8 +++++++-
modplug.c | 8 +++++++-
mp4.c | 31 ++++++++++++++++++++++++++++++-
mpc.c | 23 ++++++++++++++++++++++-
nomad.c | 40 +++++++++++++++++++++-------------------
nomad.h | 18 ++++++++++++++++++
options.c | 1 +
track_info.c | 2 ++
track_info.h | 2 ++
ui_curses.c | 3 +++
vorbis.c | 39 ++++++++++++++++++++++++++++++++++++++-
wav.c | 8 +++++++-
wavpack.c | 32 +++++++++++++++++++++++++++++++-
23 files changed, 322 insertions(+), 39 deletions(-)

diff --git a/Doc/cmus.txt b/Doc/cmus.txt
index 4ec3c07..af66b2c 100644
--- a/Doc/cmus.txt
+++ b/Doc/cmus.txt
@@ -957,6 +957,7 @@ Special Keys:
%F %{filename} @br
%{bitrate} @br
%{codec} @br
+ %{codec_profile} @br
%{rg_track_gain} @br
%{rg_track_peak} @br
%{rg_album_gain} @br
@@ -986,8 +987,8 @@ Sort option (lib_sort, pl_sort) value is space separated list of the following
sort keys:

artist, album, title, tracknumber, discnumber, date, genre, comment,
- albumartist, filename, filemtime, bitrate, codec, rg_track_gain,
- rg_track_peak, rg_album_gain, rg_album_peak
+ albumartist, filename, filemtime, bitrate, codec, codec_profile,
+ rg_track_gain, rg_track_peak, rg_album_gain, rg_album_peak


@h1 PLUGIN OPTIONS
@@ -1092,7 +1093,8 @@ built-in filters. Also (and)-grouping is done implicitly.
@h2 Strings

@li long
-*filename*, *artist*, *album*, *title*, *genre*, *comment*, *codec*
+*filename*, *artist*, *album*, *title*, *genre*, *comment*, *codec*,
+*codec_profile*
@br
Comparators: *=* and *!=* (not equal)

diff --git a/aac.c b/aac.c
index ef991c9..3153fae 100644
--- a/aac.c
+++ b/aac.c
@@ -26,6 +26,7 @@

#include <neaacdec.h>

+#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
@@ -43,6 +44,7 @@ struct aac_private {
unsigned char channels;
unsigned long sample_rate;
long bitrate;
+ int object_type;

char *overflow_buf;
int overflow_buf_len;
@@ -195,6 +197,7 @@ static int aac_open(struct input_plugin_data *ip_data)
priv = xnew0(struct aac_private, 1);
priv->decoder = NeAACDecOpen();
priv->bitrate = -1;
+ priv->object_type = -1;
ip_data->private = priv;

/* set decoder config */
@@ -429,6 +432,8 @@ static int aac_duration(struct input_plugin_data *ip_data)
/* 8 * file_size / duration */
priv->bitrate = (8 * bytes * priv->sample_rate) / samples;

+ priv->object_type = frame_info.object_type;
+
return ((file_size / bytes) * samples) / priv->sample_rate;
}

@@ -443,6 +448,30 @@ static char *aac_codec(struct input_plugin_data *ip_data)
return xstrdup("aac");
}

+static const char *object_type_to_str(int object_type)
+{
+ switch (object_type) {
+ case MAIN: return "Main";
+ case LC: return "LC";
+ case SSR: return "SSR";
+ case LTP: return "LTP";
+ case HE_AAC: return "HE";
+ case ER_LC: return "ER-LD";
+ case ER_LTP: return "ER-LTP";
+ case LD: return "LD";
+ case DRM_ER_LC: return "DRM-ER-LC";
+ }
+ return NULL;
+}
+
+static char *aac_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct aac_private *priv = ip_data->private;
+ const char *profile = object_type_to_str(priv->object_type);
+
+ return profile ? xstrdup(profile) : NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = aac_open,
.close = aac_close,
@@ -451,7 +480,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = aac_read_comments,
.duration = aac_duration,
.bitrate = aac_bitrate,
- .codec = aac_codec
+ .codec = aac_codec,
+ .codec_profile = aac_codec_profile
};

const int ip_priority = 50;
diff --git a/cache.c b/cache.c
index 48f91c8..710122c 100644
--- a/cache.c
+++ b/cache.c
@@ -32,7 +32,7 @@ struct cache_entry {
long bitrate;
time_t mtime;

- // filename, codec and N * (key, val)
+ // filename, codec, codec_profile and N * (key, val)
char strings[];
};

@@ -85,7 +85,7 @@ static int valid_cache_entry(const struct cache_entry *e, unsigned int avail)
if (!e->strings[i])
count++;
}
- if (count % 2 == 1)
+ if (count % 2 == 0)
return 0;
if (e->strings[str_size - 1])
return 0;
@@ -104,18 +104,20 @@ static struct track_info *cache_entry_to_ti(struct cache_entry *e)
ti->bitrate = e->bitrate;
ti->mtime = e->mtime;

- // count strings (filename + codec + key/val pairs)
+ // count strings (filename + codec + codec_profile + key/val pairs)
count = 0;
for (i = 0; i < str_size; i++) {
if (!strings[i])
count++;
}
- count = (count - 2) / 2;
+ count = (count - 3) / 2;

// NOTE: filename already copied by track_info_new()
pos = strlen(strings) + 1;
ti->codec = strings[pos] ? xstrdup(strings + pos) : NULL;
pos += strlen(strings + pos) + 1;
+ ti->codec_profile = strings[pos] ? xstrdup(strings + pos) : NULL;
+ pos += strlen(strings + pos) + 1;
kv = xnew(struct keyval, count + 1);
for (i = 0; i < count; i++) {
int size;
@@ -241,7 +243,7 @@ int cache_init(void)
cache_header[4] = flags & 0xff;

/* assumed version */
- cache_header[3] = 0x05;
+ cache_header[3] = 0x06;

cache_filename = xstrjoin(cmus_config_dir, "/cache");
return read_cache();
@@ -300,6 +302,8 @@ static void write_ti(int fd, struct gbuf *buf, struct track_info *ti, unsigned i
e.size += len[count++];
len[count] = (ti->codec ? strlen(ti->codec) : 0) + 1;
e.size += len[count++];
+ len[count] = (ti->codec_profile ? strlen(ti->codec_profile) : 0) + 1;
+ e.size += len[count++];
for (i = 0; kv[i].key; i++) {
if (count + 2 > alloc) {
alloc *= 2;
@@ -321,6 +325,7 @@ static void write_ti(int fd, struct gbuf *buf, struct track_info *ti, unsigned i
gbuf_add_bytes(buf, &e, sizeof(e));
gbuf_add_bytes(buf, ti->filename, len[count++]);
gbuf_add_bytes(buf, ti->codec ? ti->codec : "", len[count++]);
+ gbuf_add_bytes(buf, ti->codec_profile ? ti->codec_profile : "", len[count++]);
for (i = 0; kv[i].key; i++) {
gbuf_add_bytes(buf, kv[i].key, len[count++]);
gbuf_add_bytes(buf, kv[i].val, len[count++]);
@@ -383,6 +388,7 @@ static struct track_info *ip_get_ti(const char *filename)
ti->duration = ip_duration(ip);
ti->bitrate = ip_bitrate(ip);
ti->codec = ip_codec(ip);
+ ti->codec_profile = ip_codec_profile(ip);
ti->mtime = ip_is_remote(ip) ? -1 : file_get_mtime(filename);
}
ip_delete(ip);
diff --git a/expr.c b/expr.c
index 559b1ab..95e5111 100644
--- a/expr.c
+++ b/expr.c
@@ -411,6 +411,7 @@ static const struct {
{ "artist", EXPR_STR },
{ "bitrate", EXPR_INT },
{ "codec", EXPR_STR },
+ { "codec_profile",EXPR_STR },
{ "comment", EXPR_STR },
{ "date", EXPR_INT },
{ "discnumber", EXPR_INT },
@@ -877,6 +878,8 @@ int expr_eval(struct expr *expr, struct track_info *ti)
val = uval;
} else if (strcmp(key, "codec") == 0) {
val = ti->codec;
+ } else if (strcmp(key, "codec_profile") == 0) {
+ val = ti->codec_profile;
} else {
val = keyvals_get_val(ti->comments, key);
}
diff --git a/ffmpeg.c b/ffmpeg.c
index b5b9932..4b45364 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -457,6 +457,33 @@ static char *ffmpeg_codec(struct input_plugin_data *ip_data)
return xstrdup(priv->codec->name);
}

+#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(104<<8)+0))
+static const char *codec_profile_to_str(int profile)
+{
+ switch (profile) {
+ case FF_PROFILE_AAC_MAIN: return "Main";
+ case FF_PROFILE_AAC_LOW: return "LC";
+ case FF_PROFILE_AAC_SSR: return "SSR";
+ case FF_PROFILE_AAC_LTP: return "LTP";
+ }
+ return NULL;
+}
+#endif
+
+static char *ffmpeg_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct ffmpeg_private *priv = ip_data->private;
+ const char *profile;
+
+#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(104<<8)+0))
+ profile = codec_profile_to_str(priv->codec_context->profile);
+#else
+ profile = av_get_profile_name(priv->codec, priv->codec_context->profile);
+#endif
+
+ return profile ? xstrdup(profile) : NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = ffmpeg_open,
.close = ffmpeg_close,
@@ -465,7 +492,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = ffmpeg_read_comments,
.duration = ffmpeg_duration,
.bitrate = ffmpeg_bitrate,
- .codec = ffmpeg_codec
+ .codec = ffmpeg_codec,
+ .codec_profile = ffmpeg_codec_profile
};

const int ip_priority = 30;
diff --git a/flac.c b/flac.c
index 41cae40..6e3a2a4 100644
--- a/flac.c
+++ b/flac.c
@@ -532,6 +532,12 @@ static char *flac_codec(struct input_plugin_data *ip_data)
return xstrdup("flac");
}

+static char *flac_codec_profile(struct input_plugin_data *ip_data)
+{
+ /* maybe identify compression-level over min/max blocksize/framesize */
+ return NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = flac_open,
.close = flac_close,
@@ -540,7 +546,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = flac_read_comments,
.duration = flac_duration,
.bitrate = flac_bitrate,
- .codec = flac_codec
+ .codec = flac_codec,
+ .codec_profile = flac_codec_profile
};

const int ip_priority = 50;
diff --git a/input.c b/input.c
index 223a5ee..651ca7a 100644
--- a/input.c
+++ b/input.c
@@ -60,6 +60,8 @@ struct input_plugin {
long bitrate;
/* cached codec, NULL = unset */
char *codec;
+ /* cached codec_profile, NULL = unset */
+ char *codec_profile;

/*
* pcm is converted to 16-bit signed little-endian stereo
@@ -383,6 +385,7 @@ static void ip_init(struct input_plugin *ip, char *filename)
ip->duration = -1;
ip->bitrate = -1;
ip->codec = NULL;
+ ip->codec_profile = NULL;
ip->data.fd = -1;
ip->data.filename = filename;
ip->data.remote = is_url(filename);
@@ -723,6 +726,15 @@ char *ip_codec(struct input_plugin *ip)
return ip->codec;
}

+char *ip_codec_profile(struct input_plugin *ip)
+{
+ if (ip->data.remote)
+ return NULL;
+ if (!ip->codec_profile)
+ ip->codec_profile = ip->ops->codec_profile(&ip->data);
+ return ip->codec_profile;
+}
+
sample_format_t ip_get_sf(struct input_plugin *ip)
{
BUG_ON(!ip->open);
diff --git a/input.h b/input.h
index 1f08f84..489456a 100644
--- a/input.h
+++ b/input.h
@@ -53,6 +53,7 @@ int ip_read_comments(struct input_plugin *ip, struct keyval **comments);
int ip_duration(struct input_plugin *ip);
int ip_bitrate(struct input_plugin *ip);
char *ip_codec(struct input_plugin *ip);
+char *ip_codec_profile(struct input_plugin *ip);

sample_format_t ip_get_sf(struct input_plugin *ip);
const char *ip_get_filename(struct input_plugin *ip);
diff --git a/ip.h b/ip.h
index acaa8b9..c0409b4 100644
--- a/ip.h
+++ b/ip.h
@@ -86,6 +86,7 @@ struct input_plugin_ops {
int (*duration)(struct input_plugin_data *ip_data);
long (*bitrate)(struct input_plugin_data *ip_data);
char *(*codec)(struct input_plugin_data *ip_data);
+ char *(*codec_profile)(struct input_plugin_data *ip_data);
};

/* symbols exported by plugin */
diff --git a/mad.c b/mad.c
index 4ec6891..779af11 100644
--- a/mad.c
+++ b/mad.c
@@ -24,6 +24,7 @@
#include "xmalloc.h"
#include "read_wrapper.h"
#include "debug.h"
+#include "utils.h"

#include <stdio.h>
#include <math.h>
@@ -172,7 +173,7 @@ out:
ape_free(&ape);

/* add last so the other tags get preference */
- if (!isnan(lame->trackGain)) {
+ if (lame && !isnan(lame->trackGain)) {
char buf[64];

if (!isnan(lame->peak)) {
@@ -218,6 +219,34 @@ static char *mad_codec(struct input_plugin_data *ip_data)
return NULL;
}

+static char *mad_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct nomad *nomad = ip_data->private;
+ const struct nomad_lame *lame = nomad_lame(nomad);
+ const struct nomad_xing *xing = nomad_xing(nomad);
+ const char *mode = nomad_info(nomad)->vbr ? "vbr" : "cbr";
+
+ if (xing && lame) {
+ const char const * vbr_map[] = { NULL, "cbr", "abr", "vbr-old", "vbr", "vbr-mt" };
+
+ if (lame->vbr_method && lame->vbr_method < N_ELEMENTS(vbr_map)) {
+ mode = vbr_map[lame->vbr_method];
+
+ if (xing->flags & XING_SCALE && xing->scale && xing->scale <= 100) {
+ char buf[32];
+ int v = 10 - (xing->scale + 9) / 10;
+ int q = 10 - (xing->scale - ((9 - v) * 10));
+
+ sprintf(buf, "%s V%d q%d", mode, v, q);
+ return xstrdup(buf);
+
+ }
+ }
+ }
+
+ return xstrdup(mode);
+}
+
const struct input_plugin_ops ip_ops = {
.open = mad_open,
.close = mad_close,
@@ -226,7 +255,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = mad_read_comments,
.duration = mad_duration,
.bitrate = mad_bitrate,
- .codec = mad_codec
+ .codec = mad_codec,
+ .codec_profile = mad_codec_profile
};

const int ip_priority = 55;
diff --git a/mikmod.c b/mikmod.c
index 658b259..2021f61 100644
--- a/mikmod.c
+++ b/mikmod.c
@@ -149,6 +149,11 @@ static char *mik_codec(struct input_plugin_data *ip_data)
return (codec && codec[0]) ? xstrdup(codec) : NULL;
}

+static char *mik_codec_profile(struct input_plugin_data *ip_data)
+{
+ return NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = mik_open,
.close = mik_close,
@@ -157,7 +162,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = mik_read_comments,
.duration = mik_duration,
.bitrate = mik_bitrate,
- .codec = mik_codec
+ .codec = mik_codec,
+ .codec_profile = mik_codec_profile
};

const int ip_priority = 40;
diff --git a/modplug.c b/modplug.c
index b1df3aa..981f5b3 100644
--- a/modplug.c
+++ b/modplug.c
@@ -201,6 +201,11 @@ static char *mod_codec(struct input_plugin_data *ip_data)
return codec ? xstrdup(codec) : NULL;
}

+static char *mod_codec_profile(struct input_plugin_data *ip_data)
+{
+ return NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = mod_open,
.close = mod_close,
@@ -209,7 +214,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = mod_read_comments,
.duration = mod_duration,
.bitrate = mod_bitrate,
- .codec = mod_codec
+ .codec = mod_codec,
+ .codec_profile = mod_codec_profile
};

const int ip_priority = 50;
diff --git a/mp4.c b/mp4.c
index 5149358..ac4fdfb 100644
--- a/mp4.c
+++ b/mp4.c
@@ -474,6 +474,34 @@ static char *mp4_codec(struct input_plugin_data *ip_data)
return xstrdup("aac");
}

+static const char *object_type_to_str(uint8_t obj_type)
+{
+ switch (obj_type) {
+ case MP4_MPEG4_AAC_MAIN_AUDIO_TYPE: return "Main";
+ case MP4_MPEG4_AAC_LC_AUDIO_TYPE: return "LC";
+ case MP4_MPEG4_AAC_SSR_AUDIO_TYPE: return "SSR";
+ case MP4_MPEG4_AAC_LTP_AUDIO_TYPE: return "LTP";
+ case MP4_MPEG4_AAC_HE_AUDIO_TYPE: return "HE";
+ case MP4_MPEG4_AAC_SCALABLE_AUDIO_TYPE: return "Scalable";
+ }
+ return NULL;
+}
+
+static char *mp4_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct mp4_private *priv = ip_data->private;
+ const char *profile;
+ uint8_t obj_type;
+
+ obj_type = MP4GetTrackEsdsObjectTypeId(priv->mp4.handle, priv->mp4.track);
+ if (obj_type == MP4_MPEG4_AUDIO_TYPE)
+ obj_type = MP4GetTrackAudioMpeg4Type(priv->mp4.handle, priv->mp4.track);
+
+ profile = object_type_to_str(obj_type);
+
+ return profile ? xstrdup(profile) : NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = mp4_open,
.close = mp4_close,
@@ -482,7 +510,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = mp4_read_comments,
.duration = mp4_duration,
.bitrate = mp4_bitrate,
- .codec = mp4_codec
+ .codec = mp4_codec,
+ .codec_profile = mp4_codec_profile
};

const int ip_priority = 50;
diff --git a/mpc.c b/mpc.c
index 05990e4..6006499 100644
--- a/mpc.c
+++ b/mpc.c
@@ -378,6 +378,26 @@ static char *mpc_codec(struct input_plugin_data *ip_data)
return NULL;
}

+static char *mpc_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct mpc_private *priv = ip_data->private;
+ const char *profile = priv->info.profile_name;
+ char *s = NULL;
+
+ if (profile && profile[0]) {
+ int i;
+
+ /* remove single quotes */
+ while (*profile == '\'')
+ profile++;
+ s = xstrdup(profile);
+ for (i = strlen(s) - 1; s[i] == '\'' && i >= 0; i--)
+ s[i] = '\0';
+ }
+
+ return s;
+}
+
const struct input_plugin_ops ip_ops = {
.open = mpc_open,
.close = mpc_close,
@@ -386,7 +406,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = mpc_read_comments,
.duration = mpc_duration,
.bitrate = mpc_bitrate,
- .codec = mpc_codec
+ .codec = mpc_codec,
+ .codec_profile = mpc_codec_profile
};

const int ip_priority = 50;
diff --git a/nomad.c b/nomad.c
index 89f6b23..ce9ddd3 100644
--- a/nomad.c
+++ b/nomad.c
@@ -71,15 +71,7 @@ struct nomad {
int end_drop_samples;
int end_drop_frames;

- struct {
- unsigned int is_info : 1;
- unsigned int flags;
- unsigned int nr_frames;
- unsigned int bytes;
- unsigned int scale;
- unsigned char toc[100];
- } xing;
-
+ struct nomad_xing xing;
struct nomad_lame lame;

struct {
@@ -137,9 +129,16 @@ static int parse_lame(struct nomad *nomad, struct mad_bitptr ptr, int bitlen)
d_print("detected LAME version %s\n", nomad->lame.encoder + 4);
#endif

+ i = mad_bit_read(&ptr, 4);
+#if defined(DEBUG_LAME)
+ d_print("LAME tag revision: %d\n", i);
+#endif
+ nomad->lame.vbr_method = mad_bit_read(&ptr, 4);
+
/* ReplayGain in LAME tag was added in 3.94 */
if (version_major > 3 || (version_major == 3 && version_minor >= 94)) {
- mad_bit_read(&ptr, 16);
+ /* lowpass */
+ mad_bit_read(&ptr, 8);

/* The reference volume was changed from the 83dB used in the
* ReplayGain spec to 89dB in lame 3.95.1. Bump the gain for older
@@ -168,9 +167,14 @@ static int parse_lame(struct nomad *nomad, struct mad_bitptr ptr, int bitlen)
*/
}

+ /*
+ * 4 encoding flags
+ * 4 ATH type
+ * 8 minimal bitrate (if ABR -> specified bitrate)
+ */
mad_bit_read(&ptr, 16);
} else
- mad_bit_read(&ptr, 96);
+ mad_bit_read(&ptr, 88);

nomad->lame.encoderDelay = mad_bit_read(&ptr, 12);
nomad->lame.encoderPadding = mad_bit_read(&ptr, 12);
@@ -199,13 +203,6 @@ static int parse_lame(struct nomad *nomad, struct mad_bitptr ptr, int bitlen)
return 1;
}

-enum {
- XING_FRAMES = 0x00000001L,
- XING_BYTES = 0x00000002L,
- XING_TOC = 0x00000004L,
- XING_SCALE = 0x00000008L
-};
-
/*
* format:
*
@@ -831,9 +828,14 @@ int nomad_time_seek(struct nomad *nomad, double pos)
return 0;
}

+const struct nomad_xing *nomad_xing(struct nomad *nomad)
+{
+ return nomad->has_xing ? &nomad->xing : NULL;
+}
+
const struct nomad_lame *nomad_lame(struct nomad *nomad)
{
- return &nomad->lame;
+ return nomad->has_lame ? &nomad->lame : NULL;
}

const struct nomad_info *nomad_info(struct nomad *nomad)
diff --git a/nomad.h b/nomad.h
index 52602a6..403a8a1 100644
--- a/nomad.h
+++ b/nomad.h
@@ -33,8 +33,25 @@ struct nomad_callbacks {
int (*close)(void *datasource);
};

+enum {
+ XING_FRAMES = 0x00000001L,
+ XING_BYTES = 0x00000002L,
+ XING_TOC = 0x00000004L,
+ XING_SCALE = 0x00000008L
+};
+
+struct nomad_xing {
+ unsigned int is_info : 1;
+ unsigned int flags;
+ unsigned int nr_frames;
+ unsigned int bytes;
+ unsigned int scale;
+ unsigned char toc[100];
+};
+
struct nomad_lame {
char encoder[10]; /* 9 byte encoder name/version ("LAME3.97b") */
+ int vbr_method; /* VBR method */
float peak; /* replaygain peak */
float trackGain; /* replaygain track gain */
float albumGain; /* replaygain album gain */
@@ -79,6 +96,7 @@ int nomad_read(struct nomad *nomad, char *buffer, int count);
/* -NOMAD_ERROR_ERRNO */
int nomad_time_seek(struct nomad *nomad, double pos);

+const struct nomad_xing *nomad_xing(struct nomad *nomad);
const struct nomad_lame *nomad_lame(struct nomad *nomad);
const struct nomad_info *nomad_info(struct nomad *nomad);

diff --git a/options.c b/options.c
index df81d9e..5c37bbd 100644
--- a/options.c
+++ b/options.c
@@ -210,6 +210,7 @@ static const struct {
{ "rg_album_peak", SORT_RG_ALBUM_PEAK },
{ "bitrate", SORT_BITRATE },
{ "codec", SORT_CODEC },
+ { "codec_profile", SORT_CODEC_PROFILE },
{ NULL, SORT_INVALID }
};

diff --git a/track_info.c b/track_info.c
index 0859c24..2e5c258 100644
--- a/track_info.c
+++ b/track_info.c
@@ -34,6 +34,7 @@ static void track_info_free(struct track_info *ti)
keyvals_free(ti->comments);
free(ti->filename);
free(ti->codec);
+ free(ti->codec_profile);
free(ti->collkey_artist);
free(ti->collkey_album);
free(ti->collkey_title);
@@ -51,6 +52,7 @@ struct track_info *track_info_new(const char *filename)
ti->ref = 1;
ti->comments = NULL;
ti->codec = NULL;
+ ti->codec_profile = NULL;
return ti;
}

diff --git a/track_info.h b/track_info.h
index 15a3db7..831ae3a 100644
--- a/track_info.h
+++ b/track_info.h
@@ -33,6 +33,7 @@ struct track_info {
int duration;
long bitrate;
char *codec;
+ char *codec_profile;
int ref;
char *filename;

@@ -80,6 +81,7 @@ typedef size_t sort_key_t;
#define SORT_FILEMTIME offsetof(struct track_info, mtime)
#define SORT_BITRATE offsetof(struct track_info, bitrate)
#define SORT_CODEC offsetof(struct track_info, codec)
+#define SORT_CODEC_PROFILE offsetof(struct track_info, codec_profile)
#define SORT_INVALID ((sort_key_t) (-1))

#define TI_MATCH_ARTIST (1 << 0)
diff --git a/ui_curses.c b/ui_curses.c
index 60f33bc..5a3bf07 100644
--- a/ui_curses.c
+++ b/ui_curses.c
@@ -222,6 +222,7 @@ enum {
TF_DURATION,
TF_BITRATE,
TF_CODEC,
+ TF_CODEC_PROFILE,
TF_PATHFILE,
TF_FILE,
TF_RG_TRACK_GAIN,
@@ -244,6 +245,7 @@ static struct format_option track_fopts[NR_TFS + 1] = {
DEF_FO_TIME('d', "duration", 0),
DEF_FO_INT('\0', "bitrate", 0),
DEF_FO_STR('\0', "codec", 0),
+ DEF_FO_STR('\0', "codec_profile", 0),
DEF_FO_STR('f', "path", 0),
DEF_FO_STR('F', "filename", 0),
DEF_FO_DOUBLE('\0', "rg_track_gain", 0),
@@ -558,6 +560,7 @@ static void fill_track_fopts_track_info(struct track_info *info)
fopt_set_double(&track_fopts[TF_RG_ALBUM_PEAK], info->rg_album_peak, isnan(info->rg_album_peak));
fopt_set_int(&track_fopts[TF_BITRATE], (int) (info->bitrate / 1000. + 0.5), info->bitrate == -1);
fopt_set_str(&track_fopts[TF_CODEC], info->codec);
+ fopt_set_str(&track_fopts[TF_CODEC_PROFILE], info->codec_profile);
fopt_set_str(&track_fopts[TF_PATHFILE], filename);
if (is_url(info->filename)) {
fopt_set_str(&track_fopts[TF_FILE], filename);
diff --git a/vorbis.c b/vorbis.c
index 87dded6..dda41ae 100644
--- a/vorbis.c
+++ b/vorbis.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
+#include <math.h>

struct vorbis_private {
OggVorbis_File vf;
@@ -305,6 +306,41 @@ static char *vorbis_codec(struct input_plugin_data *ip_data)
return xstrdup("vorbis");
}

+static const long rate_mapping_44[2][12] = {
+ { 32000, 48000, 60000, 70000, 80000, 86000, 96000, 110000, 120000, 140000, 160000, 239920 },
+ { 45000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 499821 }
+};
+
+static char *vorbis_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct vorbis_private *priv = ip_data->private;
+ vorbis_info *vi = ov_info(&priv->vf, -1);
+ long b = vi->bitrate_nominal;
+ char buf[64];
+
+ if (b <= 0)
+ return NULL;
+
+ if (vi->channels > 2 || vi->rate < 44100) {
+ sprintf(buf, "b%ldk", b / 1000);
+ } else {
+ const long *map = rate_mapping_44[vi->channels - 1];
+ float q;
+ int i;
+
+ for (i = 0; i < 12-1; i++) {
+ if (b >= map[i] && b < map[i+1])
+ break;
+ }
+ /* This is used even if upper / lower bitrate are set
+ * because it gives a good approximation. */
+ q = (i - 1) + (float) (b - map[i]) / (map[i+1] - map[i]);
+ sprintf(buf, "q%g", roundf(q * 100.f) / 100.f);
+ }
+
+ return xstrdup(buf);
+}
+
const struct input_plugin_ops ip_ops = {
.open = vorbis_open,
.close = vorbis_close,
@@ -313,7 +349,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = vorbis_read_comments,
.duration = vorbis_duration,
.bitrate = vorbis_bitrate,
- .codec = vorbis_codec
+ .codec = vorbis_codec,
+ .codec_profile = vorbis_codec_profile
};

const int ip_priority = 50;
diff --git a/wav.c b/wav.c
index b20c9c6..18f064c 100644
--- a/wav.c
+++ b/wav.c
@@ -390,6 +390,11 @@ static char *wav_codec(struct input_plugin_data *ip_data)
return xstrdup(buf);
}

+static char *wav_codec_profile(struct input_plugin_data *ip_data)
+{
+ return NULL;
+}
+
const struct input_plugin_ops ip_ops = {
.open = wav_open,
.close = wav_close,
@@ -398,7 +403,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = wav_read_comments,
.duration = wav_duration,
.bitrate = wav_bitrate,
- .codec = wav_codec
+ .codec = wav_codec,
+ .codec_profile = wav_codec_profile
};

const int ip_priority = 50;
diff --git a/wavpack.c b/wavpack.c
index b5631a1..99a26c5 100644
--- a/wavpack.c
+++ b/wavpack.c
@@ -362,6 +362,35 @@ static char *wavpack_codec(struct input_plugin_data *ip_data)
return xstrdup("wavpack");
}

+static char *wavpack_codec_profile(struct input_plugin_data *ip_data)
+{
+ struct wavpack_private *priv = ip_data->private;
+ int m = WavpackGetMode(priv->wpc);
+ char buf[32];
+
+ buf[0] = '\0';
+
+ if (m & MODE_FAST)
+ strcat(buf, "fast");
+ else if (m & MODE_VERY_HIGH)
+ strcat(buf, "very high");
+ else if (m & MODE_HIGH)
+ strcat(buf, "high");
+ else
+ strcat(buf, "normal");
+
+ if (m & MODE_HYBRID)
+ strcat(buf, " hybrid");
+
+ if ((m & MODE_EXTRA) && (m & MODE_XMODE)) {
+ char xmode[] = " x0";
+ xmode[2] = ((m & MODE_XMODE) >> 12) + '0';
+ strcat(buf, xmode);
+ }
+
+ return xstrdup(buf);
+}
+
const struct input_plugin_ops ip_ops = {
.open = wavpack_open,
.close = wavpack_close,
@@ -370,7 +399,8 @@ const struct input_plugin_ops ip_ops = {
.read_comments = wavpack_read_comments,
.duration = wavpack_duration,
.bitrate = wavpack_bitrate,
- .codec = wavpack_codec
+ .codec = wavpack_codec,
+ .codec_profile = wavpack_codec_profile
};

const int ip_priority = 50;
--
1.7.4.1
Johannes Weißl
2011-04-13 21:28:04 UTC
Permalink
Hello,

the %{codec_profile} patch is not fixed yet, please test and tell if you
have suggestions for the generated string (it is in the "next" branch)!
Examples:

ogg: q3
q3.18
q-1
q10
b72k --> maybe change this to 72kbps ?
...
mp3: cbr
vbr
cbr V7 q3 --> should -q X be dropped?
vbr V5 q0
abr V2 q3
vbr-old V0 q3 --> is the vbr-old useful?
...
wv : normal
high
very high
normal hybrid x3
normal x2
...
mpc: Standard
Thumb
Radio
Extreme
Insane
BrainDead
...
aac: LC
Main
LTP
...

What do you think?


Johannes
Gregory Petrosyan
2011-04-16 12:23:54 UTC
Permalink
Post by Johannes Weißl
Hello,
the %{codec_profile} patch is not fixed yet, please test and tell if you
have suggestions for the generated string (it is in the "next" branch)!
Thanks for all the patches, they are in -pu now as well!
Post by Johannes Weißl
ogg: q3
q3.18
q-1
q10
b72k --> maybe change this to 72kbps ?
...
mp3: cbr
vbr
cbr V7 q3 --> should -q X be dropped?
vbr V5 q0
abr V2 q3
vbr-old V0 q3 --> is the vbr-old useful?
...
wv : normal
high
very high
normal hybrid x3
normal x2
...
mpc: Standard
Thumb
Radio
Extreme
Insane
BrainDead
...
aac: LC
Main
LTP
...
What do you think?
IMHO the simpler (and shorter) these strings are, the better. These ones look
good to me (maybe it is better to drop vbr-old and -q X, indeed). Other than
that, I have no comments.

Gregory
Johannes Weißl
2011-04-20 01:15:39 UTC
Permalink
Post by Gregory Petrosyan
Post by Johannes Weißl
ogg: q3
q3.18
q-1
q10
b72k --> maybe change this to 72kbps ?
...
mp3: cbr
vbr
cbr V7 q3 --> should -q X be dropped?
vbr V5 q0
abr V2 q3
vbr-old V0 q3 --> is the vbr-old useful?
...
wv : normal
high
very high
normal hybrid x3
normal x2
...
mpc: Standard
Thumb
Radio
Extreme
Insane
BrainDead
...
aac: LC
Main
LTP
...
What do you think?
IMHO the simpler (and shorter) these strings are, the better. These ones look
good to me (maybe it is better to drop vbr-old and -q X, indeed). Other than
that, I have no comments.
Ok, I dropped vbr-old and -q X, uppercased the mp3 profiles, and
b72k is now 72kbps! Also nomad->info->vbr and nomad->info->avg_bitrate
are now calculated a little bit better. The patch is attached!


Johannes
Gregory Petrosyan
2011-04-23 19:15:29 UTC
Permalink
Post by Johannes Weißl
Post by Gregory Petrosyan
Post by Johannes Weißl
ogg: q3
q3.18
q-1
q10
b72k --> maybe change this to 72kbps ?
...
mp3: cbr
vbr
cbr V7 q3 --> should -q X be dropped?
vbr V5 q0
abr V2 q3
vbr-old V0 q3 --> is the vbr-old useful?
...
wv : normal
high
very high
normal hybrid x3
normal x2
...
mpc: Standard
Thumb
Radio
Extreme
Insane
BrainDead
...
aac: LC
Main
LTP
...
What do you think?
IMHO the simpler (and shorter) these strings are, the better. These ones look
good to me (maybe it is better to drop vbr-old and -q X, indeed). Other than
that, I have no comments.
Ok, I dropped vbr-old and -q X, uppercased the mp3 profiles, and
b72k is now 72kbps! Also nomad->info->vbr and nomad->info->avg_bitrate
are now calculated a little bit better. The patch is attached!
Merged to -pu, thanks!

Gregory

Johannes Weißl
2011-04-13 21:28:24 UTC
Permalink
---
wavpack.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/wavpack.c b/wavpack.c
index 99a26c5..b891194 100644
--- a/wavpack.c
+++ b/wavpack.c
@@ -86,18 +86,22 @@ static uint32_t get_pos(void *data)
return lseek(file->fd, 0, SEEK_CUR);
}

-static int set_pos_abs(void *data, uint32_t pos)
+static int set_pos_rel(void *data, int32_t delta, int mode)
{
struct wavpack_file *file = data;
+ int rc;

- return (lseek(file->fd, pos, SEEK_SET) == -1) ? -1 : 0;
+ rc = lseek(file->fd, delta, mode);
+ if (rc == -1)
+ return -1;
+
+ file->push_back_byte = EOF;
+ return 0;
}

-static int set_pos_rel(void *data, int32_t delta, int mode)
+static int set_pos_abs(void *data, uint32_t pos)
{
- struct wavpack_file *file = data;
-
- return (lseek(file->fd, delta, mode) == -1) ? -1 : 0;
+ return set_pos_rel(data, pos, SEEK_SET);
}

static int push_back_byte(void *data, int c)
--
1.7.4.1
Johannes Weißl
2011-04-12 15:23:07 UTC
Permalink
This is easier than even more getter functions.
---
mad.c | 28 +++++++++++++++-------------
nomad.c | 36 +++++-------------------------------
nomad.h | 16 +++++++++++-----
3 files changed, 31 insertions(+), 49 deletions(-)

diff --git a/mad.c b/mad.c
index d2ea26f..4ec6891 100644
--- a/mad.c
+++ b/mad.c
@@ -68,7 +68,7 @@ static struct nomad_callbacks callbacks = {
static int mad_open(struct input_plugin_data *ip_data)
{
struct nomad *nomad;
- struct nomad_info info;
+ const struct nomad_info *info;
int rc;

rc = nomad_open_callbacks(&nomad, ip_data, &callbacks);
@@ -80,10 +80,10 @@ static int mad_open(struct input_plugin_data *ip_data)
}
ip_data->private = nomad;

- nomad_info(nomad, &info);
+ info = nomad_info(nomad);

/* always 16-bit signed little-endian */
- ip_data->sf = sf_rate(info.sample_rate) | sf_channels(info.channels) |
+ ip_data->sf = sf_rate(info->sample_rate) | sf_channels(info->channels) |
sf_bits(16) | sf_signed(1);
return 0;
}
@@ -118,11 +118,12 @@ static int mad_seek(struct input_plugin_data *ip_data, double offset)
static int mad_read_comments(struct input_plugin_data *ip_data,
struct keyval **comments)
{
+ struct nomad *nomad = ip_data->private;
+ const struct nomad_lame *lame = nomad_lame(nomad);
struct id3tag id3;
int fd, rc, save, i;
APETAG(ape);
GROWING_KEYVALS(c);
- float rg_track_peak, rg_track_gain;

fd = open(ip_data->filename, O_RDONLY);
if (fd == -1) {
@@ -171,14 +172,14 @@ out:
ape_free(&ape);

/* add last so the other tags get preference */
- if (nomad_lame_replaygain(ip_data->private, &rg_track_peak, &rg_track_gain) == 0) {
+ if (!isnan(lame->trackGain)) {
char buf[64];

- if (!isnan(rg_track_peak)) {
- sprintf(buf, "%f", rg_track_peak);
+ if (!isnan(lame->peak)) {
+ sprintf(buf, "%f", lame->peak);
comments_add_const(&c, "replaygain_track_peak", buf);
}
- sprintf(buf, "%+.1f dB", rg_track_gain);
+ sprintf(buf, "%+.1f dB", lame->trackGain);
comments_add_const(&c, "replaygain_track_gain", buf);
}

@@ -189,23 +190,24 @@ out:

static int mad_duration(struct input_plugin_data *ip_data)
{
- struct nomad *nomad;
+ struct nomad *nomad = ip_data->private;

- nomad = ip_data->private;
- return nomad_time_total(nomad);
+ return nomad_info(nomad)->duration;
}

static long mad_bitrate(struct input_plugin_data *ip_data)
{
struct nomad *nomad = ip_data->private;
- long bitrate = nomad_bitrate(nomad);
+ long bitrate = nomad_info(nomad)->avg_bitrate;
+
return bitrate != -1 ? bitrate : -IP_ERROR_FUNCTION_NOT_SUPPORTED;
}

static char *mad_codec(struct input_plugin_data *ip_data)
{
struct nomad *nomad = ip_data->private;
- switch (nomad_layer(nomad)) {
+
+ switch (nomad_info(nomad)->layer) {
case 3:
return xstrdup("mp3");
case 2:
diff --git a/nomad.c b/nomad.c
index 162d514..c8cf1fd 100644
--- a/nomad.c
+++ b/nomad.c
@@ -78,14 +78,7 @@ struct nomad {
unsigned char toc[100];
} xing;

- struct {
- char encoder[10]; /* 9 byte encoder name/version ("LAME3.97b") */
- float peak; /* replaygain peak */
- float trackGain; /* replaygain track gain */
- float albumGain; /* replaygain album gain */
- int encoderDelay; /* # of added samples at start of mp3 */
- int encoderPadding; /* # of added samples at end of mp3 */
- } lame;
+ struct nomad_lame lame;

struct {
int size;
@@ -617,11 +610,6 @@ void nomad_close(struct nomad *nomad)
free(nomad);
}

-void nomad_info(struct nomad *nomad, struct nomad_info *info)
-{
- *info = nomad->info;
-}
-
int nomad_read(struct nomad *nomad, char *buffer, int count)
{
int i, j, size, psize, to;
@@ -841,26 +829,12 @@ int nomad_time_seek(struct nomad *nomad, double pos)
return 0;
}

-int nomad_lame_replaygain(struct nomad *nomad, float *peak, float *trackGain)
-{
- if (isnan(nomad->lame.trackGain))
- return -1;
- *peak = nomad->lame.peak;
- *trackGain = nomad->lame.trackGain;
- return 0;
-}
-
-double nomad_time_total(struct nomad *nomad)
-{
- return nomad->info.duration;
-}
-
-int nomad_bitrate(struct nomad *nomad)
+const struct nomad_lame *nomad_lame(struct nomad *nomad)
{
- return nomad->info.avg_bitrate;
+ return &nomad->lame;
}

-int nomad_layer(struct nomad *nomad)
+const struct nomad_info *nomad_info(struct nomad *nomad)
{
- return nomad->info.layer;
+ return &nomad->info;
}
diff --git a/nomad.h b/nomad.h
index dcb1a89..8ddabfc 100644
--- a/nomad.h
+++ b/nomad.h
@@ -38,6 +38,15 @@ struct nomad_callbacks {
int (*close)(void *datasource);
};

+struct nomad_lame {
+ char encoder[10]; /* 9 byte encoder name/version ("LAME3.97b") */
+ float peak; /* replaygain peak */
+ float trackGain; /* replaygain track gain */
+ float albumGain; /* replaygain album gain */
+ int encoderDelay; /* # of added samples at start of mp3 */
+ int encoderPadding; /* # of added samples at end of mp3 */
+};
+
/* always 16-bit signed little-endian */
struct nomad_info {
double duration;
@@ -68,7 +77,6 @@ int nomad_open_callbacks(struct nomad **nomadp, void *datasource,
struct nomad_callbacks *cbs);

void nomad_close(struct nomad *nomad);
-void nomad_info(struct nomad *nomad, struct nomad_info *info);

/* -NOMAD_ERROR_ERRNO */
int nomad_read(struct nomad *nomad, char *buffer, int count);
@@ -76,9 +84,7 @@ int nomad_read(struct nomad *nomad, char *buffer, int count);
/* -NOMAD_ERROR_ERRNO */
int nomad_time_seek(struct nomad *nomad, double pos);

-int nomad_lame_replaygain(struct nomad *nomad, float *peak, float *trackGain);
-double nomad_time_total(struct nomad *nomad);
-int nomad_bitrate(struct nomad *nomad);
-int nomad_layer(struct nomad *nomad);
+const struct nomad_lame *nomad_lame(struct nomad *nomad);
+const struct nomad_info *nomad_info(struct nomad *nomad);

#endif
--
1.7.4.1
Loading...