Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
57
Src/replicant/audio/ifc_audio_decoder_callback.h
Normal file
57
Src/replicant/audio/ifc_audio_decoder_callback.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "nx/nxuri.h"
|
||||
#include "metadata/ifc_metadata.h"
|
||||
|
||||
/* this is the class you actually use */
|
||||
class ifc_audio_decoder_callback : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_audio_decoder_callback() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_audio_decoder_callback() {}
|
||||
public:
|
||||
/* you must implement this class to use the decoder */
|
||||
class callback : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
callback() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~callback() {}
|
||||
public:
|
||||
/* frames is defined as all channels, e.g. 16bit stereo is 4 bytes per frame (2 bytes per sample)
|
||||
return NErr_Success to continue receiving callbacks
|
||||
*/
|
||||
int OnAudio(const void *buffer, size_t buffer_frames) { return AudioDecoderCallback_OnAudio(buffer, buffer_frames); }
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION=0,
|
||||
};
|
||||
private:
|
||||
virtual int WASABICALL AudioDecoderCallback_OnAudio(const void *buffer, size_t buffer_frames)=0;
|
||||
};
|
||||
|
||||
/* if possible, returns an upper bound on the number of frames used internally. this would be the maximum buffer_frames value you receive in a callback */
|
||||
int GetFrameSize(size_t *frame_size) { return AudioDecoderCallback_GetFrameSize(frame_size); }
|
||||
int GetMetadata(ifc_metadata **metadata) { return AudioDecoderCallback_GetMetadata(metadata); }
|
||||
|
||||
/* returns
|
||||
* NErr_Success on a successfully completed decode
|
||||
* NErr_Interrupted if the callback function aborted decoding
|
||||
* anything else indicates a decoding error
|
||||
*/
|
||||
int Decode(ifc_audio_decoder_callback::callback *callback) { return AudioDecoderCallback_Decode(callback); }
|
||||
|
||||
/* Like decode, but only processes one frame.
|
||||
returns NErr_EndOfFile on the last frame */
|
||||
int DecodeStep(ifc_audio_decoder_callback::callback *callback) { return AudioDecoderCallback_DecodeStep(callback); }
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION=0,
|
||||
};
|
||||
private:
|
||||
virtual int WASABICALL AudioDecoderCallback_Decode(ifc_audio_decoder_callback::callback *callback)=0;
|
||||
virtual int WASABICALL AudioDecoderCallback_DecodeStep(ifc_audio_decoder_callback::callback *callback)=0;
|
||||
virtual int WASABICALL AudioDecoderCallback_GetFrameSize(size_t *frame_size)=0;
|
||||
virtual int WASABICALL AudioDecoderCallback_GetMetadata(ifc_metadata **metadata)=0;
|
||||
};
|
23
Src/replicant/audio/ifc_audio_decoder_packet.h
Normal file
23
Src/replicant/audio/ifc_audio_decoder_packet.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "nx/nxuri.h"
|
||||
#include "metadata/ifc_metadata.h"
|
||||
|
||||
class ifc_audio_decoder_packet : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_audio_decoder_packet() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_audio_decoder_packet() {}
|
||||
public:
|
||||
|
||||
int GetMetadata(ifc_metadata **metadata) { return AudioDecoderPacket_GetMetadata(metadata); }
|
||||
int Decode(void **out_packet, size_t *frames_available) { return AudioDecoderPacket_Decode(out_packet, frames_available); }
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION=0,
|
||||
};
|
||||
private:
|
||||
virtual int WASABICALL AudioDecoderPacket_GetMetadata(ifc_metadata **metadata)=0;
|
||||
virtual int WASABICALL AudioDecoderPacket_Decode(void **out_packet, size_t *frames_available)=0;
|
||||
};
|
34
Src/replicant/audio/ifc_audio_decoder_pull.h
Normal file
34
Src/replicant/audio/ifc_audio_decoder_pull.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "nx/nxuri.h"
|
||||
#include "metadata/ifc_metadata.h"
|
||||
|
||||
class ifc_audio_decoder_pull : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_audio_decoder_pull() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_audio_decoder_pull() {}
|
||||
public:
|
||||
|
||||
/* if possible, returns an upper bound on the number of frames used internally. pull decoders are most optimal if you use this to malloc your buffer */
|
||||
int GetFrameSize(size_t *frame_size) { return AudioDecoderPull_GetFrameSize(frame_size); }
|
||||
int GetMetadata(ifc_metadata **metadata) { return AudioDecoderPull_GetMetadata(metadata); }
|
||||
|
||||
/* returns
|
||||
* NErr_EndOfFile when decode is done (frames_written will be valid, but probably 0)
|
||||
* NErr_Success on successful decode, but not end-of-file (frames_written will be valid)
|
||||
* anything else indicates a decode error */
|
||||
int Decode(void *buffer, size_t buffer_frames, size_t *frames_written) { return AudioDecoderPull_Decode(buffer, buffer_frames, frames_written); }
|
||||
/* You need to call Close() when you are done (even if you Release) because some implementations might have ifc_metadata being the same object */
|
||||
void Close() { AudioDecoderPull_Close(); }
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION=0,
|
||||
};
|
||||
private:
|
||||
virtual int WASABICALL AudioDecoderPull_GetFrameSize(size_t *frame_size)=0;
|
||||
virtual int WASABICALL AudioDecoderPull_GetMetadata(ifc_metadata **metadata)=0;
|
||||
virtual int WASABICALL AudioDecoderPull_Decode(void *buffer, size_t buffer_frames, size_t *frames_written)=0;
|
||||
virtual void WASABICALL AudioDecoderPull_Close()=0;
|
||||
};
|
76
Src/replicant/audio/ifc_audioout.h
Normal file
76
Src/replicant/audio/ifc_audioout.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
#include "foundation/error.h"
|
||||
#include "audio/parameters.h"
|
||||
|
||||
|
||||
class NOVTABLE ifc_audioout : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_audioout() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_audioout() {}
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
CHANNEL_LAYOUT_MICROSOFT = 0x0, // microsoft channel order - http://www.microsoft.com/whdc/device/audio/multichaud.mspx#E4C
|
||||
CHANNEL_LAYOUT_MPEG = 0x1,
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
EXTENDED_FLAG_APPLY_GAIN=0x1, /* apply the gain value specified in Parameters::gain */
|
||||
EXTENDED_FLAG_REPLAYGAIN=0x2, /* pass if you tried to figure out ReplayGain on your own. otherwise the Audio Output object will apply the default gain */
|
||||
EXTENDED_FLAG_GAIN_MASK=EXTENDED_FLAG_APPLY_GAIN|EXTENDED_FLAG_REPLAYGAIN, /* a mask to check whether or not the gain value is valid */
|
||||
/* so that you can check if a flag was set that you don't understand */
|
||||
EXTENDED_FLAG_VALID_MASK=EXTENDED_FLAG_APPLY_GAIN|EXTENDED_FLAG_REPLAYGAIN,
|
||||
};
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
size_t sizeof_parameters;
|
||||
nsaudio::Parameters audio;
|
||||
/* anything after this needs sizeof_parameters to be large enough
|
||||
AND a flag set in extended_fields_flags
|
||||
if there's no flag for the field, it's because a default value of 0 can be assumed */
|
||||
unsigned int extended_fields_flags; // set these if you use any of the following fields. see comment above
|
||||
double gain; // additional gain specified by client. usually used for replaygain (so it can be combined with EQ pre-amp or float/pcm conversion)
|
||||
size_t frames_trim_start; // number of frames to trim from the start
|
||||
size_t frames_trim_end; // number of frames to trim from the start
|
||||
};
|
||||
|
||||
int Output(const void *data, size_t data_size) { return AudioOutput_Output(data, data_size); }
|
||||
// returns number of bytes that you can write
|
||||
size_t CanWrite() { return AudioOutput_CanWrite(); }
|
||||
void Flush(double seconds) { AudioOutput_Flush(seconds); }
|
||||
void Pause(int state) { AudioOutput_Pause(state); }
|
||||
|
||||
/* called by the input plugin when no more output will be sent */
|
||||
void Done() { AudioOutput_Done(); }
|
||||
/* called by the input plugin when playback was forcefully stopped */
|
||||
void Stop() { AudioOutput_Stop(); }
|
||||
|
||||
/* returns the latency in seconds (how many seconds until samples you're about to write show up at the audio output */
|
||||
double Latency() { return AudioOutput_Latency(); }
|
||||
|
||||
/* only valid after a call to Done(). Returns NErr_True if there is still data in the buffer, NErr_False otherwise */
|
||||
int Playing() { return AudioOutput_Playing(); }
|
||||
|
||||
protected:
|
||||
virtual int WASABICALL AudioOutput_Output(const void *data, size_t data_size)=0;
|
||||
virtual size_t WASABICALL AudioOutput_CanWrite()=0; // returns number of bytes that you can write
|
||||
virtual void WASABICALL AudioOutput_Flush(double seconds)=0;
|
||||
virtual void WASABICALL AudioOutput_Pause(int state)=0;
|
||||
|
||||
/* called by the input plugin when no more output will be sent */
|
||||
virtual void WASABICALL AudioOutput_Done()=0;
|
||||
/* called by the input plugin when playback was forcefully stopped */
|
||||
virtual void WASABICALL AudioOutput_Stop()=0;
|
||||
virtual double WASABICALL AudioOutput_Latency()=0;
|
||||
virtual int WASABICALL AudioOutput_Playing()=0;
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION,
|
||||
};
|
||||
};
|
27
Src/replicant/audio/ifc_equalizer.h
Normal file
27
Src/replicant/audio/ifc_equalizer.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include "foundation/dispatch.h"
|
||||
|
||||
class ifc_equalizer : public Wasabi2::Dispatchable
|
||||
{
|
||||
protected:
|
||||
ifc_equalizer() : Dispatchable(DISPATCHABLE_VERSION) {}
|
||||
~ifc_equalizer() {}
|
||||
|
||||
public:
|
||||
|
||||
int SetPreamp(double dB) { return Equalizer_SetPreamp(dB); }
|
||||
int SetBand(unsigned int band, double dB) { return Equalizer_SetBand(band, dB); }
|
||||
int Enable() { return Equalizer_Enable(); }
|
||||
int Disable() { return Equalizer_Disable(); }
|
||||
private:
|
||||
virtual int WASABICALL Equalizer_SetPreamp(double dB)=0;
|
||||
virtual int WASABICALL Equalizer_SetBand(unsigned int band, double dB)=0;
|
||||
virtual int WASABICALL Equalizer_Enable()=0;
|
||||
virtual int WASABICALL Equalizer_Disable()=0;
|
||||
|
||||
enum
|
||||
{
|
||||
DISPATCHABLE_VERSION,
|
||||
};
|
||||
|
||||
};
|
47
Src/replicant/audio/parameters.h
Normal file
47
Src/replicant/audio/parameters.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
#include "foundation/types.h"
|
||||
#include "foundation/guid.h"
|
||||
|
||||
|
||||
namespace nsaudio
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* when this is set, the const void * passed to AudioOutput_Output is assumed to be an array of channels,
|
||||
e.g. (format_type == nsaudio_type_float && (format_flags & FORMAT_FLAG_NONINTERLEAVED) && number_of_channels == 2)
|
||||
means that you pass a float *[2] to AudioOutput_Output
|
||||
*/
|
||||
FORMAT_FLAG_INTERLEAVED=0x1,
|
||||
FORMAT_FLAG_NONINTERLEAVED=0x2,
|
||||
FORMAT_FLAG_NATIVE_ENDIAN=0x4,
|
||||
FORMAT_FLAG_LITTLE_ENDIAN=0x8, /* audio is SPECIFICALLY little endian (as opposed to native endian on little-endian machines) */
|
||||
FORMAT_FLAG_BIG_ENDIAN=0x10, /* audio is SPECIFICALLY big endian (as opposed to native endian on big-endian machines) */
|
||||
FORMAT_FLAG_SIGNED=0x20, /* e.g. 8 bit PCM is typically unsigned (0-255) */
|
||||
FORMAT_FLAG_UNSIGNED=0x40, /* e.g. 8 bit PCM is typically unsigned (0-255) */
|
||||
|
||||
/* so that you can check if a flag was set that you don't understand */
|
||||
FORMAT_FLAG_VALID_INTERLEAVE = FORMAT_FLAG_INTERLEAVED|FORMAT_FLAG_NONINTERLEAVED,
|
||||
FORMAT_FLAG_VALID_ENDIAN = FORMAT_FLAG_NATIVE_ENDIAN|FORMAT_FLAG_LITTLE_ENDIAN|FORMAT_FLAG_BIG_ENDIAN,
|
||||
FORMAT_FLAG_VALID_SIGNED=FORMAT_FLAG_SIGNED|FORMAT_FLAG_UNSIGNED,
|
||||
FORMAT_FLAG_VALID_MASK=FORMAT_FLAG_VALID_INTERLEAVE|FORMAT_FLAG_VALID_ENDIAN|FORMAT_FLAG_VALID_SIGNED,
|
||||
};
|
||||
|
||||
// {4B80932C-E55F-4969-91EA-772584ABEDC2}
|
||||
static const GUID format_type_pcm =
|
||||
{ 0x4b80932c, 0xe55f, 0x4969, { 0x91, 0xea, 0x77, 0x25, 0x84, 0xab, 0xed, 0xc2 } };
|
||||
|
||||
// {6D47717F-A383-4CF8-BB1E-72254BE3F9DC}
|
||||
static const GUID format_type_float =
|
||||
{ 0x6d47717f, 0xa383, 0x4cf8, { 0xbb, 0x1e, 0x72, 0x25, 0x4b, 0xe3, 0xf9, 0xdc } };
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
double sample_rate;
|
||||
GUID format_type; // PCM, floating point, SPDIF pass-thru, etc.
|
||||
unsigned int format_flags; // endian, interleaved, signed
|
||||
unsigned int bytes_per_sample; // e.g. 4 for 20bit in a 32bit container
|
||||
unsigned int bits_per_sample; // number of valid bits within the sample
|
||||
unsigned int number_of_channels;
|
||||
unsigned int channel_layout;
|
||||
};
|
||||
};
|
44
Src/replicant/audio/types.h
Normal file
44
Src/replicant/audio/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