Skip to content

Commit

Permalink
Add a new command to allow frontend to set their audio backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
bsmiles32 committed Mar 7, 2015
1 parent 9830461 commit fc5d4a4
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 6 deletions.
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
47 changes: 47 additions & 0 deletions src/api/audio_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,53 @@
#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 */
Expand Down
5 changes: 5 additions & 0 deletions src/api/audio_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@

#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);
Expand Down
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
6 changes: 5 additions & 1 deletion src/api/m64p_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ typedef enum {
M64CMD_CORE_STATE_SET,
M64CMD_READ_SCREEN,
M64CMD_RESET,
M64CMD_ADVANCE_FRAME
M64CMD_ADVANCE_FRAME,
M64CMD_SET_AUDIO_INTERFACE_BACKEND
} m64p_command;

typedef struct {
Expand Down Expand Up @@ -368,6 +369,9 @@ typedef struct {
/* Structures and Types for Audio Backend API */
/* ------------------------------------------ */

/* current version of audio backend API */
#define M64P_AUDIO_BACKEND_VERSION 1

/* Audio backend object
*
* user_data is a pointer which will be passed as the first argument of audio backend functions.
Expand Down
4 changes: 0 additions & 4 deletions src/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
#include "osd/screenshot.h"
#include "pi/pi_controller.h"
#include "plugin/plugin.h"
#include "plugin/audio_backend_compat.h"
#include "plugin/emulate_game_controller_via_input_plugin.h"
#include "plugin/get_time_using_C_localtime.h"
#include "plugin/rumble_via_input_plugin.h"
Expand Down Expand Up @@ -928,9 +927,6 @@ m64p_error main_run(void)
// setup rendering callback from video plugin to the core, for screenshots and On-Screen-Display
gfx.setRenderingCallback(video_plugin_render_callback);

/* connect external audio sink to AI component */
memcpy(&g_ai.backend, &AUDIO_BACKEND_COMPAT, sizeof(struct m64p_audio_backend));

/* connect external time source to AF_RTC component */
g_si.pif.af_rtc.user_data = NULL;
g_si.pif.af_rtc.get_time = get_time_using_C_localtime;
Expand Down
2 changes: 1 addition & 1 deletion src/main/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define MUPEN_CORE_NAME "Mupen64Plus Core"
#define MUPEN_CORE_VERSION 0x020000

#define FRONTEND_API_VERSION 0x020101
#define FRONTEND_API_VERSION 0x020102
#define CONFIG_API_VERSION 0x020300
#define DEBUG_API_VERSION 0x020000
#define VIDEXT_API_VERSION 0x030000
Expand Down

0 comments on commit fc5d4a4

Please sign in to comment.