mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-08-20 09:57:10 +00:00
Rewrite, format, fix shiggy bug
This commit is contained in:
parent
191634264f
commit
ba75b39c3f
|
|
@ -1,38 +1,25 @@
|
||||||
#include "../../Minecraft.World/Platform/stdafx.h"
|
#include "../../Minecraft.World/Platform/stdafx.h"
|
||||||
#include "Consoles_SoundEngine.h"
|
#include "Consoles_SoundEngine.h"
|
||||||
|
|
||||||
|
bool ConsoleSoundEngine::GetIsPlayingStreamingCDMusic() {
|
||||||
bool ConsoleSoundEngine::GetIsPlayingStreamingCDMusic()
|
return m_bIsPlayingStreamingCDMusic;
|
||||||
{
|
|
||||||
return m_bIsPlayingStreamingCDMusic;
|
|
||||||
}
|
}
|
||||||
bool ConsoleSoundEngine::GetIsPlayingStreamingGameMusic()
|
bool ConsoleSoundEngine::GetIsPlayingStreamingGameMusic() {
|
||||||
{
|
return m_bIsPlayingStreamingGameMusic;
|
||||||
return m_bIsPlayingStreamingGameMusic;
|
|
||||||
}
|
}
|
||||||
void ConsoleSoundEngine::SetIsPlayingStreamingCDMusic(bool bVal)
|
void ConsoleSoundEngine::SetIsPlayingStreamingCDMusic(bool bVal) {
|
||||||
{
|
m_bIsPlayingStreamingCDMusic = bVal;
|
||||||
m_bIsPlayingStreamingCDMusic=bVal;
|
|
||||||
}
|
}
|
||||||
void ConsoleSoundEngine::SetIsPlayingStreamingGameMusic(bool bVal)
|
void ConsoleSoundEngine::SetIsPlayingStreamingGameMusic(bool bVal) {
|
||||||
{
|
m_bIsPlayingStreamingGameMusic = bVal;
|
||||||
m_bIsPlayingStreamingGameMusic=bVal;
|
|
||||||
}
|
}
|
||||||
bool ConsoleSoundEngine::GetIsPlayingEndMusic()
|
bool ConsoleSoundEngine::GetIsPlayingEndMusic() { return m_bIsPlayingEndMusic; }
|
||||||
{
|
bool ConsoleSoundEngine::GetIsPlayingNetherMusic() {
|
||||||
return m_bIsPlayingEndMusic;
|
return m_bIsPlayingNetherMusic;
|
||||||
}
|
}
|
||||||
bool ConsoleSoundEngine::GetIsPlayingNetherMusic()
|
void ConsoleSoundEngine::SetIsPlayingEndMusic(bool bVal) {
|
||||||
{
|
m_bIsPlayingEndMusic = bVal;
|
||||||
return m_bIsPlayingNetherMusic;
|
|
||||||
}
|
}
|
||||||
void ConsoleSoundEngine::SetIsPlayingEndMusic(bool bVal)
|
void ConsoleSoundEngine::SetIsPlayingNetherMusic(bool bVal) {
|
||||||
{
|
m_bIsPlayingNetherMusic = bVal;
|
||||||
m_bIsPlayingEndMusic=bVal;
|
|
||||||
}
|
}
|
||||||
void ConsoleSoundEngine::SetIsPlayingNetherMusic(bool bVal)
|
|
||||||
{
|
|
||||||
m_bIsPlayingNetherMusic=bVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,81 +4,86 @@
|
||||||
|
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
|
|
||||||
#elif defined (__PS3__)
|
#elif defined(__PS3__)
|
||||||
#undef __in
|
#undef __in
|
||||||
#undef __out
|
#undef __out
|
||||||
#include "../../Minecraft.Client/Platform/PS3/Miles/include/mss.h"
|
#include "../../Minecraft.Client/Platform/PS3/Miles/include/mss.h"
|
||||||
#elif defined (__PSVITA__)
|
#elif defined(__PSVITA__)
|
||||||
#include "../../PSVITA/Miles/include/mss.h"
|
#include "../../PSVITA/Miles/include/mss.h"
|
||||||
#elif defined _DURANGO
|
#elif defined _DURANGO
|
||||||
// 4J Stu - Temp define to get Miles to link, can likely be removed when we get a new version of Miles
|
// 4J Stu - Temp define to get Miles to link, can likely be removed when we get
|
||||||
|
// a new version of Miles
|
||||||
#define _SEKRIT
|
#define _SEKRIT
|
||||||
#include "../../Minecraft.Client/Platform/Durango/Miles/include/mss.h"
|
#include "../../Minecraft.Client/Platform/Durango/Miles/include/mss.h"
|
||||||
#elif defined _WINDOWS64
|
#elif defined _WINDOWS64
|
||||||
#include "../../windows64/Miles/include/mss.h"
|
#include "../../windows64/Miles/include/mss.h"
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
// (DecalOverdose)HACK + TODO: Find native Linux headers and libs for this, but for now I'm using Win64 ones
|
// (DecalOverdose)HACK + TODO: Find native Linux headers and libs for this, but
|
||||||
|
// for now I'm using Win64 ones
|
||||||
#include "../../Minecraft.Client/Platform/Windows64/Miles/include/mss.h"
|
#include "../../Minecraft.Client/Platform/Windows64/Miles/include/mss.h"
|
||||||
#else // PS4
|
#else // PS4
|
||||||
// 4J Stu - Temp define to get Miles to link, can likely be removed when we get a new version of Miles
|
// 4J Stu - Temp define to get Miles to link, can likely be removed when we get
|
||||||
|
// a new version of Miles
|
||||||
#define _SEKRIT2
|
#define _SEKRIT2
|
||||||
#include "../../Minecraft.Client/Platform/Orbis/Miles/include/mss.h"
|
#include "../../Minecraft.Client/Platform/Orbis/Miles/include/mss.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
float x, y, z;
|
||||||
float x,y,z;
|
} AUDIO_VECTOR;
|
||||||
}
|
|
||||||
AUDIO_VECTOR;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
bool bValid;
|
||||||
bool bValid;
|
AUDIO_VECTOR vPosition;
|
||||||
AUDIO_VECTOR vPosition;
|
AUDIO_VECTOR vOrientFront;
|
||||||
AUDIO_VECTOR vOrientFront;
|
} AUDIO_LISTENER;
|
||||||
}
|
|
||||||
AUDIO_LISTENER;
|
|
||||||
|
|
||||||
class Options;
|
class Options;
|
||||||
|
|
||||||
class ConsoleSoundEngine
|
class ConsoleSoundEngine {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
ConsoleSoundEngine()
|
||||||
|
: m_bIsPlayingStreamingCDMusic(false),
|
||||||
|
m_bIsPlayingStreamingGameMusic(false),
|
||||||
|
m_bIsPlayingEndMusic(false),
|
||||||
|
m_bIsPlayingNetherMusic(false) {};
|
||||||
|
virtual void tick(std::shared_ptr<Mob>* players, float a) = 0;
|
||||||
|
virtual void destroy() = 0;
|
||||||
|
virtual void play(int iSound, float x, float y, float z, float volume,
|
||||||
|
float pitch) = 0;
|
||||||
|
virtual void playStreaming(const std::wstring& name, float x, float y,
|
||||||
|
float z, float volume, float pitch,
|
||||||
|
bool bMusicDelay = true) = 0;
|
||||||
|
virtual void playUI(int iSound, float volume, float pitch) = 0;
|
||||||
|
virtual void updateMusicVolume(float fVal) = 0;
|
||||||
|
virtual void updateSystemMusicPlaying(bool isPlaying) = 0;
|
||||||
|
virtual void updateSoundEffectVolume(float fVal) = 0;
|
||||||
|
virtual void init(Options*) = 0;
|
||||||
|
virtual void add(const std::wstring& name, File* file) = 0;
|
||||||
|
virtual void addMusic(const std::wstring& name, File* file) = 0;
|
||||||
|
virtual void addStreaming(const std::wstring& name, File* file) = 0;
|
||||||
|
virtual char* ConvertSoundPathToName(const std::wstring& name,
|
||||||
|
bool bConvertSpaces) = 0;
|
||||||
|
virtual void playMusicTick() = 0;
|
||||||
|
|
||||||
ConsoleSoundEngine() : m_bIsPlayingStreamingCDMusic(false),m_bIsPlayingStreamingGameMusic(false), m_bIsPlayingEndMusic(false),m_bIsPlayingNetherMusic(false){};
|
virtual bool GetIsPlayingStreamingCDMusic();
|
||||||
virtual void tick(std::shared_ptr<Mob> *players, float a) =0;
|
virtual bool GetIsPlayingStreamingGameMusic();
|
||||||
virtual void destroy()=0;
|
virtual void SetIsPlayingStreamingCDMusic(bool bVal);
|
||||||
virtual void play(int iSound, float x, float y, float z, float volume, float pitch) =0;
|
virtual void SetIsPlayingStreamingGameMusic(bool bVal);
|
||||||
virtual void playStreaming(const std::wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay=true) =0;
|
virtual bool GetIsPlayingEndMusic();
|
||||||
virtual void playUI(int iSound, float volume, float pitch) =0;
|
virtual bool GetIsPlayingNetherMusic();
|
||||||
virtual void updateMusicVolume(float fVal) =0;
|
virtual void SetIsPlayingEndMusic(bool bVal);
|
||||||
virtual void updateSystemMusicPlaying(bool isPlaying) = 0;
|
virtual void SetIsPlayingNetherMusic(bool bVal);
|
||||||
virtual void updateSoundEffectVolume(float fVal) =0;
|
static const WCHAR* wchSoundNames[eSoundType_MAX];
|
||||||
virtual void init(Options *) =0 ;
|
static const WCHAR* wchUISoundNames[eSFX_MAX];
|
||||||
virtual void add(const std::wstring& name, File *file) =0;
|
|
||||||
virtual void addMusic(const std::wstring& name, File *file) =0;
|
|
||||||
virtual void addStreaming(const std::wstring& name, File *file) =0;
|
|
||||||
virtual char *ConvertSoundPathToName(const std::wstring& name, bool bConvertSpaces) =0;
|
|
||||||
virtual void playMusicTick() =0;
|
|
||||||
|
|
||||||
virtual bool GetIsPlayingStreamingCDMusic() ;
|
|
||||||
virtual bool GetIsPlayingStreamingGameMusic() ;
|
|
||||||
virtual void SetIsPlayingStreamingCDMusic(bool bVal) ;
|
|
||||||
virtual void SetIsPlayingStreamingGameMusic(bool bVal) ;
|
|
||||||
virtual bool GetIsPlayingEndMusic() ;
|
|
||||||
virtual bool GetIsPlayingNetherMusic() ;
|
|
||||||
virtual void SetIsPlayingEndMusic(bool bVal) ;
|
|
||||||
virtual void SetIsPlayingNetherMusic(bool bVal) ;
|
|
||||||
static const WCHAR *wchSoundNames[eSoundType_MAX];
|
|
||||||
static const WCHAR *wchUISoundNames[eSFX_MAX];
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// platform specific functions
|
// platform specific functions
|
||||||
|
|
||||||
virtual int initAudioHardware(int iMinSpeakers)=0;
|
virtual int initAudioHardware(int iMinSpeakers) = 0;
|
||||||
|
|
||||||
bool m_bIsPlayingStreamingCDMusic;
|
bool m_bIsPlayingStreamingCDMusic;
|
||||||
bool m_bIsPlayingStreamingGameMusic;
|
bool m_bIsPlayingStreamingGameMusic;
|
||||||
bool m_bIsPlayingEndMusic;
|
bool m_bIsPlayingEndMusic;
|
||||||
bool m_bIsPlayingNetherMusic;
|
bool m_bIsPlayingNetherMusic;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -134,6 +134,9 @@ private:
|
||||||
#else
|
#else
|
||||||
int initAudioHardware(int iMinSpeakers) { return iMinSpeakers; }
|
int initAudioHardware(int iMinSpeakers) { return iMinSpeakers; }
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __linux__
|
||||||
|
void updateMiniAudio();
|
||||||
|
#endif
|
||||||
|
|
||||||
int GetRandomishTrack(int iStart, int iEnd);
|
int GetRandomishTrack(int iStart, int iEnd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = {
|
||||||
L"mob/chicken/chickenplop", // eSoundType_MOB_CHICKENPLOP
|
L"mob/chicken/chickenplop", // eSoundType_MOB_CHICKENPLOP
|
||||||
L"mob/cow/say", // eSoundType_MOB_COW_AMBIENT
|
L"mob/cow/say", // eSoundType_MOB_COW_AMBIENT
|
||||||
L"mob/cow/hurt", // eSoundType_MOB_COW_HURT
|
L"mob/cow/hurt", // eSoundType_MOB_COW_HURT
|
||||||
L"mob/pig/say", // eSoundType_MOB_PIG_AMBIENT
|
L"mob/pig/pig", // eSoundType_MOB_PIG_AMBIENT
|
||||||
L"mob/pig/pigdeath", // eSoundType_MOB_PIG_DEATH
|
L"mob/pig/pigdeath", // eSoundType_MOB_PIG_DEATH
|
||||||
L"mob/sheep/sheep", // eSoundType_MOB_SHEEP_AMBIENT
|
L"mob/sheep/sheep", // eSoundType_MOB_SHEEP_AMBIENT
|
||||||
L"mob/wolf/growl", // eSoundType_MOB_WOLF_GROWL
|
L"mob/wolf/growl", // eSoundType_MOB_WOLF_GROWL
|
||||||
|
|
@ -78,8 +78,8 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = {
|
||||||
L"random/glass", // eSoundType_RANDOM_GLASS,
|
L"random/glass", // eSoundType_RANDOM_GLASS,
|
||||||
L"random/orb", // eSoundType_RANDOM_ORB,
|
L"random/orb", // eSoundType_RANDOM_ORB,
|
||||||
L"random/break", // eSoundType_RANDOM_BREAK,
|
L"random/break", // eSoundType_RANDOM_BREAK,
|
||||||
L"random/chestopen", // eSoundType_RANDOM_CHEST_OPEN,
|
L"block/chest/open", // eSoundType_RANDOM_CHEST_OPEN,
|
||||||
L"random/chestclosed", // eSoundType_RANDOM_CHEST_CLOSE,
|
L"block/chest/close", // eSoundType_RANDOM_CHEST_CLOSE,
|
||||||
L"random/door_open", // eSoundType_RANDOM_DOOR_OPEN,
|
L"random/door_open", // eSoundType_RANDOM_DOOR_OPEN,
|
||||||
L"random/door_close", // eSoundType_RANDOM_DOOR_CLOSE,
|
L"random/door_close", // eSoundType_RANDOM_DOOR_CLOSE,
|
||||||
L"ambient/weather/rain", // eSoundType_AMBIENT_WEATHER_RAIN,
|
L"ambient/weather/rain", // eSoundType_AMBIENT_WEATHER_RAIN,
|
||||||
|
|
@ -94,9 +94,10 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = {
|
||||||
L"portal/trigger", // eSoundType_PORTAL_TRIGGER
|
L"portal/trigger", // eSoundType_PORTAL_TRIGGER
|
||||||
L"portal/travel", // eSoundType_PORTAL_TRAVEL
|
L"portal/travel", // eSoundType_PORTAL_TRAVEL
|
||||||
|
|
||||||
L"fire/ignite", // eSoundType_FIRE_IGNITE,
|
L"fire/new_ignite", // eSoundType_FIRE_IGNITE,
|
||||||
L"fire/fire", // eSoundType_FIRE_FIRE,
|
L"fire/fire", // eSoundType_FIRE_FIRE,
|
||||||
L"damage/hurtflesh", // eSoundType_DAMAGE_HURT,
|
// Renamed to damage/hit as the other file doesn't exist
|
||||||
|
L"damage/hit", // eSoundType_DAMAGE_HURT,
|
||||||
L"damage/fallsmall", // eSoundType_DAMAGE_FALL_SMALL,
|
L"damage/fallsmall", // eSoundType_DAMAGE_FALL_SMALL,
|
||||||
L"damage/fallbig", // eSoundType_DAMAGE_FALL_BIG,
|
L"damage/fallbig", // eSoundType_DAMAGE_FALL_BIG,
|
||||||
L"note/harp", // eSoundType_NOTE_HARP,
|
L"note/harp", // eSoundType_NOTE_HARP,
|
||||||
|
|
|
||||||
|
|
@ -1,591 +0,0 @@
|
||||||
#ifndef miniaudio_libvorbis_c
|
|
||||||
#define miniaudio_libvorbis_c
|
|
||||||
|
|
||||||
#include "miniaudio_libvorbis.h"
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
#ifndef OV_EXCLUDE_STATIC_CALLBACKS
|
|
||||||
#define OV_EXCLUDE_STATIC_CALLBACKS
|
|
||||||
#endif
|
|
||||||
#include <vorbis/vorbisfile.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h> /* For memset(). */
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_ds_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
|
|
||||||
{
|
|
||||||
return ma_libvorbis_read_pcm_frames((ma_libvorbis*)pDataSource, pFramesOut, frameCount, pFramesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_ds_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
|
|
||||||
{
|
|
||||||
return ma_libvorbis_seek_to_pcm_frame((ma_libvorbis*)pDataSource, frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_ds_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
|
|
||||||
{
|
|
||||||
return ma_libvorbis_get_data_format((ma_libvorbis*)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_ds_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
|
|
||||||
{
|
|
||||||
return ma_libvorbis_get_cursor_in_pcm_frames((ma_libvorbis*)pDataSource, pCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_ds_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
|
|
||||||
{
|
|
||||||
return ma_libvorbis_get_length_in_pcm_frames((ma_libvorbis*)pDataSource, pLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_data_source_vtable g_ma_libvorbis_ds_vtable =
|
|
||||||
{
|
|
||||||
ma_libvorbis_ds_read,
|
|
||||||
ma_libvorbis_ds_seek,
|
|
||||||
ma_libvorbis_ds_get_data_format,
|
|
||||||
ma_libvorbis_ds_get_cursor,
|
|
||||||
ma_libvorbis_ds_get_length,
|
|
||||||
NULL, /* onSetLooping */
|
|
||||||
0 /* flags */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
static size_t ma_libvorbis_vf_callback__read(void* pBufferOut, size_t size, size_t count, void* pUserData)
|
|
||||||
{
|
|
||||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pUserData;
|
|
||||||
ma_result result;
|
|
||||||
size_t bytesToRead;
|
|
||||||
size_t bytesRead;
|
|
||||||
|
|
||||||
/* For consistency with fread(). If `size` of `count` is 0, return 0 immediately without changing anything. */
|
|
||||||
if (size == 0 || count == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesToRead = size * count;
|
|
||||||
result = pVorbis->onRead(pVorbis->pReadSeekTellUserData, pBufferOut, bytesToRead, &bytesRead);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
/* Not entirely sure what to return here. What if an error occurs, but some data was read and bytesRead is > 0? */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesRead / size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ma_libvorbis_vf_callback__seek(void* pUserData, ogg_int64_t offset, int whence)
|
|
||||||
{
|
|
||||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pUserData;
|
|
||||||
ma_result result;
|
|
||||||
ma_seek_origin origin;
|
|
||||||
|
|
||||||
if (whence == SEEK_SET) {
|
|
||||||
origin = ma_seek_origin_start;
|
|
||||||
} else if (whence == SEEK_END) {
|
|
||||||
origin = ma_seek_origin_end;
|
|
||||||
} else {
|
|
||||||
origin = ma_seek_origin_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = pVorbis->onSeek(pVorbis->pReadSeekTellUserData, offset, origin);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static long ma_libvorbis_vf_callback__tell(void* pUserData)
|
|
||||||
{
|
|
||||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pUserData;
|
|
||||||
ma_result result;
|
|
||||||
ma_int64 cursor;
|
|
||||||
|
|
||||||
result = pVorbis->onTell(pVorbis->pReadSeekTellUserData, &cursor);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (long)cursor;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ma_result ma_libvorbis_init_internal(const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis)
|
|
||||||
{
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(pVorbis, 0, sizeof(*pVorbis));
|
|
||||||
pVorbis->format = ma_format_f32; /* f32 by default. */
|
|
||||||
|
|
||||||
if (pConfig != NULL && (pConfig->preferredFormat == ma_format_f32 || pConfig->preferredFormat == ma_format_s16)) {
|
|
||||||
pVorbis->format = pConfig->preferredFormat;
|
|
||||||
} else {
|
|
||||||
/* Getting here means something other than f32 and s16 was specified. Just leave this unset to use the default format. */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
ma_data_source_config dataSourceConfig;
|
|
||||||
|
|
||||||
dataSourceConfig = ma_data_source_config_init();
|
|
||||||
dataSourceConfig.vtable = &g_ma_libvorbis_ds_vtable;
|
|
||||||
|
|
||||||
result = ma_data_source_init(&dataSourceConfig, &pVorbis->ds);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
return result; /* Failed to initialize the base data source. */
|
|
||||||
}
|
|
||||||
|
|
||||||
pVorbis->vf = (OggVorbis_File*)ma_malloc(sizeof(OggVorbis_File), pAllocationCallbacks);
|
|
||||||
if (pVorbis->vf == NULL) {
|
|
||||||
ma_data_source_uninit(&pVorbis->ds);
|
|
||||||
return MA_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. */
|
|
||||||
(void)pAllocationCallbacks;
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
|
|
||||||
(void)pAllocationCallbacks; /* Can't seem to find a way to configure memory allocations in libvorbis. */
|
|
||||||
|
|
||||||
if (onRead == NULL || onSeek == NULL) {
|
|
||||||
return MA_INVALID_ARGS; /* onRead and onSeek are mandatory. */
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ma_libvorbis_init_internal(pConfig, pAllocationCallbacks, pVorbis);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
pVorbis->onRead = onRead;
|
|
||||||
pVorbis->onSeek = onSeek;
|
|
||||||
pVorbis->onTell = onTell;
|
|
||||||
pVorbis->pReadSeekTellUserData = pReadSeekTellUserData;
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
int libvorbisResult;
|
|
||||||
ov_callbacks libvorbisCallbacks;
|
|
||||||
|
|
||||||
/* We can now initialize the vorbis decoder. This must be done after we've set up the callbacks. */
|
|
||||||
libvorbisCallbacks.read_func = ma_libvorbis_vf_callback__read;
|
|
||||||
libvorbisCallbacks.seek_func = ma_libvorbis_vf_callback__seek;
|
|
||||||
libvorbisCallbacks.close_func = NULL;
|
|
||||||
libvorbisCallbacks.tell_func = ma_libvorbis_vf_callback__tell;
|
|
||||||
|
|
||||||
libvorbisResult = ov_open_callbacks(pVorbis, (OggVorbis_File*)pVorbis->vf, NULL, 0, libvorbisCallbacks);
|
|
||||||
if (libvorbisResult < 0) {
|
|
||||||
ma_data_source_uninit(&pVorbis->ds);
|
|
||||||
ma_free(pVorbis->vf, pAllocationCallbacks);
|
|
||||||
return MA_INVALID_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. */
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
|
|
||||||
(void)pAllocationCallbacks; /* Can't seem to find a way to configure memory allocations in libvorbis. */
|
|
||||||
|
|
||||||
result = ma_libvorbis_init_internal(pConfig, pAllocationCallbacks, pVorbis);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
int libvorbisResult;
|
|
||||||
|
|
||||||
libvorbisResult = ov_fopen(pFilePath, (OggVorbis_File*)pVorbis->vf);
|
|
||||||
if (libvorbisResult < 0) {
|
|
||||||
ma_data_source_uninit(&pVorbis->ds);
|
|
||||||
ma_free(pVorbis->vf, pAllocationCallbacks);
|
|
||||||
return MA_INVALID_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. */
|
|
||||||
(void)pFilePath;
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API void ma_libvorbis_uninit(ma_libvorbis* pVorbis, const ma_allocation_callbacks* pAllocationCallbacks)
|
|
||||||
{
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)pAllocationCallbacks;
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
ov_clear((OggVorbis_File*)pVorbis->vf);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ma_data_source_uninit(&pVorbis->ds);
|
|
||||||
ma_free(pVorbis->vf, pAllocationCallbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_read_pcm_frames(ma_libvorbis* pVorbis, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
|
|
||||||
{
|
|
||||||
if (pFramesRead != NULL) {
|
|
||||||
*pFramesRead = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frameCount == 0) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
/* We always use floating point format. */
|
|
||||||
ma_result result = MA_SUCCESS; /* Must be initialized to MA_SUCCESS. */
|
|
||||||
ma_uint64 totalFramesRead;
|
|
||||||
ma_format format;
|
|
||||||
ma_uint32 channels;
|
|
||||||
|
|
||||||
ma_libvorbis_get_data_format(pVorbis, &format, &channels, NULL, NULL, 0);
|
|
||||||
|
|
||||||
totalFramesRead = 0;
|
|
||||||
while (totalFramesRead < frameCount) {
|
|
||||||
long libvorbisResult;
|
|
||||||
ma_uint64 framesToRead;
|
|
||||||
ma_uint64 framesRemaining;
|
|
||||||
|
|
||||||
framesRemaining = (frameCount - totalFramesRead);
|
|
||||||
framesToRead = 1024;
|
|
||||||
if (framesToRead > framesRemaining) {
|
|
||||||
framesToRead = framesRemaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format == ma_format_f32) {
|
|
||||||
float** ppFramesF32;
|
|
||||||
|
|
||||||
libvorbisResult = ov_read_float((OggVorbis_File*)pVorbis->vf, &ppFramesF32, (int)framesToRead, NULL);
|
|
||||||
if (libvorbisResult < 0) {
|
|
||||||
result = MA_ERROR; /* Error while decoding. */
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* Frames need to be interleaved. */
|
|
||||||
ma_interleave_pcm_frames(format, channels, libvorbisResult, (const void**)ppFramesF32, ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, format, channels));
|
|
||||||
totalFramesRead += libvorbisResult;
|
|
||||||
|
|
||||||
if (libvorbisResult == 0) {
|
|
||||||
result = MA_AT_END;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
libvorbisResult = ov_read((OggVorbis_File*)pVorbis->vf, (char*)ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, format, channels), (int)(framesToRead * ma_get_bytes_per_frame(format, channels)), 0, 2, 1, NULL);
|
|
||||||
if (libvorbisResult < 0) {
|
|
||||||
result = MA_ERROR; /* Error while decoding. */
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* Conveniently, there's no need to interleaving when using ov_read(). I'm not sure why ov_read_float() is different in that regard... */
|
|
||||||
totalFramesRead += libvorbisResult / ma_get_bytes_per_frame(format, channels);
|
|
||||||
|
|
||||||
if (libvorbisResult == 0) {
|
|
||||||
result = MA_AT_END;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pFramesRead != NULL) {
|
|
||||||
*pFramesRead = totalFramesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == MA_SUCCESS && totalFramesRead == 0) {
|
|
||||||
result = MA_AT_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
|
|
||||||
(void)pFramesOut;
|
|
||||||
(void)frameCount;
|
|
||||||
(void)pFramesRead;
|
|
||||||
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_seek_to_pcm_frame(ma_libvorbis* pVorbis, ma_uint64 frameIndex)
|
|
||||||
{
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
int libvorbisResult = ov_pcm_seek((OggVorbis_File*)pVorbis->vf, (ogg_int64_t)frameIndex);
|
|
||||||
if (libvorbisResult != 0) {
|
|
||||||
if (libvorbisResult == OV_ENOSEEK) {
|
|
||||||
return MA_INVALID_OPERATION; /* Not seekable. */
|
|
||||||
} else if (libvorbisResult == OV_EINVAL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
} else {
|
|
||||||
return MA_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
|
|
||||||
(void)frameIndex;
|
|
||||||
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_get_data_format(ma_libvorbis* pVorbis, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
|
|
||||||
{
|
|
||||||
/* Defaults for safety. */
|
|
||||||
if (pFormat != NULL) {
|
|
||||||
*pFormat = ma_format_unknown;
|
|
||||||
}
|
|
||||||
if (pChannels != NULL) {
|
|
||||||
*pChannels = 0;
|
|
||||||
}
|
|
||||||
if (pSampleRate != NULL) {
|
|
||||||
*pSampleRate = 0;
|
|
||||||
}
|
|
||||||
if (pChannelMap != NULL) {
|
|
||||||
memset(pChannelMap, 0, sizeof(*pChannelMap) * channelMapCap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pFormat != NULL) {
|
|
||||||
*pFormat = pVorbis->format;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
vorbis_info* pInfo = ov_info((OggVorbis_File*)pVorbis->vf, 0);
|
|
||||||
if (pInfo == NULL) {
|
|
||||||
return MA_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pChannels != NULL) {
|
|
||||||
*pChannels = pInfo->channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSampleRate != NULL) {
|
|
||||||
*pSampleRate = pInfo->rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pChannelMap != NULL) {
|
|
||||||
ma_channel_map_init_standard(ma_standard_channel_map_vorbis, pChannelMap, channelMapCap, pInfo->channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_get_cursor_in_pcm_frames(ma_libvorbis* pVorbis, ma_uint64* pCursor)
|
|
||||||
{
|
|
||||||
if (pCursor == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pCursor = 0; /* Safety. */
|
|
||||||
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
ogg_int64_t offset = ov_pcm_tell((OggVorbis_File*)pVorbis->vf);
|
|
||||||
if (offset < 0) {
|
|
||||||
return MA_INVALID_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pCursor = (ma_uint64)offset;
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_get_length_in_pcm_frames(ma_libvorbis* pVorbis, ma_uint64* pLength)
|
|
||||||
{
|
|
||||||
if (pLength == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pLength = 0; /* Safety. */
|
|
||||||
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Will work in the supermajority of cases where a file has a single logical bitstream. Concatenated streams
|
|
||||||
are much harder to determine the length of since they can have sample rate changes, but they should be
|
|
||||||
extremely rare outside of unseekable livestreams anyway.
|
|
||||||
*/
|
|
||||||
if (ov_streams((OggVorbis_File*)pVorbis->vf) == 1) {
|
|
||||||
ogg_int64_t length = ov_pcm_total((OggVorbis_File*)pVorbis->vf, 0);
|
|
||||||
if(length != OV_EINVAL) {
|
|
||||||
*pLength = (ma_uint64)length;
|
|
||||||
} else {
|
|
||||||
/* Unseekable. */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Concatenated stream. */
|
|
||||||
}
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
/* libvorbis is disabled. Should never hit this since initialization would have failed. */
|
|
||||||
assert(MA_FALSE);
|
|
||||||
return MA_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
The code below defines the vtable that you'll plug into your `ma_decoder_config` object.
|
|
||||||
*/
|
|
||||||
#if !defined(MA_NO_LIBVORBIS)
|
|
||||||
static ma_result ma_decoding_backend_init__libvorbis(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
ma_libvorbis* pVorbis;
|
|
||||||
|
|
||||||
(void)pUserData;
|
|
||||||
|
|
||||||
pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks);
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ma_libvorbis_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pVorbis);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
ma_free(pVorbis, pAllocationCallbacks);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppBackend = pVorbis;
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ma_result ma_decoding_backend_init_file__libvorbis(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
ma_libvorbis* pVorbis;
|
|
||||||
|
|
||||||
(void)pUserData;
|
|
||||||
|
|
||||||
pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks);
|
|
||||||
if (pVorbis == NULL) {
|
|
||||||
return MA_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ma_libvorbis_init_file(pFilePath, pConfig, pAllocationCallbacks, pVorbis);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
ma_free(pVorbis, pAllocationCallbacks);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppBackend = pVorbis;
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ma_decoding_backend_uninit__libvorbis(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks)
|
|
||||||
{
|
|
||||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend;
|
|
||||||
|
|
||||||
(void)pUserData;
|
|
||||||
|
|
||||||
ma_libvorbis_uninit(pVorbis, pAllocationCallbacks);
|
|
||||||
ma_free(pVorbis, pAllocationCallbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ma_decoding_backend_vtable ma_gDecodingBackendVTable_libvorbis =
|
|
||||||
{
|
|
||||||
ma_decoding_backend_init__libvorbis,
|
|
||||||
ma_decoding_backend_init_file__libvorbis,
|
|
||||||
NULL, /* onInitFileW() */
|
|
||||||
NULL, /* onInitMemory() */
|
|
||||||
ma_decoding_backend_uninit__libvorbis
|
|
||||||
};
|
|
||||||
ma_decoding_backend_vtable* ma_decoding_backend_libvorbis = &ma_gDecodingBackendVTable_libvorbis;
|
|
||||||
#else
|
|
||||||
ma_decoding_backend_vtable* ma_decoding_backend_libvorbis = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* miniaudio_libvorbis_c */
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
This implements a data source that decodes Vorbis streams via libvorbis + libvorbisfile
|
|
||||||
|
|
||||||
This object can be plugged into any `ma_data_source_*()` API and can also be used as a custom
|
|
||||||
decoding backend. See the custom_decoder example.
|
|
||||||
*/
|
|
||||||
#ifndef miniaudio_libvorbis_h
|
|
||||||
#define miniaudio_libvorbis_h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../../miniaudio.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ma_data_source_base ds; /* The libvorbis decoder can be used independently as a data source. */
|
|
||||||
ma_read_proc onRead;
|
|
||||||
ma_seek_proc onSeek;
|
|
||||||
ma_tell_proc onTell;
|
|
||||||
void* pReadSeekTellUserData;
|
|
||||||
ma_format format; /* Will be either f32 or s16. */
|
|
||||||
/*OggVorbis_File**/ void* vf; /* Typed as void* so we can avoid a dependency on opusfile in the header section. */
|
|
||||||
} ma_libvorbis;
|
|
||||||
|
|
||||||
MA_API ma_result ma_libvorbis_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis);
|
|
||||||
MA_API ma_result ma_libvorbis_init_file(const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis);
|
|
||||||
MA_API void ma_libvorbis_uninit(ma_libvorbis* pVorbis, const ma_allocation_callbacks* pAllocationCallbacks);
|
|
||||||
MA_API ma_result ma_libvorbis_read_pcm_frames(ma_libvorbis* pVorbis, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
|
|
||||||
MA_API ma_result ma_libvorbis_seek_to_pcm_frame(ma_libvorbis* pVorbis, ma_uint64 frameIndex);
|
|
||||||
MA_API ma_result ma_libvorbis_get_data_format(ma_libvorbis* pVorbis, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
|
|
||||||
MA_API ma_result ma_libvorbis_get_cursor_in_pcm_frames(ma_libvorbis* pVorbis, ma_uint64* pCursor);
|
|
||||||
MA_API ma_result ma_libvorbis_get_length_in_pcm_frames(ma_libvorbis* pVorbis, ma_uint64* pLength);
|
|
||||||
|
|
||||||
/* Decoding backend vtable. This is what you'll plug into ma_decoder_config.pBackendVTables. No user data required. */
|
|
||||||
extern ma_decoding_backend_vtable* ma_decoding_backend_libvorbis;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* miniaudio_libvorbis_h */
|
|
||||||
|
|
@ -956,7 +956,8 @@ static int set_file_offset(stb_vorbis *f, unsigned int loc)
|
||||||
#endif
|
#endif
|
||||||
f->eof = 0;
|
f->eof = 0;
|
||||||
if (USE_MEMORY(f)) {
|
if (USE_MEMORY(f)) {
|
||||||
if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) {
|
if ((size_t)(f->stream_start + loc) >= (size_t)f->stream_end ||
|
||||||
|
(size_t)(f->stream_start + loc) < (size_t)f->stream_start) {
|
||||||
f->stream = f->stream_end;
|
f->stream = f->stream_end;
|
||||||
f->eof = 1;
|
f->eof = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 7adc6c47882409c31e4f2d66fbfabdf4a3a98fd1
|
|
||||||
Loading…
Reference in a new issue