Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
71
Src/replicant/player/ifc_playback.h
Normal file
71
Src/replicant/player/ifc_playback.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "foundation/error.h"
|
||||
#include "types.h"
|
||||
#include "svc_output.h"
|
||||
#include "ifc_playback_parameters.h"
|
||||
|
||||
/* Note that since a typical ifc_playback implementation
|
||||
is running on another thread, most functions will always succeed (except for out of memory or thread creation problems)
|
||||
but might report an error later to the ifc_player object that was passed
|
||||
when creating the playback object */
|
||||
|
||||
class NOVTABLE ifc_playback : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_playback() : Dispatchable(NUM_DISPATCH_CODES) {}
|
||||
~ifc_playback() {}
|
||||
public:
|
||||
/* optionally call Cue before calling Play to set the start and end positions
|
||||
in a cuesheet situation, these will might also get called after
|
||||
you indicate that cue end position has been reached */
|
||||
int Cue(Agave_PositionType position_type, Agave_Position start, Agave_Position end) { return Playback_Cue(position_type, start, end); }
|
||||
// start only version of Cue
|
||||
int CueStart(Agave_PositionType position_type, Agave_Position start) { return Playback_CueStart(position_type, start); }
|
||||
|
||||
// begins playback.
|
||||
int Play(svc_output *output, ifc_playback_parameters *secondary_parameters) { return Playback_Play(output, secondary_parameters); }
|
||||
|
||||
int SeekSeconds(double seconds) { return Playback_SeekSeconds(seconds); }
|
||||
|
||||
// called on user-initiated stop. not called if the playback object indiciated a stop (e.g. EOF)
|
||||
int Stop() { return Playback_Stop(); }
|
||||
|
||||
int Pause() { return Playback_Pause(); }
|
||||
int Unpause() { return Playback_Unpause(); }
|
||||
|
||||
/* called to shut things down.
|
||||
note that if your playback object is in a 'stopped' state,
|
||||
it should be prepared to receive Cue/Play call until Close() is called */
|
||||
int Close() { return Playback_Close(); }
|
||||
|
||||
/* most of the time, you'll pass SetVolume and SetPan on to the output object
|
||||
but some special-use playback objects (e.g. analog CD playback) might have to implement this */
|
||||
// 0 to 1.0
|
||||
int SetVolume(float volume) { return Playback_SetVolume(volume); }
|
||||
// -1.0 to 1.0
|
||||
int SetPan(float pan) { return Playback_SetPan(pan); }
|
||||
|
||||
/* most of the time, you'll ignore SetEQ
|
||||
but some special-use playback objects (e.g. analog CD playback) might have to implement this */
|
||||
int SetEQ(float preamp, int num_bands, float *bands) { return Playback_SetEQ(preamp, num_bands, bands); }
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_DISPATCH_CODES,
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual int WASABICALL Playback_Cue(Agave_PositionType position_type, Agave_Position start, Agave_Position end) { return NErr_NotImplemented; }
|
||||
virtual int WASABICALL Playback_CueStart(Agave_PositionType position_type, Agave_Position start) { return NErr_NotImplemented; }
|
||||
virtual int WASABICALL Playback_Play(svc_output *output, ifc_playback_parameters *secondary_parameters)=0;
|
||||
virtual int WASABICALL Playback_SeekSeconds(double seconds)=0;
|
||||
virtual int WASABICALL Playback_Stop()=0;
|
||||
virtual int WASABICALL Playback_Pause()=0;
|
||||
virtual int WASABICALL Playback_Unpause()=0;
|
||||
virtual int WASABICALL Playback_Close()=0;
|
||||
virtual int WASABICALL Playback_SetVolume(float volume) { return NErr_NotImplemented; }
|
||||
virtual int WASABICALL Playback_SetPan(float pan) { return NErr_NotImplemented; }
|
||||
virtual int WASABICALL Playback_SetEQ(float preamp, int num_bands, float *bands) { return NErr_NotImplemented; }
|
||||
};
|
||||
|
20
Src/replicant/player/ifc_playback_parameters.h
Normal file
20
Src/replicant/player/ifc_playback_parameters.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
|
||||
/* ifc_output_parameters abstracts output parameters that are passed to an input plugin
|
||||
it is things that an input plugin wouldn't necessary know about
|
||||
for example, is a playback object is being used for track preview,
|
||||
it might be configured to play out of a different output device
|
||||
and there's no way an input plugin would know that
|
||||
*/
|
||||
class NOVTABLE ifc_playback_parameters : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_playback_parameters() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_playback_parameters() {}
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION=0,
|
||||
};
|
||||
};
|
93
Src/replicant/player/ifc_player.h
Normal file
93
Src/replicant/player/ifc_player.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "foundation/error.h"
|
||||
#include "foundation/types.h"
|
||||
#include "metadata/ifc_metadata.h"
|
||||
#include "audio/ifc_equalizer.h"
|
||||
#include "nx/nxuri.h"
|
||||
|
||||
/* implemented by Winamp (or whatever application)
|
||||
your ifc_playback implementation should call this with events
|
||||
|
||||
TODO: benski> should we require the ifc_playback object to get passed in to each function?
|
||||
*/
|
||||
|
||||
class NOVTABLE ifc_player : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_player() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_player() {}
|
||||
public:
|
||||
|
||||
/* When your playback object has read enough of the file to provide metadata
|
||||
it should call this method.
|
||||
It will be called for both song metadata (artist, album, etc) and codec metadata (bitrate, samplerate, etc).
|
||||
so make sure you can provide both - this might mean you have to wait until the first frame is decoded.
|
||||
The player object will add a reference in the function, and release whenever it is no longer needed (usually on start of next track)
|
||||
*/
|
||||
void SetMetadata(ifc_metadata *metadata) { Player_SetMetadata(metadata); }
|
||||
|
||||
/* Call this just once (with timestamp=0) for CBR files or update continuously for VBR
|
||||
bitrate should be in bits per second, e.g. 128000 (not 128!)
|
||||
*/
|
||||
void SetBitrate(uint64_t bitrate, double timestamp) { Player_SetBitrate(bitrate, timestamp); }
|
||||
|
||||
/* Playback plugin should call this when it knows the length
|
||||
can be updated if necessary (e.g. for VBR files w/o header)
|
||||
If this is not called, it assumed to be a stream (radio)
|
||||
*/
|
||||
void SetLength(double length) { Player_SetLength(length); }
|
||||
|
||||
/* Output plugin should call this every once in a while,
|
||||
if your input plugin does its own audio output (e.g. analog CD) you should call this yourself
|
||||
*/
|
||||
void SetPosition(double timestamp) { Player_SetPosition(timestamp); }
|
||||
|
||||
void OnLoaded(nx_uri_t filename) { Player_OnLoaded(filename); }
|
||||
/* Input plugin should call this when playback ends at the end of the file
|
||||
Do not call if playback stopped because of an error */
|
||||
void OnEndOfFile() { Player_OnEndOfFile(); }
|
||||
|
||||
void OnError(NError code) { Player_OnError(code); }
|
||||
|
||||
void OnStopped() { Player_OnStopped(); }
|
||||
|
||||
void SetEqualizer(ifc_equalizer *equalizer) { return Player_SetEqualizer(equalizer); }
|
||||
|
||||
/* percent is 0-100. setting to 100 implies that buffering has finished */
|
||||
void SetBufferStatus(int percent) { return Player_SetBufferStatus(percent); }
|
||||
|
||||
void OnSeekComplete(int error_code, double new_position) { return Player_OnSeekComplete(error_code, new_position); }
|
||||
|
||||
/* seekable is 0 (false) or 1 (true) */
|
||||
void SetSeekable(int seekable) { return Player_SetSeekable(seekable); }
|
||||
|
||||
void AsynchronousFunctionCall(void (*function)(void *, void *, double), void *param1, void *param2, double real_param) { Player_AsynchronousFunctionCall(function, param1, param2, real_param); }
|
||||
|
||||
/* Call this after you've successfully opened and parsed the playback file, and are attempting to start playback */
|
||||
void OnReady() { Player_OnReady(); };
|
||||
|
||||
/* Call this after EndOfFile() when either 1) You process an ifc_playback::Close() call or 2) ifc_audioout::IsPlaying() returns NErr_False while waiting for a Close() call */
|
||||
void OnClosed() { Player_OnClosed(); };
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION,
|
||||
};
|
||||
protected:
|
||||
virtual void WASABICALL Player_SetMetadata(ifc_metadata *metadata) = 0;
|
||||
virtual void WASABICALL Player_SetBitrate(uint64_t bitrate, double timestamp) = 0;
|
||||
virtual void WASABICALL Player_SetLength(double length) = 0;
|
||||
virtual void WASABICALL Player_SetPosition(double timestamp) = 0;
|
||||
virtual void WASABICALL Player_OnLoaded(nx_uri_t filename) = 0;
|
||||
virtual void WASABICALL Player_OnEndOfFile() = 0;
|
||||
virtual void WASABICALL Player_OnError(NError code) = 0;
|
||||
virtual void WASABICALL Player_OnStopped()=0;
|
||||
virtual void WASABICALL Player_SetEqualizer(ifc_equalizer *equalizer)=0;
|
||||
virtual void WASABICALL Player_SetBufferStatus(int percent)=0;
|
||||
virtual void WASABICALL Player_OnSeekComplete(int error_code, double new_position)=0;
|
||||
virtual void WASABICALL Player_SetSeekable(int seekable)=0;
|
||||
virtual void WASABICALL Player_AsynchronousFunctionCall(void (*function)(void *, void *, double), void *param1, void *param2, double real_param)=0;
|
||||
virtual void WASABICALL Player_OnReady()=0;
|
||||
virtual void WASABICALL Player_OnClosed()=0;
|
||||
};
|
40
Src/replicant/player/svc_output.h
Normal file
40
Src/replicant/player/svc_output.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "audio/ifc_audioout.h"
|
||||
#include "player/ifc_playback_parameters.h"
|
||||
|
||||
class ifc_player;
|
||||
|
||||
// {FB5E9AE3-E033-407C-942B-6C1BFAF52A5C}
|
||||
static const GUID output_service_guid =
|
||||
{ 0xfb5e9ae3, 0xe033, 0x407c, { 0x94, 0x2b, 0x6c, 0x1b, 0xfa, 0xf5, 0x2a, 0x5c } };
|
||||
|
||||
class NOVTABLE svc_output : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
svc_output() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~svc_output() {}
|
||||
public:
|
||||
static GUID GetServiceType() { return output_service_guid; }
|
||||
/* ----- Audio Output ----- */
|
||||
// Opens winamp2-style Audio Output - good for audio-only streams (buffered, push, output-plugin-defined buffersize)
|
||||
int AudioOpen(const ifc_audioout::Parameters *format, ifc_player *player, ifc_playback_parameters *secondary_parameters, ifc_audioout **out_output) { return OutputService_AudioOpen(format, player, secondary_parameters, out_output); }
|
||||
|
||||
/* ----- Video Output ----- */
|
||||
int VideoOpen();
|
||||
|
||||
/* ----- Text Output ----- */
|
||||
// Opens a subtitle stream
|
||||
int TextOpenSubtitle();
|
||||
// Opens a video info text stream
|
||||
int TextOpenInfo();
|
||||
// Opens a lyrics text stream
|
||||
int TextOpenLyrics();
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION,
|
||||
};
|
||||
protected:
|
||||
virtual int WASABICALL OutputService_AudioOpen(const ifc_audioout::Parameters *format, ifc_player *player, ifc_playback_parameters *secondary_parameters, ifc_audioout **out_output) = 0;
|
||||
};
|
44
Src/replicant/player/types.h
Normal file
44
Src/replicant/player/types.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include "foundation/types.h"
|
||||
|
||||
enum Agave_PositionType
|
||||
{
|
||||
AGAVE_PLAYPOSITION_100NANOECONDS = 0,
|
||||
AGAVE_PLAYPOSITION_MILLISECONDS = 1,
|
||||
AGAVE_PLAYPOSITION_SECONDS = 2,
|
||||
AGAVE_PLAYPOSITION_HMSF= 3,
|
||||
AGAVE_PLAYPOSITION_SAMPLE_FRAMES = 4,
|
||||
AGAVE_PLAYPOSITION_BYTES = 5,
|
||||
AGAVE_PLAYPOSITION_PACKETS = 6,
|
||||
};
|
||||
|
||||
struct Agave_HMSF
|
||||
{
|
||||
uint8_t hours;
|
||||
uint8_t minutes;
|
||||
uint8_t seconds;
|
||||
uint8_t frames;
|
||||
};
|
||||
|
||||
union Agave_Position
|
||||
{
|
||||
uint64_t nanoseconds100; // in increments of 100 nanoseconds (microsoft style)
|
||||
uint64_t milliseconds;
|
||||
double seconds;
|
||||
Agave_HMSF hmsf;
|
||||
uint64_t sample_frames;
|
||||
uint64_t bytes;
|
||||
uint64_t packets;
|
||||
};
|
||||
|
||||
struct Agave_Seek
|
||||
{
|
||||
Agave_PositionType position_type;
|
||||
Agave_Position position;
|
||||
};
|
||||
|
||||
static void Agave_Seek_SetBytes(Agave_Seek *seek, uint64_t bytes)
|
||||
{
|
||||
seek->position_type=AGAVE_PLAYPOSITION_BYTES;
|
||||
seek->position.bytes = bytes;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue