audio: Update audio design

This patch updates the design to something that makes a bit more sense,
and works with the new audio drivers.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2014-05-31 21:06:48 -04:00
parent 1cacbf51e7
commit 6f3fcaae6e
1 changed files with 39 additions and 79 deletions

118
DESIGN
View File

@ -1371,115 +1371,75 @@ Audio Driver:
Audio: (lib/audio.cpp)
This file will introduce an "audio" namespace containing all of the
functions interacting with gstreamer. This will create a wrapper
namespace that will be easier to work with than using raw gstreamer
functions.
The audio layer is meant to be an interface used by the front end to
control most features of the backend library. This means implementing
next track, previous track, and so on here.
Audio:
The audio layer uses the configured driver to control audio playback.
Gstreamer options passed to audio :: init() can be found by running
`gst-inspect-1.0 --help-gst` on the command line.
- Internal:
Set up a message bus to look for end-of-stream and error messages so
the next song can be played. This function should call the play
function after loading a track and after checking the "pause after N"
count.
- File:
File cur_track("cur_track");
The audio layer will also create an internal playqueue for tracking
recently played songs.
File << current_track->id << endl;
- State:
The audio layer will store the current trackid to disk, and then save
the playqueue deck.
File << current_track << endl
deck.write(File);
- Seconds -> Nanoseconds conversion:
#define O_SECOND 1000000000
- API:
void audio :: init(argc, argv);
Initialize the gstreamer layer and reload the track that was
last loaded before shutdown. Gstreamer is supposed to remove
options from the argv array as they are processed, so pass
pointers to argc and argv to this function.
Read in the state file.
void audio :: quit();
Clean up memory allocated by gstreamer.
Write out the state file.
void audio :: init(int *argc, char ***argv);
Initialize the audio driver through argc and argv. Read in
the current track file and load the track.
void audio :: play();
void audio :: pause();
Change the gstreamer state to either GST_STATE_PLAYING or
GST_STATE_PAUSED. Do nothing if there is not a track loaded
in the pipeline. Throw -EAUDIO if there is an error changing
state.
void audio :: seek_to(long pos);
Call the corresponding function from the audio driver, but only
if a track is loaded.
void audio :: seek_to(long);
Seek to a position X nanoseconds into the track. Throw -EAUDIO
if there is an error seeking to the requested position. Do
nothing if there is not a track loaded in the pipeline.
long audio :: position();
long audio :: duration();
Call the corresponding function from the audio driver. Return
0 if no track is currently loaded.
Seconds can be converted to nanoseconds by multiplying with
GST_SECOND.
std::string audio :: position_str();
Return the current audio position in string form.
Return an empty string if there is no current track.
void audio :: stop();
pause()
seek_to(0)
void audio :: next();
Call the deck :: next() function to get the next trackid,
and load that file into the gstreamer pipeline. Do not change
the state of the pipeline (if nothing is playing yet, don't
call play()). Throw -EEXIST if there is no track to load
into the pipeline.
Call the deck :: next() function to get the next track that
should be played and use the audio driver to load the track.
When a track is loaded:
Is it already in the recently played playqueue?
If yes, remove it from the playqueue.
Add to the front of the recently played playqueue.
Reset the current pointer in the playqueue to 0.
Save that track's ID to the cur_track file.
Write out the state file.
void audio :: prev();
Call the deck :: previous() function to find a new track to
play and use the audio driver to load the track.
void audio :: previous();
Call the playlist :: previous() function to iterate backwards
through the recently played playqueue. Load the returned trackid
without changing the pipeline state.
Save that track's ID to the cur_track file.
trackid audio :: current_trackid();
Return the trackid of the currently playing song. If no track
is loaded throw -EEXIST;
Track *audio :: current_track();
Return the currently playing Track.
Return NULL if there is no current track.
unsigned int audio :: position();
Return the number of seconds that the song has played.
void audio :: load_track(Track *track);
Load the requested track.
unsigned int audio :: duration();
Return the duration of the current song in seconds.
Save that track's ID to the cur_track file.
void audio :: pause_after(bool enabled, unsigned int N);
Pause after N tracks. The first parameter is a bool
representing if this feature is enabled or not (true == enabled,
false == disabled).
The count will only be decremented when an end-of-stream message
is received by the gstreamer pipeline, and not when calling
next().
If enabled == true:
Configure Ocarina to pause playback after N tracks
have been played.
If enabled == false:
Do not automatically pause.
bool audio :: pause_enabled();
Return true if pausing is enabled, and false if pausing is
disabled.
unsigned int audio :: pause_count();
Return the number of tracks that will be played before
playback pauses.
Use these functions to access the current "pause after N" state.