Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/emuwiki-api-doc/Mupen64Plus-v2.0-API-Versioning.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ This is the most complicated interface, because it involves 3 components: the vi
* '''FRONTEND_API_VERSION''' version 2.1.1:
** Core command M64CMD_CORE_STATE_SET will now accept M64CORE_VIDEO_SIZE parameter
*** will call the video plugin function ResizeVideoOutput()
* '''FRONTEND_API_VERSION''' version 2.1.2:
** added "m64p_command" types:
*** M64CMD_SET_AUDIO_INTERFACE_BACKEND
* '''CONFIG_API_VERSION''' version 2.1.0:
** add new function "ConfigSaveSection()" to save only a single config section to disk
* '''CONFIG_API_VERSION''' version 2.2.0:
Expand Down
6 changes: 6 additions & 0 deletions doc/emuwiki-api-doc/Mupen64Plus-v2.0-Core-Front-End.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ Most libmupen64plus functions return an <tt>m64p_error</tt> return code, which i
|Advance one frame (the emulator will run until the next frame, then pause).
|'''<tt>ParamInt</tt>''' Ignored'''<br /><tt>ParamPtr</tt>''' Ignored
|The emulator must be currently running or paused.
|-
|M64CMD_SET_AUDIO_INTERFACE_BACKEND
|This command allow the frontend to specify the audio backend to be used by the AI controller.
|'''<tt>ParamPtr</tt>''' is a pointer to the m64p_audio_backend structure (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) to be used. If any of the function pointers in the structure are NULL, a dummy backend will be used (eg no sound). For now, usage of audio backends is optional and as such, a frontend is not required to use this command. In this case, the core will use the audio plugin mechanism to play sound. However, we encourage frontend writers to consider this new mechanism over audio plugins which may be deprecated in the future.
'''<tt>ParamInt</tt>''' is the version of the m64p_audio_backend structure. This should be M64P_AUDIO_BACKEND_VERSION
|
|}
<br />

Expand Down
34 changes: 34 additions & 0 deletions doc/emuwiki-api-doc/Mupen64Plus-v2.0-headers.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,37 @@
m64p_error (*VidExtFuncResizeWindow)(int, int);
} m64p_video_extension_functions;

/* ------------------------------------------ */
/* Structures and Types for Audio Backend API */
/* ------------------------------------------ */

/* Audio backend object
*
* user_data is a pointer which will be passed as the first argument of audio backend functions.
* Frontend writers are free to use it as they please.
*
* set_audio_format function allows the audio backend to be notified of the format of incoming samples.
* 2nd parameter frequency is the sample rate of incoming samples.
* 3rd parameter bits is the sample resolution (usually 16 bits)
*
* This function should be called by the core at least one time before any call to "push_audio_samples".
* Audio backends are expected to handle gracefully eventual changes of audio format
* even after this "initial" setup. Though in practice, very few games, if any,
* changes the audio format after the initial setup.
*
* push_audio_samples function notifies the audio backend of new samples ready to be played.
* 2nd parameter buffer is a pointer to the beginning of the incoming samples.
* 3rd parameter size is the size in bytes of the buffer.
*
* Samples are in stereo interleaved format (LR LR LR ...) and their resolution (bits per channel)
* is specified by prior calls of set_audio_format.
* Audio backends are expected not to block during the servicing of this function.
* We invite audio backends writers to buffer (and maybe resample) the incoming samples
* and return control to the core as soon as possible.
*/
struct m64p_audio_backend
{
void* user_data;
void (*set_audio_format)(void*, unsigned int, unsigned int);
void (*push_audio_samples)(void*, const void*, size_t);
};
6 changes: 5 additions & 1 deletion projects/VisualStudio2013/mupen64plus-core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<ItemGroup>
<ClCompile Include="..\..\src\ai\ai_controller.c" />
<ClCompile Include="..\..\src\api\callbacks.c" />
<ClCompile Include="..\..\src\api\audio_backend.c" />
<ClCompile Include="..\..\src\api\common.c" />
<ClCompile Include="..\..\src\api\config.c" />
<ClCompile Include="..\..\src\api\debugger.c" />
Expand Down Expand Up @@ -70,6 +71,7 @@
<ClCompile Include="..\..\src\pi\flashram.c" />
<ClCompile Include="..\..\src\pi\pi_controller.c" />
<ClCompile Include="..\..\src\pi\sram.c" />
<ClCompile Include="..\..\src\plugin\audio_backend_compat.c" />
<ClCompile Include="..\..\src\plugin\dummy_audio.c" />
<ClCompile Include="..\..\src\plugin\dummy_input.c" />
<ClCompile Include="..\..\src\plugin\dummy_rsp.c" />
Expand Down Expand Up @@ -285,6 +287,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\ai\ai_controller.h" />
<ClInclude Include="..\..\src\api\audio_backend.h" />
<ClInclude Include="..\..\src\api\callbacks.h" />
<ClInclude Include="..\..\src\api\config.h" />
<ClInclude Include="..\..\src\api\debugger.h" />
Expand Down Expand Up @@ -335,6 +338,7 @@
<ClInclude Include="..\..\src\pi\flashram.h" />
<ClInclude Include="..\..\src\pi\pi_controller.h" />
<ClInclude Include="..\..\src\pi\sram.h" />
<ClInclude Include="..\..\src\plugin\audio_backend_compat.h" />
<ClInclude Include="..\..\src\plugin\dummy_audio.h" />
<ClInclude Include="..\..\src\plugin\dummy_input.h" />
<ClInclude Include="..\..\src\plugin\dummy_rsp.h" />
Expand Down Expand Up @@ -647,4 +651,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
3 changes: 2 additions & 1 deletion projects/unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ OBJDIR = _obj$(POSTFIX)
# list of required source files for compilation
SOURCE = \
$(SRCDIR)/ai/ai_controller.c \
$(SRCDIR)/api/audio_backend.c \
$(SRCDIR)/api/callbacks.c \
$(SRCDIR)/api/common.c \
$(SRCDIR)/api/config.c \
Expand All @@ -439,7 +440,7 @@ SOURCE = \
$(SRCDIR)/pi/pi_controller.c \
$(SRCDIR)/pi/sram.c \
$(SRCDIR)/plugin/emulate_game_controller_via_input_plugin.c \
$(SRCDIR)/plugin/emulate_speaker_via_audio_plugin.c \
$(SRCDIR)/plugin/audio_backend_compat.c \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it silly to have a distinct folder plugin and backend? As the new backend approach is supposed to take away the concept of plugin, I just ask.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put the audio_backend_compat in the plugin folder because it is related to plugins, and will also go away when plugins are dropped.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! Sorry for the bad idea. ^^'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't worry about asking questions even if you think they are "bad idea".
I'm am not perfect and I make mistake very often, so I'm glad someone look at my work and question it. That way if I have overlooked something I can correct it. Otherwise if it's not a mistake on my part, I can justify why I did it that way, so it helps other to understand my work.

$(SRCDIR)/plugin/get_time_using_C_localtime.c \
$(SRCDIR)/plugin/rumble_via_input_plugin.c \
$(SRCDIR)/plugin/plugin.c \
Expand Down
18 changes: 4 additions & 14 deletions src/ai/ai_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "ai_controller.h"

#include "api/audio_backend.h"
#include "main/rom.h"
#include "memory/memory.h"
#include "r4300/r4300_core.h"
Expand Down Expand Up @@ -81,13 +82,13 @@ static void do_dma(struct ai_controller* ai, const struct ai_dma* dma)
? 16
: 1 + ai->regs[AI_BITRATE_REG];

set_audio_format(ai, frequency, bits);
set_audio_format(&ai->backend, frequency, bits);

ai->samples_format_changed = 0;
}

/* push audio samples to external sink */
push_audio_samples(ai, &ai->ri->rdram.dram[dma->address/4], dma->length);
/* push audio samples to audio backend */
push_audio_samples(&ai->backend, &ai->ri->rdram.dram[dma->address/4], dma->length);

/* schedule end of dma event */
update_count();
Expand Down Expand Up @@ -134,17 +135,6 @@ static void fifo_pop(struct ai_controller* ai)
}


void set_audio_format(struct ai_controller* ai, unsigned int frequency, unsigned int bits)
{
ai->set_audio_format(ai->user_data, frequency, bits);
}

void push_audio_samples(struct ai_controller* ai, const void* buffer, size_t size)
{
ai->push_audio_samples(ai->user_data, buffer, size);
}


void connect_ai(struct ai_controller* ai,
struct r4300_core* r4300,
struct ri_controller* ri,
Expand Down
9 changes: 3 additions & 6 deletions src/ai/ai_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef M64P_AI_AI_CONTROLLER_H
#define M64P_AI_AI_CONTROLLER_H

#include "api/m64p_types.h"

#include <stddef.h>
#include <stdint.h>

Expand Down Expand Up @@ -53,10 +55,7 @@ struct ai_controller
struct ai_dma fifo[2];
unsigned int samples_format_changed;

/* external speaker output */
void* user_data;
void (*set_audio_format)(void*,unsigned int, unsigned int);
void (*push_audio_samples)(void*,const void*,size_t);
struct m64p_audio_backend backend;

struct r4300_core* r4300;
struct ri_controller* ri;
Expand All @@ -68,8 +67,6 @@ static uint32_t ai_reg(uint32_t address)
return (address & 0xffff) >> 2;
}

void set_audio_format(struct ai_controller* ai, unsigned int frequency, unsigned int bits);
void push_audio_samples(struct ai_controller* ai, const void* buffer, size_t size);

void connect_ai(struct ai_controller* ai,
struct r4300_core* r4300,
Expand Down
83 changes: 83 additions & 0 deletions src/api/audio_backend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - audio_backend.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2015 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "audio_backend.h"

#include "api/m64p_types.h"
#include "ai/ai_controller.h"

#include <string.h>

extern struct ai_controller g_ai;


/* Dummy Audio Backend object */
static void set_audio_format_dummy(void* user_data, unsigned int frequency, unsigned int bits)
{
}

static void push_audio_samples_dummy(void* user_data, const void* buffer, size_t size)
{
}

const struct m64p_audio_backend AUDIO_BACKEND_DUMMY =
{
NULL,
set_audio_format_dummy,
push_audio_samples_dummy
};


/* Global function for use by frontend.c */
m64p_error SetAudioInterfaceBackend(unsigned int version, const struct m64p_audio_backend* backend)
{
/* check input data */
if (backend == NULL)
return M64ERR_INPUT_ASSERT;

/* check backend version */
if (version != M64P_AUDIO_BACKEND_VERSION)
return M64ERR_INCOMPATIBLE;

/* if any of the function pointers are NULL, use the dummy audio backend */
if (backend->set_audio_format == NULL ||
backend->push_audio_samples == NULL)
{
backend = &AUDIO_BACKEND_DUMMY;
}

/* otherwise use the user provided backend */
memcpy(&g_ai.backend, backend, sizeof(struct m64p_audio_backend));

return M64ERR_SUCCESS;
}


/* Thin wrappers to ease usage of backend callbacks - used by ai_controller.c */
void set_audio_format(struct m64p_audio_backend* backend, unsigned int frequency, unsigned int bits)
{
backend->set_audio_format(backend->user_data, frequency, bits);
}

void push_audio_samples(struct m64p_audio_backend* backend, const void* buffer, size_t size)
{
backend->push_audio_samples(backend->user_data, buffer, size);
}
43 changes: 43 additions & 0 deletions src/api/audio_backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - audio_backend.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2015 Bobby Smiles *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* This file contains the definitions for the audio backend functions which
* will be called from other Core modules.
*/

#if !defined(M64P_API_AUDIO_BACKEND_H)
#define M64P_API_AUDIO_BACKEND_H

#include "m64p_types.h"

#include <stddef.h>

/* Dummy Audio Backend object */
extern const struct m64p_audio_backend AUDIO_BACKEND_DUMMY;

/* Global function for use by frontend.c */
m64p_error SetAudioInterfaceBackend(unsigned int version, const struct m64p_audio_backend* backend);

/* Thin wrappers to ease usage of backend callbacks - used by ai_controller.c */
void set_audio_format(struct m64p_audio_backend* backend, unsigned int frequency, unsigned int bits);
void push_audio_samples(struct m64p_audio_backend* backend, const void* buffer, size_t size);

#endif /* M64P_API_AUDIO_BACKEND_H */
7 changes: 7 additions & 0 deletions src/api/frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "callbacks.h"
#include "m64p_config.h"
#include "m64p_frontend.h"
#include "audio_backend.h"
#include "config.h"
#include "vidext.h"

Expand All @@ -47,6 +48,7 @@
#include "main/workqueue.h"
#include "osd/screenshot.h"
#include "plugin/plugin.h"
#include "plugin/audio_backend_compat.h"

/* some local state variables */
static int l_CoreInit = 0;
Expand Down Expand Up @@ -78,6 +80,9 @@ EXPORT m64p_error CALL CoreStartup(int APIVersion, const char *ConfigPath, const
plugin_connect(M64PLUGIN_INPUT, NULL);
plugin_connect(M64PLUGIN_CORE, NULL);

/* set default AI backend */
SetAudioInterfaceBackend(M64P_AUDIO_BACKEND_VERSION, &AUDIO_BACKEND_COMPAT);

savestates_init();

/* next, start up the configuration handling code by loading and parsing the config file */
Expand Down Expand Up @@ -291,6 +296,8 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P
return M64ERR_INVALID_STATE;
main_advance_one();
return M64ERR_SUCCESS;
case M64CMD_SET_AUDIO_INTERFACE_BACKEND:
return SetAudioInterfaceBackend(ParamInt, ParamPtr);
default:
return M64ERR_INPUT_INVALID;
}
Expand Down
Loading