Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View 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;
};

View 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;
};

View 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;
};

View 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,
};
};

View 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,
};
};

View 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;
};
};

View 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;
}