Calculating through the iterator may lead to unexpected problems. We
already know the id of every database entry, so we might as well use it
directly.
Signed-off-by: Anna Schumaker <anna@ocarinaproject.net>
If a title began with a number then the number would be read as part of
the length, adding extra time. So a track with length "100" and title
"42 abcde" would be read back as having length "10042" and title "abcde"
Signed-off-by: Anna Schumaker <anna@ocarinaproject.net>
- Double check that track->valid == true before notifying the UI that
there is a new track.
- Use primary_key() instead of manually calculating the full filepath.
Signed-off-by: Anna Schumaker <anna@ocarinaproject.net>
Recalculating this doesn't change the runtime significantly, so we might
as well save some disk space.
Signed-off-by: Anna Schumaker <anna@ocarinaproject.net>
This will let me set up a Track class that has pointers to the
corresponding artist, album and genre information without needing to
know their IDs directly. Having this information available means I
won't need to keep a "join struct" when doing lookups - instead I can
return a pointer to a Track class that already knows everything.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I didn't have any changes to make to the IdleQueue itself, but I did
need to update the unit test and reword a few things in the design.
Signed-off-by: Anna Schuamker <schumaker.anna@gmail.com>
- filter :: add() now returns the lowercased text
- Don't cache lowercased strings
- Remove functions depending on CONFIG_TEST
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I updated the design and rewrote the unit tests. This creates something
more consistent with how I ended up using the index.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I add:
- Autosaving option
- Real iterators
- Better accessor functions
The new design and unit test also allows me to remove the 300,000+ line
"database.good" file that the old tests were based on.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Needing to use throw / catch was getting in the way. Instead, check for
a boolean return value.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I changed primary_key() into a function since it is only called once,
and there is no point in using more mmemory than I need to. I also
created a basic unit test for everything that database entries are
supposed to do.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I was double clicking tracks in the gui, and they were removed from the
playqueue! This patch fixes that.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I'm taking a break from gui code to clean up the build system and update
my unit tests. This patch updates how code is built, and reworks my
"print" test to test version number instead.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I need this in case the user deletes all tracks from a playqueue without
adding anything by the time next() is called.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This is called by the GUI to tell the playqueue that a track has been
selected. This gives the PQ a chance to (possibly) remove it.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
When a track finishes, I tell the library to update playcount. Then,
the library triggers a callback to the playqueue deck telling it to
update.
This patch also finds and prints the track that causes a gstreamer
error.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
- Reimplement binary search for neater code
- Flip sort order when resetting sort if the first field is the one we
are sorting by.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The history playqueue should never change sort order, so use this flag
to prevent user changes.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
My test was done with a library size of 8040.
Before this patch, I make 21919628 calls to my "less_than" function.
With this patch, I now make 101205 calls to my "less than" function.
This comes out to a 216-X improvement. I should have done this sooner.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I don't have user-configurable sorting (yet), but for now I'm sorting by
Artist -> Year -> Track #.
I also fix a bug where the library wasn't lowercasing artist, album,
genere, and track fields when reading from file.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The history and collection playqueues are never saved to disk, so I only
care about saving when a flag is changed.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
When the count is changed or pausing finishes, I trigger this callback
to notify the UI. I also added in a line to enable pausing any time the
count is incremented.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I almost did this on the gui side, but then I remembered that this isn't
a trivial job. I chose to stick with my rule: "if something can be done
in the backend then it should be done in the backend"
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
- Check for path existing in the library already before adding again.
- Iterate over track database using <= for comparison, and not just <
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Only available when CONFIG_TESTING is enabled. Used to test clearing
the library and library playqueue for testing.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This was a bug I discovered when double clicking on paths in the
collection manager to change the path in the FileChooserWidget.
Before this patch, strings could be read as:
<string> /home/anna/Music</string>
Now, the same string will be read as:
<string>/home/anna/Music</string>
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
For some reason I was only loading the library_db, and ignoring the
others. I fix this, and send out callbacks for each track loaded.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I implemented an entire Gtk::TreeModel in this commit, plus some minor
supporting code in the library to look up playlist entries by index.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Gstreamer includes <errno.h>, which already defines several of these
symbols. I rename them to avoid namespace collisions. Perhaps a better
solution would be to use the errno.h definitions directly?
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This is used for the recently played playqueue to iterate backwards when
the previous() function is called.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I was using CONFIG_DEBUG for these, but they really should be under
CONFIG_TEST for use by the testing code ONLY.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This returns a pointer to the library :: Library structure requested.
The gui will use this to display information about each path.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I track the size of each library path for display purposes. I also had
to add in a check for if a new track already exists in the db before
tagging it so updating a library should be much faster now.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The legacy file type will only be used for importing old libraries, so
point things to this directory on construction.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
- Combine Artist and Genre struct
- Add in exceptions, rather than boolean returns
- Update the library through idle tasks
I have not implemented importing Ocarina 5.11 libraries yet.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I do not make any of the library spec changes yet, instead I update the
backend code so it compiles and still works with the changes I have made
so far.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I changed the two playlists that are supported, added in exception
handling, and removed the list() function since I will always know the
names of playlists. I also rename everything to "playlist" from
"group".
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This function will convert the provided text to lowercase. This really
isn't a filter function, but the filter already implements a lowercase
cache that should be useful.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I had been returning success / failed boolean values for various
operations. I think it's better to throw an exception in these
"exceptional" circumstances since error values can give more information
about why a function failed.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This patch implements the pause-after-N-tracks feature. I also included
various improvements to the audio code.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
- Seek(), position() and duration() functions are implemented
- There are bugs in the test program :(
- Clean up next()
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The read and write functions will be called by a higher up layer, so I
need to open the file manually in the test.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I make sure to remove empty playlists from the deck and throw an error
if there are no playable tracks on the deck.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The file will be passed in by the deck layer, since it stores multiple
files. I just fake up a file in test_2() that is used for storing the
playlist.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I scan the track database and remove files that no longer exist. I
don't yet add in new tracks found in the directories.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This patch updates the design so indexes are built upon databases using
a special IndexEntry. I also updated the tests/index/ test to match
the new system, but I have not updated filter or group tests yet.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
If the id is valid, I fill out a song structure and return true.
If the id is invalid, I return false.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This is each song's track number, play count, and anything else specific
to a single file. After updating, save all the changed databases.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Passing the TagLib :: Tag pointer is much easier and cuts down on extra
arguments to each constructor.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I don't build up a complete set of databases yet, but I do create the
Artist name database to use later.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Eventually these functions may have to become idle tasks, but for now I
write to disk whenever the library_db is changed and then read from disk
by calling the init() function.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I can add and remove root-level directories from the library database.
I do not save the database when modified, and I don't yet run an update
on all the files.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This function is used in debug mode to print the current status of the
index. I also created a print_keys() function to only list the keys.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
Rather than doing everything in tedious if blocks written in any order,
I instead resolve dependencies using a much simpler loop. At the moment
each module only depends on a single other module, so this will have to
be extended if I ever need multiple-dependency resolution.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I was using my own cpp file to remove old test data to start with a
clean slate. I've decided it's easier to just remove the files before
running tests if they exist.
I also use this patch to update the test design and add an idea for the
future.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
The idle queue is used to schedule tasks ... later. This code was
mostly adoted from a reference TDD experiment by Josh Larson
(themutatedshrimp@gmail.com). Thanks Josh!
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I only handle the "All Music", "Library" and "Banned" groups at the
moment but I'll eventually add in more features (in future versions).
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I have everything except for save() and load() written. My unittest is
fairly comprehensive and tests everything implemented so far, so with
any luck putting in save() and load() features will go quickly.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
A database may have invalid rows. If this is the case, then the next()
function needs to return the id of the next valid row. I'm aware that
this could get horribly inefficient on large DBs with many invalid rows.
I don't expect people to delete large chunks of music all at once, but a
defragment tool is on my "todo" list for a future Ocarina version.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
I've been excited about this! I think it'll be a better design than
what I had for Ocarina 5.x.
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
- Don't be verbose when removing files.
- Reverse diff order so output makes more sense.
- Only strip whitespace from the end of lines.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
- Inherit from fstream to gain access to << and >> operators.
- Make the file version accessable to the outside world.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
- Support OPEN_READ and OPEN_WRITE
- Update the design to accomidate for error checking
- Add lib/test.cpp containing basic functions that can be used for
testing
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
The class resolves the path to the ocarina directory based on the file
hint provided. NOTE: compile-debug.good and compile.good resolve paths
to my home directory. Other users will need to change the values for
the test to pass.
Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>