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
List
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
YGOPRO-520DIY
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
Hide 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 @@
...
@@ -30,6 +30,7 @@
/irrklang
/irrklang
/ikpmp3
/ikpmp3
/lua
/lua
/miniaudio
/sqlite3
/sqlite3
/gframe/*.ico
/gframe/*.ico
/gframe/ygopro.rc
/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
"lzma/."
include
"spmemvfs/."
include
"spmemvfs/."
if
USE_AUDIO
then
include
"miniaudio/."
end
project
"YGOPro"
project
"YGOPro"
kind
"WindowedApp"
kind
"WindowedApp"
...
@@ -43,7 +40,8 @@ project "YGOPro"
...
@@ -43,7 +40,8 @@ project "YGOPro"
if
USE_AUDIO
then
if
USE_AUDIO
then
defines
{
"YGOPRO_USE_AUDIO"
}
defines
{
"YGOPRO_USE_AUDIO"
}
links
{
"cminiaudio"
}
includedirs
{
"../miniaudio"
}
links
{
"miniaudio"
}
end
end
filter
"system:windows"
filter
"system:windows"
...
...
gframe/sound_manager.cpp
View file @
9a36ca40
#include "sound_manager.h"
#include "sound_manager.h"
#ifdef YGOPRO_USE_AUDIO
#include "../miniaudio/miniaudio_libvorbis.h"
#include "../miniaudio/miniaudio_libopus.h"
#endif
#include "myfilesystem.h"
#include "myfilesystem.h"
namespace
ygo
{
namespace
ygo
{
...
@@ -10,7 +14,21 @@ bool SoundManager::Init() {
...
@@ -10,7 +14,21 @@ bool SoundManager::Init() {
bgm_scene
=
-
1
;
bgm_scene
=
-
1
;
RefreshBGMList
();
RefreshBGMList
();
rnd
.
reset
((
unsigned
int
)
std
::
time
(
nullptr
));
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
;
return
false
;
}
else
{
}
else
{
return
true
;
return
true
;
...
...
gframe/sound_manager.h
View file @
9a36ca40
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
#include "game.h"
#include "game.h"
#include "../ocgcore/mtrandom.h"
#include "../ocgcore/mtrandom.h"
#ifdef YGOPRO_USE_AUDIO
#ifdef YGOPRO_USE_AUDIO
#include "miniaudio/miniaudio.h"
#include "
../
miniaudio/miniaudio.h"
#endif
#endif
namespace
ygo
{
namespace
ygo
{
...
@@ -15,6 +15,9 @@ private:
...
@@ -15,6 +15,9 @@ private:
int
bgm_scene
;
int
bgm_scene
;
mt19937
rnd
;
mt19937
rnd
;
#ifdef YGOPRO_USE_AUDIO
#ifdef YGOPRO_USE_AUDIO
ma_resource_manager_config
resourceManagerConfig
;
ma_resource_manager
resourceManager
;
ma_engine_config
engineConfig
;
ma_engine
engineSound
;
ma_engine
engineSound
;
ma_engine
engineMusic
;
ma_engine
engineMusic
;
ma_sound
soundBGM
;
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
...
@@ -52081,8 +52081,6 @@ static ma_result ma_decoder_init_mp3_from_memory__internal(const void* pData, si
#endif /* ma_dr_mp3_h */
#endif /* ma_dr_mp3_h */
/* Vorbis */
/* Vorbis */
// This is the line added by YGOPro
#include "stb_vorbis.c"
#ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
#ifdef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define MA_HAS_VORBIS
#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"
...
@@ -199,6 +199,6 @@ workspace "YGOPro"
if
BUILD_SQLITE
then
if
BUILD_SQLITE
then
include
"sqlite3"
include
"sqlite3"
end
end
--if BUILD_IKPMP3
then
if
USE_AUDIO
then
-- include "ikpmp3
"
include
"miniaudio
"
--
end
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