diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2009-10-11 17:14:10 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2009-10-11 17:14:10 +0200 |
commit | 4326a465afb45622d22d2dd52fe6f4d25f1a17ef (patch) | |
tree | c9480b530aa077ab43f5bc9a3940eda556accb03 | |
parent | 9425bbc1716081cff72c73744a4fc82251b9db41 (diff) |
added total playtime display to statusbar
-rw-r--r-- | callbacks.c | 6 | ||||
-rw-r--r-- | cdumb.c | 2 | ||||
-rw-r--r-- | cgme.c | 6 | ||||
-rw-r--r-- | csid.cpp | 4 | ||||
-rw-r--r-- | deadbeef.h | 3 | ||||
-rw-r--r-- | gtkplaylist.c | 8 | ||||
-rw-r--r-- | main.c | 12 | ||||
-rw-r--r-- | playlist.c | 49 | ||||
-rw-r--r-- | playlist.h | 10 | ||||
-rw-r--r-- | plugins.c | 10 | ||||
-rw-r--r-- | plugins/cdda/cdda.c | 2 | ||||
-rw-r--r-- | plugins/faad2/faad2.c | 2 | ||||
-rw-r--r-- | plugins/ffap/ffap.c | 2 | ||||
-rw-r--r-- | plugins/flac/flac.c | 2 | ||||
-rw-r--r-- | plugins/lastfm/lastfm.c | 6 | ||||
-rw-r--r-- | plugins/mpgmad/mpgmad.c | 8 | ||||
-rw-r--r-- | plugins/sndfile/sndfile.c | 2 | ||||
-rw-r--r-- | plugins/vorbis/vorbis.c | 10 | ||||
-rw-r--r-- | plugins/wavpack/wavpack.c | 2 |
19 files changed, 96 insertions, 50 deletions
diff --git a/callbacks.c b/callbacks.c index e8af63dd..abf970fc 100644 --- a/callbacks.c +++ b/callbacks.c @@ -921,8 +921,8 @@ seekbar_draw (GtkWidget *widget) { pos = x; } else { - if (str_playing_song.decoder && str_playing_song.duration > 0) { - pos = streamer_get_playpos () / str_playing_song.duration; + if (str_playing_song.decoder && str_playing_song._duration > 0) { + pos = streamer_get_playpos () / str_playing_song._duration; pos *= widget->allocation.width; } } @@ -1012,7 +1012,7 @@ on_seekbar_button_release_event (GtkWidget *widget, seekbar_moving = 0; seekbar_draw (widget); seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); - float time = event->x * str_playing_song.duration / (widget->allocation.width); + float time = event->x * str_playing_song._duration / (widget->allocation.width); if (time < 0) { time = 0; } @@ -781,7 +781,7 @@ cdumb_insert (DB_playItem_t *after, const char *fname) { deadbeef->pl_add_meta (it, "title", NULL); } dumb_it_do_initial_runthrough (duh); - it->duration = duh_get_length (duh)/65536.0f; + deadbeef->pl_set_item_duration (it, duh_get_length (duh)/65536.0f); it->filetype = ftype; // printf ("duration: %f\n", plugin.info.duration); after = deadbeef->pl_insert_item (after, it); @@ -42,7 +42,7 @@ cgme_init (DB_playItem_t *it) { plugin.info.bps = 16; plugin.info.channels = 2; plugin.info.samplerate = deadbeef->playback_get_samplerate (); - duration = it->duration; + duration = deadbeef->pl_get_item_duration (it); reallength = inf.length; nzerosamples = 0; plugin.info.readpos = 0; @@ -136,10 +136,10 @@ cgme_insert (DB_playItem_t *after, const char *fname) { snprintf (trk, 10, "%d", i+1); deadbeef->pl_add_meta (it, "track", trk); if (inf.length == -1) { - it->duration = 300; + deadbeef->pl_set_item_duration (it, 300); } else { - it->duration = (float)inf.length/1000.f; + deadbeef->pl_set_item_duration (it, (float)inf.length/1000.f); } const char *ext = fname + strlen (fname) - 1; while (ext >= fname && *ext != '.') { @@ -319,7 +319,7 @@ csid_init (DB_playItem_t *it) { // resid->create (1); resid->filter (true); resid->sampling (deadbeef->playback_get_samplerate ()); - duration = it->duration; + duration = deadbeef->pl_get_item_duration (it); tune = new SidTune (it->fname); tune->selectSong (it->tracknum+1); @@ -554,7 +554,7 @@ csid_insert (DB_playItem_t *after, const char *fname) { // printf ("\n"); // } } - it->duration = length; + deadbeef->pl_set_item_duration (it, length); it->filetype = "SID"; after = deadbeef->pl_insert_item (after, it); @@ -70,7 +70,6 @@ typedef struct { int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs) int startsample; // start sample of track, or -1 for auto int endsample; // end sample of track, or -1 for auto - float duration; // in seconds int shufflerating; // sort order for shuffle mode float playtime; // total playtime time_t started_timestamp; // result of calling time(NULL) @@ -201,6 +200,8 @@ typedef struct { void (*pl_add_meta) (DB_playItem_t *it, const char *key, const char *value); const char *(*pl_find_meta) (DB_playItem_t *song, const char *meta); void (*pl_delete_all_meta) (DB_playItem_t *it); + void (*pl_set_item_duration) (DB_playItem_t *it, float duration); + float (*pl_get_item_duration) (DB_playItem_t *it); // cuesheet support DB_playItem_t *(*pl_insert_cue_from_buffer) (DB_playItem_t *after, const char *fname, const uint8_t *buffer, int buffersize, struct DB_decoder_s *decoder, const char *ftype, int numsamples, int samplerate); DB_playItem_t * (*pl_insert_cue) (DB_playItem_t *after, const char *filename, struct DB_decoder_s *decoder, const char *ftype, int numsamples, int samplerate); diff --git a/gtkplaylist.c b/gtkplaylist.c index 9d72aef2..b50565d9 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -89,7 +89,7 @@ const char *colnames[pl_ncolumns] = { "Artist / Album", "Track №", "Title / Track Artist", - "Duration" + "_duration" }; static uintptr_t play16_pixbuf; @@ -265,9 +265,9 @@ gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it) { // draw as columns char dur[10] = "-:--"; if (it) { - if (it->duration >= 0) { - int min = (int)it->duration/60; - int sec = (int)(it->duration-min*60); + if (it->_duration >= 0) { + int min = (int)it->_duration/60; + int sec = (int)(it->_duration-min*60); snprintf (dur, 10, "%d:%02d", min, sec); } } @@ -102,8 +102,10 @@ update_songinfo (void) { float playpos = streamer_get_playpos (); int minpos = playpos / 60; int secpos = playpos - minpos * 60; - int mindur = str_playing_song.duration / 60; - int secdur = str_playing_song.duration - mindur * 60; + int mindur = str_playing_song._duration / 60; + int secdur = str_playing_song._duration - mindur * 60; + int mintotal = pl_totaltime / 60; + int sectotal = pl_totaltime - mintotal * 60; const char *mode = c->info.channels == 1 ? "Mono" : "Stereo"; int samplerate = c->info.samplerate; int bitspersample = c->info.bps; @@ -111,14 +113,14 @@ update_songinfo (void) { codec_unlock (); char t[100]; - if (str_playing_song.duration >= 0) { + if (str_playing_song._duration >= 0) { snprintf (t, sizeof (t), "%d:%02d", mindur, secdur); } else { strcpy (t, "-:--"); } - snprintf (sbtext_new, 512, "[%s] %dHz | %d bit | %s | %d:%02d / %s | %d songs total", str_playing_song.filetype ? str_playing_song.filetype:"-", samplerate, bitspersample, mode, minpos, secpos, t, pl_getcount ()); + snprintf (sbtext_new, sizeof (sbtext_new), "[%s] %dHz | %d bit | %s | %d:%02d / %s | %d songs | %d:%02d total playtime", str_playing_song.filetype ? str_playing_song.filetype:"-", samplerate, bitspersample, mode, minpos, secpos, t, pl_getcount (), mintotal, sectotal); } if (strcmp (sbtext_new, sb_text)) { @@ -144,7 +146,7 @@ update_songinfo (void) { if (mainwin) { GtkWidget *widget = lookup_widget (mainwin, "seekbar"); // translate volume to seekbar pixels - songpos /= str_playing_song.duration; + songpos /= str_playing_song._duration; songpos *= widget->allocation.width; if ((int)(songpos*2) != (int)(last_songpos*2)) { GDK_THREADS_ENTER(); @@ -48,6 +48,7 @@ playItem_t *playlist_head[PL_MAX_ITERATORS]; playItem_t *playlist_tail[PL_MAX_ITERATORS]; playItem_t *playlist_current_ptr; int pl_count = 0; +float pl_totaltime = 0; static int pl_order = 0; // 0 = linear, 1 = shuffle, 2 = random static int pl_loop_mode = 0; // 0 = loop, 1 = don't loop, 2 = loop single @@ -186,15 +187,15 @@ pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, c return after; } (*prev)->endsample = (prevtime * samplerate) - 1; - (*prev)->duration = (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate; - if ((*prev)->duration < 0) { + pl_set_item_duration (*prev, (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate); + if ((*prev)->_duration < 0) { // might be bad cuesheet file, try to fix trace ("cuesheet seems to be corrupted, trying workaround\n"); trace ("[bad:] calc endsample=%d, prevtime=%f, samplerate=%d, prev track duration=%f\n", (*prev)->endsample, prevtime, samplerate, (*prev)->duration); prevtime = f_index01; (*prev)->endsample = (prevtime * samplerate) - 1; - (*prev)->duration = (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate; - if ((*prev)->duration > 0) { + pl_set_item_duration (*prev, (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate); + if ((*prev)->_duration > 0) { trace ("success :-D\n"); } else { @@ -308,7 +309,7 @@ pl_insert_cue_from_buffer (playItem_t *after, const char *fname, const uint8_t * if (after) { trace ("last track endsample: %d\n", numsamples-1); after->endsample = numsamples-1; - after->duration = (float)(after->endsample - after->startsample + 1) / samplerate; + pl_set_item_duration (after, (float)(after->endsample - after->startsample + 1) / samplerate); } return after; } @@ -518,6 +519,10 @@ pl_remove (playItem_t *it) { else { playlist_tail[PL_MAIN] = it->prev[PL_MAIN]; } + // totaltime + if (it->_duration > 0) { + pl_totaltime -= it->_duration; + } pl_item_free (it); free (it); return 0; @@ -608,6 +613,11 @@ pl_insert_item (playItem_t *after, playItem_t *it) { it->shufflerating = rand (); it->played = 0; + // totaltime + if (it->_duration > 0) { + pl_totaltime += it->_duration; + } + return it; } @@ -618,7 +628,7 @@ pl_item_copy (playItem_t *out, playItem_t *it) { out->tracknum = it->tracknum; out->startsample = it->startsample; out->endsample = it->endsample; - out->duration = it->duration; + pl_set_item_duration (out, it->_duration); out->shufflerating = it->shufflerating; out->filetype = it->filetype; out->replaygain_album_gain = it->replaygain_album_gain; @@ -1057,7 +1067,7 @@ pl_save (const char *fname) { if (fwrite (&it->endsample, 1, 4, fp) != 4) { goto save_fail; } - if (fwrite (&it->duration, 1, 4, fp) != 4) { + if (fwrite (&it->_duration, 1, 4, fp) != 4) { goto save_fail; } uint8_t ft = it->filetype ? strlen (it->filetype) : 0; @@ -1204,9 +1214,11 @@ pl_load (const char *fname) { goto load_fail; } // duration - if (fread (&it->duration, 1, 4, fp) != 4) { + float d; + if (fread (&d, 1, 4, fp) != 4) { goto load_fail; } + pl_set_item_duration (it, d); // get const filetype string from decoder uint8_t ft; if (fread (&ft, 1, 1, fp) != 1) { @@ -1342,3 +1354,24 @@ pl_delete_all_meta (playItem_t *it) { } it->meta = NULL; } + +void +pl_set_item_duration (playItem_t *it, float duration) { + if (pl_get_idx_of (it) != -1) { + if (it->_duration > 0) { + pl_totaltime -= it->_duration; + } + if (duration > 0) { + pl_totaltime += duration; + } + if (pl_totaltime < 0) { + pl_totaltime = 0; + } + } + it->_duration = duration; +} + +float +pl_get_item_duration (playItem_t *it) { + return it->_duration; +} @@ -37,7 +37,6 @@ typedef struct playItem_s { int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs) int startsample; int endsample; - float duration; // in seconds int shufflerating; // sort order for shuffle mode float playtime; // total playtime time_t started_timestamp; // result of calling time(NULL) @@ -46,6 +45,8 @@ typedef struct playItem_s { float replaygain_album_peak; float replaygain_track_gain; float replaygain_track_peak; + // private area, must not be visible to plugins + float _duration; // in seconds struct playItem_s *next[PL_MAX_ITERATORS]; // next item in linked list struct playItem_s *prev[PL_MAX_ITERATORS]; // prev item in linked list struct metaInfo_s *meta; // linked list storing metainfo @@ -58,6 +59,7 @@ extern playItem_t *playlist_tail[PL_MAX_ITERATORS]; // tail of linked list extern playItem_t *playlist_current_ptr; // pointer to a real current playlist item (or NULL) extern int pl_count; +extern float pl_totaltime; int pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data); @@ -161,4 +163,10 @@ pl_select_all (void); void pl_reshuffle (playItem_t **ppmin, playItem_t **ppmax); +// required to calculate total playtime +void +pl_set_item_duration (playItem_t *it, float duration); + +float +pl_get_item_duration (playItem_t *it); #endif // __PLAYLIST_H @@ -82,6 +82,8 @@ static DB_functions_t deadbeef_api = { .pl_item_copy = (void (*)(DB_playItem_t *, DB_playItem_t *))pl_item_copy, .pl_insert_item = (DB_playItem_t *(*) (DB_playItem_t *after, DB_playItem_t *it))pl_insert_item, .pl_get_idx_of = (int (*) (DB_playItem_t *it))pl_get_idx_of, + .pl_set_item_duration = (void (*) (DB_playItem_t *it, float duration))pl_set_item_duration, + .pl_get_item_duration = (float (*) (DB_playItem_t *it))pl_get_item_duration, // metainfo .pl_add_meta = (void (*) (DB_playItem_t *, const char *, const char *))pl_add_meta, .pl_find_meta = (const char *(*) (DB_playItem_t *, const char *))pl_find_meta, @@ -241,18 +243,18 @@ plug_playback_random (void) { float plug_playback_get_pos (void) { - if (str_playing_song.duration <= 0) { + if (str_playing_song._duration <= 0) { return 0; } - return streamer_get_playpos () * 100 / str_playing_song.duration; + return streamer_get_playpos () * 100 / str_playing_song._duration; } void plug_playback_set_pos (float pos) { - if (str_playing_song.duration <= 0) { + if (str_playing_song._duration <= 0) { return; } - float t = pos * str_playing_song.duration / 100.f; + float t = pos * str_playing_song._duration / 100.f; streamer_set_seek (t); } diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c index 76b4662a..a429d5a6 100644 --- a/plugins/cdda/cdda.c +++ b/plugins/cdda/cdda.c @@ -289,7 +289,7 @@ insert_single_track (CdIo_t* cdio, DB_playItem_t *after, const char* file, int t it->decoder = &plugin; it->fname = strdup (tmp); it->filetype = "cdda"; - it->duration = (float)sector_count / 75.0; + deadbeef->pl_set_item_duration (it, (float)sector_count / 75.0); snprintf (tmp, sizeof (tmp), "CD Track %02d", track_nr); deadbeef->pl_add_meta (it, "title", tmp); diff --git a/plugins/faad2/faad2.c b/plugins/faad2/faad2.c index 7c1d8cac..46a144ce 100644 --- a/plugins/faad2/faad2.c +++ b/plugins/faad2/faad2.c @@ -223,7 +223,7 @@ aac_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = ftype; - it->duration = duration; + deadbeef->pl_set_item_duration (it, duration); // read tags if (ftype == "aac") { diff --git a/plugins/ffap/ffap.c b/plugins/ffap/ffap.c index fd96fc9f..993863ed 100644 --- a/plugins/ffap/ffap.c +++ b/plugins/ffap/ffap.c @@ -1657,7 +1657,7 @@ ffap_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = "APE"; - it->duration = duration; + deadbeef->pl_set_item_duration (it, duration); int v2err = deadbeef->junk_read_id3v2 (it, fp); int v1err = deadbeef->junk_read_id3v1 (it, fp); diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c index 4a6b9f9c..de78d653 100644 --- a/plugins/flac/flac.c +++ b/plugins/flac/flac.c @@ -364,7 +364,7 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str DB_playItem_t *it = cb->it; //it->tracknum = 0; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { - it->duration = metadata->data.stream_info.total_samples / (float)metadata->data.stream_info.sample_rate; + deadbeef->pl_set_item_duration (it, metadata->data.stream_info.total_samples / (float)metadata->data.stream_info.sample_rate); } else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { const FLAC__StreamMetadata_VorbisComment *vc = &metadata->data.vorbis_comment; diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c index bd4577c9..e7c5cddb 100644 --- a/plugins/lastfm/lastfm.c +++ b/plugins/lastfm/lastfm.c @@ -247,7 +247,7 @@ lfm_fetch_song_info (DB_playItem_t *song, const char **a, const char **t, const if (!*b) { *b = ""; } - *l = song->duration; + *l = deadbeef->pl_get_item_duration (song); *n = deadbeef->pl_find_meta (song, "track"); if (!*n) { *n = ""; @@ -425,12 +425,12 @@ lastfm_songfinished (DB_event_song_t *ev, uintptr_t data) { #if !LFM_IGNORE_RULES // check submission rules // duration must be >= 30 sec - if (ev->song->duration < 30) { + if (deadbeef->pl_get_item_duration (ev->song) < 30) { trace ("song duration is %f seconds. not eligible for submission\n", ev->song->duration); return 0; } // must be played for >=240sec of half the total time - if (ev->song->playtime < 240 && ev->song->playtime < ev->song->duration/2) { + if (ev->song->playtime < 240 && ev->song->playtime < deadbeef->pl_get_item_duration (ev->song)/2) { trace ("song playtime=%f seconds. not eligible for submission\n", ev->song->playtime); return 0; } diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c index d25f59d4..7465a076 100644 --- a/plugins/mpgmad/mpgmad.c +++ b/plugins/mpgmad/mpgmad.c @@ -502,7 +502,7 @@ cmp3_init (DB_playItem_t *it) { plugin.seek_sample (0); } else { - it->duration = buffer.duration; + deadbeef->pl_set_item_duration (it, buffer.duration); buffer.startsample = 0; buffer.endsample = buffer.totalsamples-1; buffer.skipsamples = buffer.startdelay; @@ -526,7 +526,7 @@ cmp3_init (DB_playItem_t *it) { plugin.free (); return -1; } - it->duration = buffer.duration; + deadbeef->pl_set_item_duration (it, buffer.duration); if (buffer.duration >= 0) { buffer.endsample = buffer.totalsamples - 1; } @@ -921,7 +921,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) { it->fname = strdup (fname); deadbeef->fclose (fp); deadbeef->pl_add_meta (it, "title", NULL); - it->duration = -1; + deadbeef->pl_set_item_duration (it, -1); it->filetype = filetypes[0]; after = deadbeef->pl_insert_item (after, it); return after; @@ -998,7 +998,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) { int v1err = deadbeef->junk_read_id3v1 (it, fp); deadbeef->fclose (fp); deadbeef->pl_add_meta (it, "title", NULL); - it->duration = buffer.duration; + deadbeef->pl_set_item_duration (it, buffer.duration); it->filetype = ftype; after = deadbeef->pl_insert_item (after, it); diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c index 545d41b8..46e3a99f 100644 --- a/plugins/sndfile/sndfile.c +++ b/plugins/sndfile/sndfile.c @@ -138,7 +138,7 @@ sndfile_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = "wav"; - it->duration = duration; + deadbeef->pl_set_item_duration (it, duration); trace ("sndfile: totalsamples=%d, samplerate=%d, duration=%f\n", totalsamples, samplerate, duration); diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c index d3de500f..8a32bd86 100644 --- a/plugins/vorbis/vorbis.c +++ b/plugins/vorbis/vorbis.c @@ -132,7 +132,7 @@ cvorbis_init (DB_playItem_t *it) { plugin.free (); return -1; } - it->duration = -1; + deadbeef->pl_set_item_duration (it, -1); } else { @@ -150,7 +150,7 @@ cvorbis_init (DB_playItem_t *it) { plugin.free (); return -1; } - it->duration = ov_time_total (&vorbis_file, -1); + deadbeef->pl_set_item_duration (it, ov_time_total (&vorbis_file, -1)); } vi = ov_info (&vorbis_file, -1); if (!vi) { // not a vorbis stream @@ -177,7 +177,7 @@ cvorbis_init (DB_playItem_t *it) { } else { startsample = 0; - if (it->duration < 0) { + if (deadbeef->pl_get_item_duration (it) < 0) { endsample = -1; } else { @@ -311,7 +311,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = "OggVorbis"; - it->duration = -1; + deadbeef->pl_set_item_duration (it, -1); deadbeef->pl_add_meta (it, "title", NULL); after = deadbeef->pl_insert_item (after, it); return after; @@ -342,7 +342,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = "OggVorbis"; - it->duration = duration; + deadbeef->pl_set_item_duration (it, duration); // metainfo vorbis_comment *vc = ov_comment (&vorbis_file, -1); diff --git a/plugins/wavpack/wavpack.c b/plugins/wavpack/wavpack.c index 51608d64..5400a600 100644 --- a/plugins/wavpack/wavpack.c +++ b/plugins/wavpack/wavpack.c @@ -230,7 +230,7 @@ wv_insert (DB_playItem_t *after, const char *fname) { it->decoder = &plugin; it->fname = strdup (fname); it->filetype = "wv"; - it->duration = duration; + deadbeef->pl_set_item_duration (it, duration); trace ("wv: totalsamples=%d, samplerate=%d, duration=%f\n", totalsamples, samplerate, duration); |