diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Agave/DecodeFile | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Agave/DecodeFile')
-rw-r--r-- | Src/Agave/DecodeFile/api_decodefile.h | 104 | ||||
-rw-r--r-- | Src/Agave/DecodeFile/ifc_audiostream.h | 65 | ||||
-rw-r--r-- | Src/Agave/DecodeFile/ifc_raw_media_reader.h | 26 | ||||
-rw-r--r-- | Src/Agave/DecodeFile/svc_raw_media_reader.h | 32 |
4 files changed, 227 insertions, 0 deletions
diff --git a/Src/Agave/DecodeFile/api_decodefile.h b/Src/Agave/DecodeFile/api_decodefile.h new file mode 100644 index 00000000..c2b3c46a --- /dev/null +++ b/Src/Agave/DecodeFile/api_decodefile.h @@ -0,0 +1,104 @@ +#ifndef NULLSOFT_AGAVE_API_DECODEFILE_H +#define NULLSOFT_AGAVE_API_DECODEFILE_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include "ifc_audiostream.h" + +enum +{ + API_DECODEFILE_SUCCESS = 0, + API_DECODEFILE_FAILURE = 1, + + API_DECODEFILE_UNSUPPORTED = 2, // type is unsupported + API_DECODEFILE_NO_INTERFACE = 3, // type is supported, but plugin does provide any interfaces for direct decoding + API_DECODEFILE_WINAMP_PRO = 4, // user has to pay $$$ to do this + API_DECODEFILE_NO_RIGHTS = 5, // user is not allowed to decode this file (e.g. DRM) + API_DECODEFILE_BAD_RESAMPLE = 6, // Winamp is unable to resample this file to CDDA format (stereo 16bit 44.1kHz) + API_DECODEFILE_FAIL_NO_WARN = 7, // we have already informed the user of an issue so do not show again e.g. CD playing so cannot also do a rip +}; + +enum +{ + AUDIOPARAMETERS_FLOAT = 1, + AUDIOPARAMETERS_MAXCHANNELS = 2, // set this if channels is meant to define an upper limit + // (e.g. setting channels=2 and flags |= AUDIOPARAMETERS_MAXCHANNELS means 1 or 2 channels is OK, but not more) + AUDIOPARAMETERS_MAXSAMPLERATE = 4, // like AUDIOPARAMETERS_MAXCHANNELS but for sample rate + AUDIOPARAMETERS_NON_INTERLEAVED = 8, // audio data is stored as separate buffers per channel. not currently implemented +}; + +struct AudioParameters +{ +public: + AudioParameters() : bitsPerSample(0), channels(0), sampleRate(0), sampleRateReal(0.f), flags(0), sizeBytes((size_t) - 1), errorCode(API_DECODEFILE_SUCCESS) + {} + uint32_t bitsPerSample; + uint32_t channels; + uint32_t sampleRate; + float sampleRateReal; // yes this is duplicate. + int flags; + size_t sizeBytes; // total size of decoded file, (size_t)-1 means don't know + int errorCode; +}; + +class api_decodefile : public Dispatchable +{ +public: + /* OpenAudioBackground gives you back an ifc_audiostream that you can use to get decompressed bits + * if it returns 0, check parameters->errorCode for the failure reason + * fill parameters with desired values (0 if you don't care) + * the decoder will _do its best_ to satisfy your passed-in audio parameters + * but this API does not guarantee them, so be sure to check the parameters struct after the function returns + * it's **UP TO YOU** to do any necessary conversion (sample rate, channels, bits-per-sample) if the decoder can't do it + */ + ifc_audiostream *OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters); + /* OpenAudio is the same as OpenAudioBackground + * but, it will use the input plugin system to decode if necessary + * so it's best to use this in a separate winamp.exe + * to be honest, it was designed for internal use in the CD burner + * so it's best not to use this one at all + */ + ifc_audiostream *OpenAudio(const wchar_t *filename, AudioParameters *parameters); + + void CloseAudio(ifc_audiostream *audioStream); + /* verifies that a decoder exists to decompress this filename. + this is not a guarantee that the file is openable, just that it can be matched to a decoder */ + bool DecoderExists(const wchar_t *filename); + +public: + DISPATCH_CODES + { + API_DECODEFILE_OPENAUDIO = 10, + API_DECODEFILE_OPENAUDIO2 = 11, + API_DECODEFILE_CLOSEAUDIO = 20, + API_DECODEFILE_DECODEREXISTS = 30, + }; +}; + +inline ifc_audiostream *api_decodefile::OpenAudio(const wchar_t *filename, AudioParameters *parameters) +{ + return _call(API_DECODEFILE_OPENAUDIO, (ifc_audiostream *)0, filename, parameters); +} + +inline ifc_audiostream *api_decodefile::OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters) +{ + return _call(API_DECODEFILE_OPENAUDIO2, (ifc_audiostream *)0, filename, parameters); +} + +inline void api_decodefile::CloseAudio(ifc_audiostream *audioStream) +{ + _voidcall(API_DECODEFILE_CLOSEAUDIO, audioStream); +} + +inline bool api_decodefile::DecoderExists(const wchar_t *filename) +{ + return _call(API_DECODEFILE_DECODEREXISTS, (bool)true, filename); // we default to true so that an old implementation doesn't break completely +} + +// {9B4188F5-4295-48ab-B50C-F2B0BB56D242} +static const GUID decodeFileGUID = +{ + 0x9b4188f5, 0x4295, 0x48ab, { 0xb5, 0xc, 0xf2, 0xb0, 0xbb, 0x56, 0xd2, 0x42 } +}; + +#endif
\ No newline at end of file diff --git a/Src/Agave/DecodeFile/ifc_audiostream.h b/Src/Agave/DecodeFile/ifc_audiostream.h new file mode 100644 index 00000000..586d704c --- /dev/null +++ b/Src/Agave/DecodeFile/ifc_audiostream.h @@ -0,0 +1,65 @@ +#ifndef NULLSOFT_AGAVE_IFC_AUDIOSTREAM_H +#define NULLSOFT_AGAVE_IFC_AUDIOSTREAM_H + +#include <bfc/dispatch.h> + +class ifc_audiostream : public Dispatchable +{ +protected: + ifc_audiostream() {} + ~ifc_audiostream() {} +public: + /* returns number of bytes written to buffer. + * a return value of 0 means EOF + */ + size_t ReadAudio(void *buffer, size_t sizeBytes); + + size_t ReadAudio(void *buffer, size_t, int *killswitch, int *errorCode); + /* Seeks to a point in the stream in milliseconds + * returns TRUE if successful, FALSE otherwise + */ + int SeekToTimeMs(int millisecs); + + /* returns 1 if this stream is seekable using SeekToTime, 0 otherwise + */ + int CanSeek(); +public: + DISPATCH_CODES + { + IFC_AUDIOSTREAM_READAUDIO = 10, + IFC_AUDIOSTREAM_READAUDIO2 = 11, + IFC_AUDIOSTREAM_SEEKTOTIMEMS = 20, + IFC_AUDIOSTREAM_CANSEEK = 30, + }; +}; + +inline size_t ifc_audiostream::ReadAudio(void *buffer, size_t sizeBytes) +{ + return _call(IFC_AUDIOSTREAM_READAUDIO, (size_t)0, buffer, sizeBytes); +} + +inline size_t ifc_audiostream::ReadAudio(void *buffer, size_t sizeBytes, int *killswitch, int *errorCode) +{ + void *params[4] = { &buffer, &sizeBytes, &killswitch, &errorCode}; + size_t retval; + + if (_dispatch(IFC_AUDIOSTREAM_READAUDIO2, &retval, params, 4)) + return retval; + else + { + *errorCode=0; + return ReadAudio(buffer, sizeBytes); + } +} + +inline int ifc_audiostream::SeekToTimeMs(int millisecs) +{ + return _call(IFC_AUDIOSTREAM_SEEKTOTIMEMS, (int)0, millisecs); +} + +inline int ifc_audiostream::CanSeek() +{ + return _call(IFC_AUDIOSTREAM_CANSEEK, (int)0); +} + +#endif diff --git a/Src/Agave/DecodeFile/ifc_raw_media_reader.h b/Src/Agave/DecodeFile/ifc_raw_media_reader.h new file mode 100644 index 00000000..cc86f1a9 --- /dev/null +++ b/Src/Agave/DecodeFile/ifc_raw_media_reader.h @@ -0,0 +1,26 @@ +#pragma once + +#include <bfc/dispatch.h> +#include <bfc/error.h> + +class ifc_raw_media_reader : public Dispatchable +{ +protected: + ifc_raw_media_reader() {} + ~ifc_raw_media_reader() {} + +public: + int Read(void *buffer, size_t buffer_size, size_t *bytes_read); + /* TODO: we'll probably need stuff in here like EndOfFile, determining a good buffer size, etc */ + + DISPATCH_CODES + { + RAW_READ + }; +}; + +inline int ifc_raw_media_reader::Read(void *buffer, size_t buffer_size, size_t *bytes_read) +{ + return _call(RAW_READ, (int)NErr_NotImplemented, buffer, buffer_size, bytes_read); +} + diff --git a/Src/Agave/DecodeFile/svc_raw_media_reader.h b/Src/Agave/DecodeFile/svc_raw_media_reader.h new file mode 100644 index 00000000..c70c8085 --- /dev/null +++ b/Src/Agave/DecodeFile/svc_raw_media_reader.h @@ -0,0 +1,32 @@ +#pragma once + +#include <bfc/dispatch.h> +#include "ifc_raw_media_reader.h" +#include <bfc/error.h> + +class svc_raw_media_reader : public Dispatchable +{ +protected: + svc_raw_media_reader() {} + ~svc_raw_media_reader() {} +public: + static FOURCC getServiceType() { return svc_raw_media_reader::SERVICETYPE; } + int CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **reader); +public: + DISPATCH_CODES + { + CREATERAWMEDIAREADER = 0, + }; + + + enum + { + SERVICETYPE = MK4CC('r','a','w','m') + }; +}; + +inline int svc_raw_media_reader::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **reader) +{ + return _call(CREATERAWMEDIAREADER, (int)NErr_NotImplemented, filename, reader); +} + |