From 4e393d27701c3779acfc35e8b1d493746dbfdaac Mon Sep 17 00:00:00 2001 From: daper Date: Sat, 16 Dec 2006 16:38:58 +0000 Subject: [PATCH] Added average bitrate field to the output of mocp -i. (Jack Miller ) git-svn-id: svn://svn.daper.net/moc/trunk@1950 910807d9-36e0-0310-a014-e9ea483e2ba4 --- decoder.h | 12 +++++++++++- decoder_plugins/ffmpeg/ffmpeg.c | 16 +++++++++++++++- decoder_plugins/flac/flac.c | 13 ++++++++++++- decoder_plugins/modplug/modplug.c | 1 + decoder_plugins/mp3/mp3.c | 20 +++++++++++++++++++- decoder_plugins/musepack/musepack.c | 14 ++++++++++++-- decoder_plugins/sndfile/sndfile_formats.c | 1 + decoder_plugins/speex/speex.c | 3 ++- decoder_plugins/vorbis/vorbis.c | 14 ++++++++++++-- interface.c | 14 ++++++++++++++ player.c | 9 +++++++++ protocol.h | 2 ++ server.c | 12 ++++++++++++ server.h | 1 + 14 files changed, 123 insertions(+), 9 deletions(-) diff --git a/decoder.h b/decoder.h index 929789b7..06c509d1 100644 --- a/decoder.h +++ b/decoder.h @@ -9,7 +9,7 @@ * * On every change in the decoder API this number will be changed, so MOC will * not load plugins compiled with older/newer decoder.h. */ -#define DECODER_API_VERSION 6 +#define DECODER_API_VERSION 7 /** Type of the decoder error. */ enum decoder_error_type @@ -241,6 +241,16 @@ struct decoder * \return Pointer to the used IO stream. */ struct io_stream *(*get_stream)(void *data); + + /** Get the average bitrate. + * + * Get the bitrate of the whole file. + * + * \param data Decoder's private data. + * + * \return Average bitrate in Kbps or -1 if not available. + */ + int (*get_avg_bitrate)(void *data); }; /** Initialize decoder plugin. diff --git a/decoder_plugins/ffmpeg/ffmpeg.c b/decoder_plugins/ffmpeg/ffmpeg.c index 64b88141..3674b96c 100644 --- a/decoder_plugins/ffmpeg/ffmpeg.c +++ b/decoder_plugins/ffmpeg/ffmpeg.c @@ -29,6 +29,9 @@ #undef COMMON_H #undef LOG_H +/* same for logging... */ +#undef LOG_H + #define DEBUG #include "common.h" @@ -49,6 +52,7 @@ struct ffmpeg_data int ok; /* was this stream successfully opened? */ struct decoder_error error; int bitrate; + int avg_bitrate; }; static void ffmpeg_init () @@ -151,6 +155,8 @@ static void *ffmpeg_open (const char *file) data->remain_buf_len = 0; data->ok = 1; + data->avg_bitrate = (int) (data->ic->file_size / + (data->ic->duration / 1000000) * 8); data->bitrate = data->ic->bit_rate / 1000; return data; @@ -319,6 +325,13 @@ static int ffmpeg_get_bitrate (void *prv_data) return data->bitrate; } +static int ffmpeg_get_avg_bitrate (void *prv_data) +{ + struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data; + + return data->avg_bitrate / 1000; +} + static int ffmpeg_get_duration (void *prv_data) { struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data; @@ -377,7 +390,8 @@ static struct decoder ffmpeg_decoder = { NULL, ffmpeg_get_name, NULL, - NULL + NULL, + ffmpeg_get_avg_bitrate }; struct decoder *plugin_init () diff --git a/decoder_plugins/flac/flac.c b/decoder_plugins/flac/flac.c index 2eb0ff4d..b44554dd 100644 --- a/decoder_plugins/flac/flac.c +++ b/decoder_plugins/flac/flac.c @@ -49,6 +49,7 @@ struct flac_data #endif struct io_stream *stream; int bitrate; + int avg_bitrate; int abort; /* abort playing (due to an error) */ unsigned length; @@ -307,6 +308,7 @@ static void *flac_open_internal (const char *file, const int buffered) data->decoder = NULL; data->bitrate = -1; + data->avg_bitrate = -1; data->abort = 0; data->sample_buffer_fill = 0; data->last_decode_position = 0; @@ -399,6 +401,7 @@ static void *flac_open_internal (const char *file, const int buffered) return data; } #endif + data->avg_bitrate = (data->bits_per_sample) * data->sample_rate; return data; } @@ -652,6 +655,13 @@ static int flac_get_bitrate (void *void_data) return data->bitrate; } +static int flac_get_avg_bitrate (void *void_data) +{ + struct flac_data *data = (struct flac_data *)void_data; + + return data->avg_bitrate / 1000; +} + static int flac_get_duration (void *void_data) { struct flac_data *data = (struct flac_data *)void_data; @@ -694,7 +704,8 @@ static struct decoder flac_decoder = { NULL, flac_get_name, NULL, - NULL + NULL, + flac_get_avg_bitrate }; struct decoder *plugin_init () diff --git a/decoder_plugins/modplug/modplug.c b/decoder_plugins/modplug/modplug.c index 47b70ca8..ee0fc8a8 100644 --- a/decoder_plugins/modplug/modplug.c +++ b/decoder_plugins/modplug/modplug.c @@ -305,6 +305,7 @@ static struct decoder modplug_decoder = NULL, modplug_get_name, NULL, + NULL, NULL }; diff --git a/decoder_plugins/mp3/mp3.c b/decoder_plugins/mp3/mp3.c index 86bb8b17..820d8775 100644 --- a/decoder_plugins/mp3/mp3.c +++ b/decoder_plugins/mp3/mp3.c @@ -59,6 +59,8 @@ struct mp3_data { struct io_stream *io_stream; unsigned long bitrate; + long avg_bitrate; + unsigned int freq; short channels; signed long duration; /* Total time of the file in seconds. @@ -289,6 +291,9 @@ static int count_time_internal (struct mp3_data *data) /* samplerate is a constant */ num_frames = (long) (time * header.samplerate / nsamples); + /* the average bitrate is the constant bitrate */ + data->avg_bitrate = bitrate; + mad_timer_set(&duration, (long)time, (long)(timefrac*100), 100); } @@ -304,6 +309,10 @@ static int count_time_internal (struct mp3_data *data) "VBR file."); } + if (data->avg_bitrate == -1) + data->avg_bitrate = data->size + / mad_timer_count(duration, MAD_UNITS_SECONDS) * 8; + mad_header_finish(&header); debug ("MP3 time: %ld", mad_timer_count (duration, MAD_UNITS_SECONDS)); @@ -325,6 +334,7 @@ static struct mp3_data *mp3_open_internal (const char *file, data->channels = 0; data->skip_frames = 0; data->bitrate = -1; + data->avg_bitrate = -1; /* Open the file */ data->io_stream = io_open (file, buffered); @@ -652,6 +662,13 @@ static int mp3_get_bitrate (void *void_data) return data->bitrate / 1000; } +static int mp3_get_avg_bitrate (void *void_data) +{ + struct mp3_data *data = (struct mp3_data *)void_data; + + return data->avg_bitrate / 1000; +} + static int mp3_get_duration (void *void_data) { struct mp3_data *data = (struct mp3_data *)void_data; @@ -785,7 +802,8 @@ static struct decoder mp3_decoder = { mp3_our_mime, mp3_get_name, NULL, - mp3_get_stream + mp3_get_stream, + mp3_get_avg_bitrate }; struct decoder *plugin_init () diff --git a/decoder_plugins/musepack/musepack.c b/decoder_plugins/musepack/musepack.c index dfe80871..57e69637 100644 --- a/decoder_plugins/musepack/musepack.c +++ b/decoder_plugins/musepack/musepack.c @@ -37,6 +37,7 @@ struct musepack_data mpc_decoder decoder; mpc_reader reader; mpc_streaminfo info; + int avg_bitrate; int bitrate; struct decoder_error error; int ok; /* was this stream successfully opened? */ @@ -119,7 +120,8 @@ static void musepack_open_stream_internal (struct musepack_data *data) return; } - debug ("Avg bitrate: %d", (int)(data->info.average_bitrate / 1000)); + data->avg_bitrate = (int) (data->info.average_bitrate / 1000); + debug ("Avg bitrate: %d", data->avg_bitrate); data->remain_buf = NULL; data->remain_buf_len = 0; @@ -323,6 +325,13 @@ static int musepack_get_bitrate (void *prv_data) return data->bitrate; } +static int musepack_get_avg_bitrate (void *prv_data) +{ + struct musepack_data *data = (struct musepack_data *)prv_data; + + return data->avg_bitrate; +} + static int musepack_get_duration (void *prv_data) { struct musepack_data *data = (struct musepack_data *)prv_data; @@ -372,7 +381,8 @@ static struct decoder musepack_decoder = { NULL /*musepack_our_mime*/, musepack_get_name, NULL /* musepack_current_tags */, - musepack_get_stream + musepack_get_stream, + musepack_get_avg_bitrate }; struct decoder *plugin_init () diff --git a/decoder_plugins/sndfile/sndfile_formats.c b/decoder_plugins/sndfile/sndfile_formats.c index 9c74220f..a307981a 100644 --- a/decoder_plugins/sndfile/sndfile_formats.c +++ b/decoder_plugins/sndfile/sndfile_formats.c @@ -200,6 +200,7 @@ static struct decoder sndfile_decoder = { NULL, sndfile_get_name, NULL, + NULL, NULL }; diff --git a/decoder_plugins/speex/speex.c b/decoder_plugins/speex/speex.c index ac018639..824a2e2a 100644 --- a/decoder_plugins/speex/speex.c +++ b/decoder_plugins/speex/speex.c @@ -704,7 +704,8 @@ static struct decoder spx_decoder = { spx_our_mime, spx_get_name, NULL /*spx_current_tags*/, - spx_get_stream + spx_get_stream, + NULL }; struct decoder *plugin_init () diff --git a/decoder_plugins/vorbis/vorbis.c b/decoder_plugins/vorbis/vorbis.c index ee04ef17..fda9e0ca 100644 --- a/decoder_plugins/vorbis/vorbis.c +++ b/decoder_plugins/vorbis/vorbis.c @@ -35,6 +35,7 @@ struct vorbis_data OggVorbis_File vf; int last_section; int bitrate; + int avg_bitrate; int duration; struct decoder_error error; int ok; /* was this stream successfully opened? */ @@ -218,7 +219,8 @@ static void vorbis_open_stream_internal (struct vorbis_data *data) } else { data->last_section = -1; - data->bitrate = ov_bitrate(&data->vf, -1) / 1000; + data->avg_bitrate = ov_bitrate(&data->vf, -1) / 1000; + data->bitrate = data->avg_bitrate; if ((data->duration = ov_time_total(&data->vf, -1)) == OV_EINVAL) data->duration = -1; @@ -367,6 +369,13 @@ static int vorbis_get_bitrate (void *prv_data) return data->bitrate; } +static int vorbis_get_avg_bitrate (void *prv_data) +{ + struct vorbis_data *data = (struct vorbis_data *)prv_data; + + return data->avg_bitrate; +} + static int vorbis_get_duration (void *prv_data) { struct vorbis_data *data = (struct vorbis_data *)prv_data; @@ -422,7 +431,8 @@ static struct decoder vorbis_decoder = { vorbis_our_mime, vorbis_get_name, vorbis_current_tags, - vorbis_get_stream + vorbis_get_stream, + vorbis_get_avg_bitrate }; struct decoder *plugin_init () diff --git a/interface.c b/interface.c index 1c0c956f..68bb01d4 100644 --- a/interface.c +++ b/interface.c @@ -95,6 +95,7 @@ static struct file_info { char *file; struct file_tags *tags; char *title; + int avg_bitrate; int bitrate; int rate; int curr_time; @@ -410,6 +411,12 @@ static int get_bitrate () return get_data_int (); } +static int get_avg_bitrate () +{ + send_int_to_srv (CMD_GET_AVG_BITRATE); + return get_data_int (); +} + static int get_curr_time () { send_int_to_srv (CMD_GET_CTIME); @@ -1009,6 +1016,9 @@ static void server_event (const int event, void *data) case EV_FILE_TAGS: ev_file_tags ((struct tag_ev_response *)data); break; + case EV_AVG_BITRATE: + curr_file.avg_bitrate = get_avg_bitrate (); + break; default: interface_fatal ("Unknown event: 0x%02x", event); } @@ -3621,6 +3631,7 @@ void interface_cmdline_file_info (const int server_sock) curr_file.rate = get_rate (); curr_file.bitrate = get_bitrate (); curr_file.curr_time = get_curr_time (); + curr_file.avg_bitrate = get_avg_bitrate (); if (curr_file.tags->time != -1) sec_to_min (time_str, curr_file.tags->time); @@ -3668,6 +3679,9 @@ void interface_cmdline_file_info (const int server_sock) printf ("Bitrate: %dKbps\n", curr_file.bitrate > 0 ? curr_file.bitrate : 0); + printf ("AvgBitrate: %dKbps\n", + curr_file.avg_bitrate > 0 + ? curr_file.avg_bitrate : 0); printf ("Rate: %dKHz\n", curr_file.rate); file_info_cleanup (&curr_file); diff --git a/player.c b/player.c index 52c4c0bc..fbfd47cf 100644 --- a/player.c +++ b/player.c @@ -607,6 +607,7 @@ static void play_file (const char *file, const struct decoder *f, decoder_data = precache.decoder_data; set_info_channels (sound_params.channels); set_info_rate (sound_params.rate / 1000); + if (!audio_open(&sound_params)) return; audio_send_buf (precache.buf, precache.buf_fill); @@ -621,6 +622,12 @@ static void play_file (const char *file, const struct decoder *f, } already_decoded_time = precache.decoded_time; + + if(f->get_avg_bitrate) + set_info_avg_bitrate (f->get_avg_bitrate(decoder_data)); + else + set_info_avg_bitrate (0); + bitrate_list_init (&bitrate_list); bitrate_list.head = precache.bitrate_list.head; bitrate_list.tail = precache.bitrate_list.tail; @@ -644,6 +651,8 @@ static void play_file (const char *file, const struct decoder *f, } already_decoded_time = 0.0; + if(f->get_avg_bitrate) + set_info_avg_bitrate (f->get_avg_bitrate(decoder_data)); bitrate_list_init (&bitrate_list); } diff --git a/protocol.h b/protocol.h index b4e2abd8..c56be63d 100644 --- a/protocol.h +++ b/protocol.h @@ -56,6 +56,7 @@ enum noblock_io_status #define EV_STATUS_MSG 0x0f /* Followed by a status message */ #define EV_MIXER_CHANGE 0x10 /* the mixer channel was changed */ #define EV_FILE_TAGS 0x11 /* tags in a response for tags request */ +#define EV_AVG_BITRATE 0x12 /* average bitrate has changed (new song) */ /* Events caused by a client that wants to modify the playlist (see * CMD_CLI_PLIST* commands. */ @@ -118,6 +119,7 @@ enum noblock_io_status requests up to some file */ #define CMD_CLI_PLIST_MOVE 0x31 /* move an item */ #define CMD_LIST_MOVE 0x32 /* move an item */ +#define CMD_GET_AVG_BITRATE 0x33 /* get the average bitrate */ char *socket_name (); int get_int (int sock, int *i); diff --git a/server.c b/server.c index 9e809443..bc07359e 100644 --- a/server.c +++ b/server.c @@ -76,10 +76,12 @@ static char err_msg[265] = ""; /* Information about currently played file */ static struct { + int avg_bitrate; int bitrate; int rate; int channels; } sound_info = { + -1, -1, -1, -1 @@ -1024,6 +1026,10 @@ static void handle_command (const int client_id) if (!send_data_int(cli, sound_info.bitrate)) err = 1; break; + case CMD_GET_AVG_BITRATE: + if (!send_data_int(cli, sound_info.avg_bitrate)) + err = 1; + break; case CMD_GET_RATE: if (!send_data_int(cli, sound_info.rate)) err = 1; @@ -1294,6 +1300,12 @@ void set_info_rate (const int rate) add_event_all (EV_RATE, NULL); } +void set_info_avg_bitrate (const int avg_bitrate) +{ + sound_info.avg_bitrate = avg_bitrate; + add_event_all (EV_AVG_BITRATE, NULL); +} + /* Notify the client about change of the player state. */ void state_change () { diff --git a/server.h b/server.h index faebdf6a..b7280078 100644 --- a/server.h +++ b/server.h @@ -12,6 +12,7 @@ void state_change (); void set_info_rate (const int rate); void set_info_channels (const int channels); void set_info_bitrate (const int bitrate); +void set_info_avg_bitrate (const int avg_bitrate); void tags_change (); void ctime_change (); void status_msg (const char *msg);