Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
ygopro
Commits
9a36ca40
Commit
9a36ca40
authored
Mar 27, 2025
by
mercury233
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
test opus & vorbis
parent
5ebd8aef
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1255 additions
and
5603 deletions
+1255
-5603
.gitignore
.gitignore
+1
-0
gframe/miniaudio/premake5.lua
gframe/miniaudio/premake5.lua
+0
-6
gframe/miniaudio/stb_vorbis.c
gframe/miniaudio/stb_vorbis.c
+0
-5584
gframe/premake5.lua
gframe/premake5.lua
+2
-4
gframe/sound_manager.cpp
gframe/sound_manager.cpp
+19
-1
gframe/sound_manager.h
gframe/sound_manager.h
+4
-1
miniaudio/miniaudio.c
miniaudio/miniaudio.c
+0
-2
miniaudio/miniaudio.h
miniaudio/miniaudio.h
+0
-0
miniaudio/miniaudio_libopus.c
miniaudio/miniaudio_libopus.c
+536
-0
miniaudio/miniaudio_libopus.h
miniaudio/miniaudio_libopus.h
+43
-0
miniaudio/miniaudio_libvorbis.c
miniaudio/miniaudio_libvorbis.c
+574
-0
miniaudio/miniaudio_libvorbis.h
miniaudio/miniaudio_libvorbis.h
+42
-0
ocgcore
ocgcore
+1
-1
premake/miniaudio/premake5.lua
premake/miniaudio/premake5.lua
+29
-0
premake5.lua
premake5.lua
+3
-3
script
script
+1
-1
No files found.
.gitignore
View file @
9a36ca40
...
...
@@ -30,6 +30,7 @@
/irrklang
/ikpmp3
/lua
/miniaudio
/sqlite3
/gframe/*.ico
/gframe/ygopro.rc
...
...
gframe/miniaudio/premake5.lua
deleted
100644 → 0
View file @
5ebd8aef
project
"cminiaudio"
kind
"StaticLib"
files
{
"*.c"
,
"*.h"
}
filter
"system:linux"
links
{
"dl"
,
"pthread"
,
"m"
}
gframe/miniaudio/stb_vorbis.c
deleted
100644 → 0
View file @
5ebd8aef
This source diff could not be displayed because it is too large. You can
view the blob
instead.
gframe/premake5.lua
View file @
9a36ca40
include
"lzma/."
include
"spmemvfs/."
if
USE_AUDIO
then
include
"miniaudio/."
end
project
"YGOPro"
kind
"WindowedApp"
...
...
@@ -43,7 +40,8 @@ project "YGOPro"
if
USE_AUDIO
then
defines
{
"YGOPRO_USE_AUDIO"
}
links
{
"cminiaudio"
}
includedirs
{
"../miniaudio"
}
links
{
"miniaudio"
}
end
filter
"system:windows"
...
...
gframe/sound_manager.cpp
View file @
9a36ca40
#include "sound_manager.h"
#ifdef YGOPRO_USE_AUDIO
#include "../miniaudio/miniaudio_libvorbis.h"
#include "../miniaudio/miniaudio_libopus.h"
#endif
#include "myfilesystem.h"
namespace
ygo
{
...
...
@@ -10,7 +14,21 @@ bool SoundManager::Init() {
bgm_scene
=
-
1
;
RefreshBGMList
();
rnd
.
reset
((
unsigned
int
)
std
::
time
(
nullptr
));
if
(
ma_engine_init
(
nullptr
,
&
engineSound
)
||
ma_engine_init
(
nullptr
,
&
engineMusic
))
{
ma_decoding_backend_vtable
*
pCustomBackendVTables
[]
=
{
ma_decoding_backend_libvorbis
,
ma_decoding_backend_libopus
};
resourceManagerConfig
=
ma_resource_manager_config_init
();
resourceManagerConfig
.
ppCustomDecodingBackendVTables
=
pCustomBackendVTables
;
resourceManagerConfig
.
customDecodingBackendCount
=
sizeof
(
pCustomBackendVTables
)
/
sizeof
(
pCustomBackendVTables
[
0
]);
resourceManagerConfig
.
pCustomDecodingBackendUserData
=
NULL
;
if
(
ma_resource_manager_init
(
&
resourceManagerConfig
,
&
resourceManager
)
!=
MA_SUCCESS
)
{
return
false
;
}
engineConfig
=
ma_engine_config_init
();
engineConfig
.
pResourceManager
=
&
resourceManager
;
if
(
ma_engine_init
(
&
engineConfig
,
&
engineSound
)
!=
MA_SUCCESS
||
ma_engine_init
(
&
engineConfig
,
&
engineMusic
)
!=
MA_SUCCESS
)
{
return
false
;
}
else
{
return
true
;
...
...
gframe/sound_manager.h
View file @
9a36ca40
...
...
@@ -4,7 +4,7 @@
#include "game.h"
#include "../ocgcore/mtrandom.h"
#ifdef YGOPRO_USE_AUDIO
#include "miniaudio/miniaudio.h"
#include "
../
miniaudio/miniaudio.h"
#endif
namespace
ygo
{
...
...
@@ -15,6 +15,9 @@ private:
int
bgm_scene
;
mt19937
rnd
;
#ifdef YGOPRO_USE_AUDIO
ma_resource_manager_config
resourceManagerConfig
;
ma_resource_manager
resourceManager
;
ma_engine_config
engineConfig
;
ma_engine
engineSound
;
ma_engine
engineMusic
;
ma_sound
soundBGM
;
...
...
gframe/
miniaudio/miniaudio.c
→
miniaudio/miniaudio.c
View file @
9a36ca40
...
...
@@ -52081,8 +52081,6 @@ static ma_result ma_decoder_init_mp3_from_memory__internal(const void* pData, si
#endif /* ma_dr_mp3_h */
/* Vorbis */
// This is the line added by YGOPro
#include "stb_vorbis.c"
#ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define MA_HAS_VORBIS
gframe/
miniaudio/miniaudio.h
→
miniaudio/miniaudio.h
View file @
9a36ca40
File moved
miniaudio/miniaudio_libopus.c
0 → 100644
View file @
9a36ca40
#ifndef miniaudio_libopus_c
#define miniaudio_libopus_c
#include "miniaudio_libopus.h"
#if !defined(MA_NO_LIBOPUS)
#include <opusfile.h>
#endif
#include <string.h>
/* For memset(). */
#include <assert.h>
static
ma_result
ma_libopus_ds_read
(
ma_data_source
*
pDataSource
,
void
*
pFramesOut
,
ma_uint64
frameCount
,
ma_uint64
*
pFramesRead
)
{
return
ma_libopus_read_pcm_frames
((
ma_libopus
*
)
pDataSource
,
pFramesOut
,
frameCount
,
pFramesRead
);
}
static
ma_result
ma_libopus_ds_seek
(
ma_data_source
*
pDataSource
,
ma_uint64
frameIndex
)
{
return
ma_libopus_seek_to_pcm_frame
((
ma_libopus
*
)
pDataSource
,
frameIndex
);
}
static
ma_result
ma_libopus_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_libopus_get_data_format
((
ma_libopus
*
)
pDataSource
,
pFormat
,
pChannels
,
pSampleRate
,
pChannelMap
,
channelMapCap
);
}
static
ma_result
ma_libopus_ds_get_cursor
(
ma_data_source
*
pDataSource
,
ma_uint64
*
pCursor
)
{
return
ma_libopus_get_cursor_in_pcm_frames
((
ma_libopus
*
)
pDataSource
,
pCursor
);
}
static
ma_result
ma_libopus_ds_get_length
(
ma_data_source
*
pDataSource
,
ma_uint64
*
pLength
)
{
return
ma_libopus_get_length_in_pcm_frames
((
ma_libopus
*
)
pDataSource
,
pLength
);
}
static
ma_data_source_vtable
g_ma_libopus_ds_vtable
=
{
ma_libopus_ds_read
,
ma_libopus_ds_seek
,
ma_libopus_ds_get_data_format
,
ma_libopus_ds_get_cursor
,
ma_libopus_ds_get_length
,
NULL
,
/* onSetLooping */
0
/* flags */
};
#if !defined(MA_NO_LIBOPUS)
static
int
ma_libopus_of_callback__read
(
void
*
pUserData
,
unsigned
char
*
pBufferOut
,
int
bytesToRead
)
{
ma_libopus
*
pOpus
=
(
ma_libopus
*
)
pUserData
;
ma_result
result
;
size_t
bytesRead
;
result
=
pOpus
->
onRead
(
pOpus
->
pReadSeekTellUserData
,
(
void
*
)
pBufferOut
,
bytesToRead
,
&
bytesRead
);
if
(
result
!=
MA_SUCCESS
)
{
return
-
1
;
}
return
(
int
)
bytesRead
;
}
static
int
ma_libopus_of_callback__seek
(
void
*
pUserData
,
ogg_int64_t
offset
,
int
whence
)
{
ma_libopus
*
pOpus
=
(
ma_libopus
*
)
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
=
pOpus
->
onSeek
(
pOpus
->
pReadSeekTellUserData
,
offset
,
origin
);
if
(
result
!=
MA_SUCCESS
)
{
return
-
1
;
}
return
0
;
}
static
opus_int64
ma_libopus_of_callback__tell
(
void
*
pUserData
)
{
ma_libopus
*
pOpus
=
(
ma_libopus
*
)
pUserData
;
ma_result
result
;
ma_int64
cursor
;
if
(
pOpus
->
onTell
==
NULL
)
{
return
-
1
;
}
result
=
pOpus
->
onTell
(
pOpus
->
pReadSeekTellUserData
,
&
cursor
);
if
(
result
!=
MA_SUCCESS
)
{
return
-
1
;
}
return
cursor
;
}
#endif
static
ma_result
ma_libopus_init_internal
(
const
ma_decoding_backend_config
*
pConfig
,
ma_libopus
*
pOpus
)
{
ma_result
result
;
ma_data_source_config
dataSourceConfig
;
if
(
pOpus
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
memset
(
pOpus
,
0
,
sizeof
(
*
pOpus
));
pOpus
->
format
=
ma_format_f32
;
/* f32 by default. */
if
(
pConfig
!=
NULL
&&
(
pConfig
->
preferredFormat
==
ma_format_f32
||
pConfig
->
preferredFormat
==
ma_format_s16
))
{
pOpus
->
format
=
pConfig
->
preferredFormat
;
}
else
{
/* Getting here means something other than f32 and s16 was specified. Just leave this unset to use the default format. */
}
dataSourceConfig
=
ma_data_source_config_init
();
dataSourceConfig
.
vtable
=
&
g_ma_libopus_ds_vtable
;
result
=
ma_data_source_init
(
&
dataSourceConfig
,
&
pOpus
->
ds
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
/* Failed to initialize the base data source. */
}
return
MA_SUCCESS
;
}
MA_API
ma_result
ma_libopus_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_libopus
*
pOpus
)
{
ma_result
result
;
(
void
)
pAllocationCallbacks
;
/* Can't seem to find a way to configure memory allocations in libopus. */
result
=
ma_libopus_init_internal
(
pConfig
,
pOpus
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
}
if
(
onRead
==
NULL
||
onSeek
==
NULL
)
{
return
MA_INVALID_ARGS
;
/* onRead and onSeek are mandatory. */
}
pOpus
->
onRead
=
onRead
;
pOpus
->
onSeek
=
onSeek
;
pOpus
->
onTell
=
onTell
;
pOpus
->
pReadSeekTellUserData
=
pReadSeekTellUserData
;
#if !defined(MA_NO_LIBOPUS)
{
int
libopusResult
;
OpusFileCallbacks
libopusCallbacks
;
/* We can now initialize the Opus decoder. This must be done after we've set up the callbacks. */
libopusCallbacks
.
read
=
ma_libopus_of_callback__read
;
libopusCallbacks
.
seek
=
ma_libopus_of_callback__seek
;
libopusCallbacks
.
close
=
NULL
;
libopusCallbacks
.
tell
=
ma_libopus_of_callback__tell
;
pOpus
->
of
=
op_open_callbacks
(
pOpus
,
&
libopusCallbacks
,
NULL
,
0
,
&
libopusResult
);
if
(
pOpus
->
of
==
NULL
)
{
return
MA_INVALID_FILE
;
}
return
MA_SUCCESS
;
}
#else
{
/* libopus is disabled. */
return
MA_NOT_IMPLEMENTED
;
}
#endif
}
MA_API
ma_result
ma_libopus_init_file
(
const
char
*
pFilePath
,
const
ma_decoding_backend_config
*
pConfig
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
,
ma_libopus
*
pOpus
)
{
ma_result
result
;
(
void
)
pAllocationCallbacks
;
/* Can't seem to find a way to configure memory allocations in libopus. */
result
=
ma_libopus_init_internal
(
pConfig
,
pOpus
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
}
#if !defined(MA_NO_LIBOPUS)
{
int
libopusResult
;
pOpus
->
of
=
op_open_file
(
pFilePath
,
&
libopusResult
);
if
(
pOpus
->
of
==
NULL
)
{
return
MA_INVALID_FILE
;
}
return
MA_SUCCESS
;
}
#else
{
/* libopus is disabled. */
(
void
)
pFilePath
;
return
MA_NOT_IMPLEMENTED
;
}
#endif
}
MA_API
void
ma_libopus_uninit
(
ma_libopus
*
pOpus
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
)
{
if
(
pOpus
==
NULL
)
{
return
;
}
(
void
)
pAllocationCallbacks
;
#if !defined(MA_NO_LIBOPUS)
{
op_free
((
OggOpusFile
*
)
pOpus
->
of
);
}
#else
{
/* libopus is disabled. Should never hit this since initialization would have failed. */
assert
(
MA_FALSE
);
}
#endif
ma_data_source_uninit
(
&
pOpus
->
ds
);
}
MA_API
ma_result
ma_libopus_read_pcm_frames
(
ma_libopus
*
pOpus
,
void
*
pFramesOut
,
ma_uint64
frameCount
,
ma_uint64
*
pFramesRead
)
{
if
(
pFramesRead
!=
NULL
)
{
*
pFramesRead
=
0
;
}
if
(
frameCount
==
0
)
{
return
MA_INVALID_ARGS
;
}
if
(
pOpus
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
#if !defined(MA_NO_LIBOPUS)
{
/* 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_libopus_get_data_format
(
pOpus
,
&
format
,
&
channels
,
NULL
,
NULL
,
0
);
totalFramesRead
=
0
;
while
(
totalFramesRead
<
frameCount
)
{
long
libopusResult
;
ma_uint64
framesToRead
;
ma_uint64
framesRemaining
;
framesRemaining
=
(
frameCount
-
totalFramesRead
);
framesToRead
=
1024
;
if
(
framesToRead
>
framesRemaining
)
{
framesToRead
=
framesRemaining
;
}
if
(
format
==
ma_format_f32
)
{
libopusResult
=
op_read_float
((
OggOpusFile
*
)
pOpus
->
of
,
(
float
*
)
ma_offset_pcm_frames_ptr
(
pFramesOut
,
totalFramesRead
,
format
,
channels
),
(
int
)(
framesToRead
*
channels
),
NULL
);
}
else
{
libopusResult
=
op_read
((
OggOpusFile
*
)
pOpus
->
of
,
(
opus_int16
*
)
ma_offset_pcm_frames_ptr
(
pFramesOut
,
totalFramesRead
,
format
,
channels
),
(
int
)(
framesToRead
*
channels
),
NULL
);
}
if
(
libopusResult
<
0
)
{
result
=
MA_ERROR
;
/* Error while decoding. */
break
;
}
else
{
totalFramesRead
+=
libopusResult
;
if
(
libopusResult
==
0
)
{
result
=
MA_AT_END
;
break
;
}
}
}
if
(
pFramesRead
!=
NULL
)
{
*
pFramesRead
=
totalFramesRead
;
}
if
(
result
==
MA_SUCCESS
&&
totalFramesRead
==
0
)
{
result
=
MA_AT_END
;
}
return
result
;
}
#else
{
/* libopus 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_libopus_seek_to_pcm_frame
(
ma_libopus
*
pOpus
,
ma_uint64
frameIndex
)
{
if
(
pOpus
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
#if !defined(MA_NO_LIBOPUS)
{
int
libopusResult
=
op_pcm_seek
((
OggOpusFile
*
)
pOpus
->
of
,
(
ogg_int64_t
)
frameIndex
);
if
(
libopusResult
!=
0
)
{
if
(
libopusResult
==
OP_ENOSEEK
)
{
return
MA_INVALID_OPERATION
;
/* Not seekable. */
}
else
if
(
libopusResult
==
OP_EINVAL
)
{
return
MA_INVALID_ARGS
;
}
else
{
return
MA_ERROR
;
}
}
return
MA_SUCCESS
;
}
#else
{
/* libopus 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_libopus_get_data_format
(
ma_libopus
*
pOpus
,
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
(
pOpus
==
NULL
)
{
return
MA_INVALID_OPERATION
;
}
if
(
pFormat
!=
NULL
)
{
*
pFormat
=
pOpus
->
format
;
}
#if !defined(MA_NO_LIBOPUS)
{
ma_uint32
channels
=
op_channel_count
((
OggOpusFile
*
)
pOpus
->
of
,
-
1
);
if
(
pChannels
!=
NULL
)
{
*
pChannels
=
channels
;
}
if
(
pSampleRate
!=
NULL
)
{
*
pSampleRate
=
48000
;
}
if
(
pChannelMap
!=
NULL
)
{
ma_channel_map_init_standard
(
ma_standard_channel_map_vorbis
,
pChannelMap
,
channelMapCap
,
channels
);
}
return
MA_SUCCESS
;
}
#else
{
/* libopus is disabled. Should never hit this since initialization would have failed. */
assert
(
MA_FALSE
);
return
MA_NOT_IMPLEMENTED
;
}
#endif
}
MA_API
ma_result
ma_libopus_get_cursor_in_pcm_frames
(
ma_libopus
*
pOpus
,
ma_uint64
*
pCursor
)
{
if
(
pCursor
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
*
pCursor
=
0
;
/* Safety. */
if
(
pOpus
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
#if !defined(MA_NO_LIBOPUS)
{
ogg_int64_t
offset
=
op_pcm_tell
((
OggOpusFile
*
)
pOpus
->
of
);
if
(
offset
<
0
)
{
return
MA_INVALID_FILE
;
}
*
pCursor
=
(
ma_uint64
)
offset
;
return
MA_SUCCESS
;
}
#else
{
/* libopus is disabled. Should never hit this since initialization would have failed. */
assert
(
MA_FALSE
);
return
MA_NOT_IMPLEMENTED
;
}
#endif
}
MA_API
ma_result
ma_libopus_get_length_in_pcm_frames
(
ma_libopus
*
pOpus
,
ma_uint64
*
pLength
)
{
if
(
pLength
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
*
pLength
=
0
;
/* Safety. */
if
(
pOpus
==
NULL
)
{
return
MA_INVALID_ARGS
;
}
#if !defined(MA_NO_LIBOPUS)
{
ogg_int64_t
length
=
op_pcm_total
((
OggOpusFile
*
)
pOpus
->
of
,
-
1
);
if
(
length
<
0
)
{
return
MA_ERROR
;
}
*
pLength
=
(
ma_uint64
)
length
;
return
MA_SUCCESS
;
}
#else
{
/* libopus 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_LIBOPUS)
static
ma_result
ma_decoding_backend_init__libopus
(
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_libopus
*
pOpus
;
(
void
)
pUserData
;
pOpus
=
(
ma_libopus
*
)
ma_malloc
(
sizeof
(
*
pOpus
),
pAllocationCallbacks
);
if
(
pOpus
==
NULL
)
{
return
MA_OUT_OF_MEMORY
;
}
result
=
ma_libopus_init
(
onRead
,
onSeek
,
onTell
,
pReadSeekTellUserData
,
pConfig
,
pAllocationCallbacks
,
pOpus
);
if
(
result
!=
MA_SUCCESS
)
{
ma_free
(
pOpus
,
pAllocationCallbacks
);
return
result
;
}
*
ppBackend
=
pOpus
;
return
MA_SUCCESS
;
}
static
ma_result
ma_decoding_backend_init_file__libopus
(
void
*
pUserData
,
const
char
*
pFilePath
,
const
ma_decoding_backend_config
*
pConfig
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
,
ma_data_source
**
ppBackend
)
{
ma_result
result
;
ma_libopus
*
pOpus
;
(
void
)
pUserData
;
pOpus
=
(
ma_libopus
*
)
ma_malloc
(
sizeof
(
*
pOpus
),
pAllocationCallbacks
);
if
(
pOpus
==
NULL
)
{
return
MA_OUT_OF_MEMORY
;
}
result
=
ma_libopus_init_file
(
pFilePath
,
pConfig
,
pAllocationCallbacks
,
pOpus
);
if
(
result
!=
MA_SUCCESS
)
{
ma_free
(
pOpus
,
pAllocationCallbacks
);
return
result
;
}
*
ppBackend
=
pOpus
;
return
MA_SUCCESS
;
}
static
void
ma_decoding_backend_uninit__libopus
(
void
*
pUserData
,
ma_data_source
*
pBackend
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
)
{
ma_libopus
*
pOpus
=
(
ma_libopus
*
)
pBackend
;
(
void
)
pUserData
;
ma_libopus_uninit
(
pOpus
,
pAllocationCallbacks
);
ma_free
(
pOpus
,
pAllocationCallbacks
);
}
static
ma_decoding_backend_vtable
ma_gDecodingBackendVTable_libopus
=
{
ma_decoding_backend_init__libopus
,
ma_decoding_backend_init_file__libopus
,
NULL
,
/* onInitFileW() */
NULL
,
/* onInitMemory() */
ma_decoding_backend_uninit__libopus
};
ma_decoding_backend_vtable
*
ma_decoding_backend_libopus
=
&
ma_gDecodingBackendVTable_libopus
;
#else
ma_decoding_backend_vtable
*
ma_decoding_backend_libopus
=
NULL
;
#endif
#endif
/* miniaudio_libopus_c */
miniaudio/miniaudio_libopus.h
0 → 100644
View file @
9a36ca40
/*
This implements a data source that decodes Opus streams via libopus + libopusfile
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_libopus_h
#define miniaudio_libopus_h
#ifdef __cplusplus
extern
"C"
{
#endif
#include <miniaudio.h>
typedef
struct
{
ma_data_source_base
ds
;
/* The libopus 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. */
/*OggOpusFile**/
void
*
of
;
/* Typed as void* so we can avoid a dependency on opusfile in the header section. */
}
ma_libopus
;
MA_API
ma_result
ma_libopus_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_libopus
*
pOpus
);
MA_API
ma_result
ma_libopus_init_file
(
const
char
*
pFilePath
,
const
ma_decoding_backend_config
*
pConfig
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
,
ma_libopus
*
pOpus
);
MA_API
void
ma_libopus_uninit
(
ma_libopus
*
pOpus
,
const
ma_allocation_callbacks
*
pAllocationCallbacks
);
MA_API
ma_result
ma_libopus_read_pcm_frames
(
ma_libopus
*
pOpus
,
void
*
pFramesOut
,
ma_uint64
frameCount
,
ma_uint64
*
pFramesRead
);
MA_API
ma_result
ma_libopus_seek_to_pcm_frame
(
ma_libopus
*
pOpus
,
ma_uint64
frameIndex
);
MA_API
ma_result
ma_libopus_get_data_format
(
ma_libopus
*
pOpus
,
ma_format
*
pFormat
,
ma_uint32
*
pChannels
,
ma_uint32
*
pSampleRate
,
ma_channel
*
pChannelMap
,
size_t
channelMapCap
);
MA_API
ma_result
ma_libopus_get_cursor_in_pcm_frames
(
ma_libopus
*
pOpus
,
ma_uint64
*
pCursor
);
MA_API
ma_result
ma_libopus_get_length_in_pcm_frames
(
ma_libopus
*
pOpus
,
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_libopus
;
#ifdef __cplusplus
}
#endif
#endif
/* miniaudio_libopus_h */
miniaudio/miniaudio_libvorbis.c
0 → 100644
View file @
9a36ca40
#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
)
{
ma_result
result
;
ma_data_source_config
dataSourceConfig
;
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. */
}
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. */
}
#if !defined(MA_NO_LIBVORBIS)
{
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. */
result
=
ma_libvorbis_init_internal
(
pConfig
,
pAllocationCallbacks
,
pVorbis
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
}
if
(
onRead
==
NULL
||
onSeek
==
NULL
)
{
return
MA_INVALID_ARGS
;
/* onRead and onSeek are mandatory. */
}
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
)
{
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
)
{
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)
{
/* I don't know how to reliably retrieve the length in frames using libvorbis, so returning 0 for now. */
*
pLength
=
0
;
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 */
miniaudio/miniaudio_libvorbis.h
0 → 100644
View file @
9a36ca40
/*
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 */
ocgcore
@
d2c75412
Subproject commit
fe48b4fbbf9c84c459eca432de494a5bcef1c276
Subproject commit
d2c754121645fb021de5dc7d7f13f0a4210f5d9e
premake/miniaudio/premake5.lua
0 → 100644
View file @
9a36ca40
project
"miniaudio"
kind
"StaticLib"
files
{
"*.c"
,
"*.h"
}
files
{
"external/ogg/src/**.c"
,
"external/ogg/src/**.h"
}
files
{
"external/opus/src/**.c"
,
"external/opus/src/**.h"
}
files
{
"external/opus/celt/*.c"
,
"external/opus/celt/*.h"
}
files
{
"external/opus/silk/*.c"
,
"external/opus/silk/*.h"
}
files
{
"external/opus/silk/float/*.c"
,
"external/opus/silk/float/*.h"
}
files
{
"external/opusfile/src/**.c"
,
"external/opusfile/src/**.h"
}
files
{
"external/vorbis/lib/**.c"
,
"external/vorbis/lib/**.h"
}
removefiles
{
"external/opus/src/opus_demo.c"
,
"external/opus/src/tone.c"
,
"external/opus/src/opus_encoder.c"
,
"external/vorbis/lib/psy.h"
,
"external/vorbis/lib/psytune.c"
,
"external/vorbis/lib/tone.c"
,}
defines
{
"USE_ALLOCA"
,
"OPUS_BUILD"
}
includedirs
{
"."
,
"external/ogg/include"
,
"external/opus/include"
,
"external/opus/celt"
,
"external/opus/silk"
,
"external/opus/silk/float"
,
"external/opusfile/include"
,
"external/vorbis/include"
}
filter
"system:linux"
links
{
"dl"
,
"pthread"
,
"m"
}
premake5.lua
View file @
9a36ca40
...
...
@@ -199,6 +199,6 @@ workspace "YGOPro"
if
BUILD_SQLITE
then
include
"sqlite3"
end
--if BUILD_IKPMP3
then
-- include "ikpmp3
"
--
end
if
USE_AUDIO
then
include
"miniaudio
"
end
script
@
f10071b5
Subproject commit
5d9d3779b34df5937ea9db039b68e6e440d461ec
Subproject commit
f10071b5d60b728dda89d2d9dffb8d345d3efba1
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment