ocarina/libsaria/track/track.cpp

253 lines
4.6 KiB
C++

// Copyright (c) 2011 Bryan Schumaker.
#include <library.h>
#include <notify.h>
#include <format.h>
#include <track.h>
#include <audio.h>
#include <prefs.h>
#include <print.h>
#include <deck.h>
#include <taglib/tag.h>
#include <taglib/fileref.h>
#include <ctime>
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace std;
static libsaria::Track *cur = NULL;
static void make_lenstr(unsigned int length, string &res)
{
int minutes;
int seconds;
stringstream stream;
/* Convert length into mm:ss format */
minutes = length / 60;
seconds = length - (minutes * 60);
stream << minutes << ":";
if (seconds < 10)
stream << "0";
stream << seconds;
res = stream.str();
}
static inline void escape_text(string &text)
{
replace(text.begin(), text.end(), '\n', ' ');
}
namespace libsaria
{
void Track::read_tags()
{
TagLib::Tag *tag;
TagLib::AudioProperties *prop;
TagLib::FileRef ref(filepath.c_str());
if (ref.isNull())
throw "Error tagging file: " + filepath;
/* Extract tags */
tag = ref.tag();
title = tag->title().to8Bit(true);
artist = tag->artist().to8Bit(true);
album = tag->album().to8Bit(true);
comment = tag->comment().to8Bit(true);
genre = tag->genre().to8Bit(true);
year = tag->year();
track = tag->track();
/* Strip out newline characters */
escape_text(title);
escape_text(artist);
escape_text(album);
escape_text(comment);
escape_text(genre);
/* Extract audio properties */
prop = ref.audioProperties();
length = prop->length();
bitrate = prop->bitrate();
sample = prop->sampleRate();
channels = prop->channels();
}
Track::Track()
{
}
Track::Track(string file)
{
filepath = file;
banned = false;
read_tags();
}
Track::Track(string file, struct library::Path *lib_path)
{
filepath = file;
path = lib_path;
count = 0;
last_day = 0;
last_month = 0;
last_year = 0;
banned = false;
read_tags();
id = lib_path->tracks.size();
artist_lc = lowercase(artist);
album_lc = lowercase(album);
make_lenstr(length, lenstr);
find_substrs();
}
Track::Track(ifstream &in, struct library::Path *lib_path,
unsigned int version)
{
string tmp;
stringstream s;
path = lib_path;
getline(in, filepath);
getline(in, title);
getline(in, artist);
getline(in, album);
getline(in, comment);
getline(in, genre);
getline(in, lenstr);
getline(in, tmp);
s.clear();
s.str(tmp);
s >> id;
s >> year;
s >> track;
s >> count;
s >> last_day;
s >> last_month;
s >> last_year;
s >> length;
s >> bitrate;
s >> sample;
s >> channels;
if (version >= 2)
s >> banned;
else
banned = false;
artist_lc = lowercase(artist);
album_lc = lowercase(album);
find_substrs();
}
Track::~Track()
{
}
void Track::mark_played()
{
time_t now = time(0);
tm *ltm = localtime(&now);
list<Playlist *>::iterator it;
if (path && audio::played()) {
count++;
last_day = ltm->tm_mday;
last_month = ltm->tm_mon + 1;
last_year = 1900 + ltm->tm_year;
library::save_path(path);
for (it = playlists.begin(); it != playlists.end(); it++)
(*it)->track_updated(this);
}
}
void Track::load_unlisted(bool play)
{
if (cur)
cur->mark_played();
println("Loading: " + title + " by " + artist);
audio::load(filepath, play);
if (path) {
prefs::set("libsaria.current.library", path->id);
prefs::set("libsaria.current.track", id);
}
cur = this;
notify(TRACK_CHANGED, cur);
}
void Track::load(bool play)
{
load_unlisted(play);
if (path)
deck::list_recent(this);
}
Track *current_track()
{
return cur;
}
void Track::save(ofstream *out)
{
*out << filepath << "\n";
*out << title << "\n";
*out << artist << "\n";
*out << album << "\n";
*out << comment << "\n";
*out << genre << "\n";
*out << lenstr << "\n";
*out << id << " ";
*out << year << " ";
*out << track << " ";
*out << count << " ";
*out << last_day << " ";
*out << last_month << " ";
*out << last_year << " ";
*out << length << " ";
*out << bitrate << " ";
*out << sample << " ";
*out << channels << " ";
*out << banned << "\n";
}
void Track::add_playlist(Playlist *plist)
{
playlists.push_back(plist);
}
void Track::rm_playlist(Playlist *plist)
{
playlists.remove(plist);
}
void Track::find_substrs()
{
format_substrs(artist, substrs);
format_substrs(album, substrs);
format_substrs(title, substrs);
}
bool Track::is_visible(set<string> *search) {
set<string>::iterator it;
for (it = search->begin(); it != search->end(); it++) {
if (substrs.find(*it) == substrs.end())
return false;
}
return true;
}
} /* Namespace: libsaria */