Skip to content

Commit

Permalink
fix single_file building, optimise audio sample callback, remove "deb…
Browse files Browse the repository at this point in the history
…ugger"

removed the debugger because it was not finished and pretty useless.

optimised the audio callback as now you can pass in a buffer which the core will first fill
and then call the callback. this reduces function call overhead.

added basic mixer function to the core for s16 output.
tis function will be improved for accuracy eventually with proper mixing as
it is unlikely that each channel is perfectly mixed (see NES APU).
  • Loading branch information
ITotalJustice committed Dec 24, 2022
1 parent c39a5a5 commit 8b51c35
Show file tree
Hide file tree
Showing 29 changed files with 115 additions and 2,515 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ option(SWITCH "build switch" OFF)
option(SDL "build sdl frontend" OFF)
option(SDL2 "build sdl2 frontend" OFF)
option(LIBRETRO "build libretro core" OFF)
option(DEBUGGER "build debugger" OFF)

option(SMS_SINGLE_FILE "include all src in single.c" OFF)
option(SMS_DEBUG "enable debug" OFF)
Expand Down
14 changes: 0 additions & 14 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@
"SMS_DEV": true
}
},
{
"name": "debugger",
"displayName": "debugger",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"LTO": true,
"DEBUGGER": true
}
},
{
"name": "dreamcast",
"displayName": "dreamcast build",
Expand Down Expand Up @@ -184,10 +174,6 @@
"name": "sdl2-dev",
"configurePreset": "sdl2-dev"
},
{
"name": "debugger",
"configurePreset": "debugger"
},
{
"name": "dreamcast",
"configurePreset": "dreamcast"
Expand Down
5 changes: 0 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,6 @@ if (PLATFORM_N64)
add_subdirectory(platforms/n64)
endif()

if (DEBUGGER)
add_subdirectory(platforms/debugger)
set(USE_MGB ON)
endif()

if (PLATFORM_EMSCRIPTEN)
add_subdirectory(platforms/emscripten)
set(USE_MGB ON)
Expand Down
7 changes: 5 additions & 2 deletions src/core/sms.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,16 @@ void SMS_set_userdata(struct SMS_Core* sms, void* userdata)
sms->userdata = userdata;
}

void SMS_set_apu_callback(struct SMS_Core* sms, sms_apu_callback_t cb, uint32_t freq)
void SMS_set_apu_callback(struct SMS_Core* sms, sms_apu_callback_t cb, struct SMS_ApuSample* samples, uint32_t size, uint32_t freq)
{
// avoid div by 0
if (cb && freq)
if (cb && samples && size && freq)
{
sms->apu_callback = cb;
sms->apu_callback_freq = (SMS_CPU_CLOCK / freq);
sms->apu_samples = samples;
sms->apu_sample_size = size;
sms->apu_sample_index = 0;
}
else
{
Expand Down
11 changes: 10 additions & 1 deletion src/core/sms.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ bool SMS_used_sram(const struct SMS_Core* sms);

void SMS_skip_frame(struct SMS_Core* sms, bool enable);
void SMS_set_pixels(struct SMS_Core* sms, void* pixels, uint16_t pitch, uint8_t bpp);
void SMS_set_apu_callback(struct SMS_Core* sms, sms_apu_callback_t cb, uint32_t freq);
void SMS_set_apu_callback(struct SMS_Core* sms, sms_apu_callback_t cb, struct SMS_ApuSample* samples, uint32_t size, uint32_t freq);
void SMS_set_vblank_callback(struct SMS_Core* sms, sms_vblank_callback_t cb);
void SMS_set_colour_callback(struct SMS_Core* sms, sms_colour_callback_t cb);
void SMS_set_userdata(struct SMS_Core* sms, void* userdata);
Expand All @@ -40,6 +40,15 @@ bool SMS_loadstate(struct SMS_Core* sms, const struct SMS_State* state);
// setting this to true will re-enable better drums!
void SMS_set_better_drums(struct SMS_Core* sms, bool enable);

/**
* @brief mixes samples into s16 stereo format
*
* @param samples the sample buffer
* @param output number of entires must be count*2
* @param count number of samples
*/
void SMS_apu_mixer_s16(const struct SMS_ApuSample* samples, int16_t* output, uint32_t count);

void SMS_set_system_type(struct SMS_Core* sms, enum SMS_System system);
enum SMS_System SMS_get_system_type(const struct SMS_Core* sms);
bool SMS_is_system_type_sms(const struct SMS_Core* sms);
Expand Down
58 changes: 49 additions & 9 deletions src/core/sms_psg.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,21 +192,61 @@ static FORCE_INLINE uint8_t sample_channel(struct SMS_Core* sms, const uint8_t i

static void sample(struct SMS_Core* sms)
{
if (sms->apu_sample_index >= sms->apu_sample_size)
{
sms->apu_callback(sms->userdata, sms->apu_samples, sms->apu_sample_size);
sms->apu_sample_index = 0;
}

// generate samples
const uint8_t tone0 = sample_channel(sms, 0);
const uint8_t tone1 = sample_channel(sms, 1);
const uint8_t tone2 = sample_channel(sms, 2);
// the noise channel sounds louder on actual console
const uint8_t noise = sample_channel(sms, 3);

struct SMS_ApuCallbackData data =
{
.tone0 = { tone0 * PSG.channel_enable[0][0], tone0 * PSG.channel_enable[0][1] },
.tone1 = { tone1 * PSG.channel_enable[1][0], tone1 * PSG.channel_enable[1][1] },
.tone2 = { tone2 * PSG.channel_enable[2][0], tone2 * PSG.channel_enable[2][1] },
.noise = { noise * PSG.channel_enable[3][0], noise * PSG.channel_enable[3][1] },
};
// apply stereo
struct SMS_ApuSample* sample = &sms->apu_samples[sms->apu_sample_index];
sample->tone0[0] = tone0 * PSG.channel_enable[0][0];
sample->tone0[1] = tone0 * PSG.channel_enable[0][1];
sample->tone1[0] = tone1 * PSG.channel_enable[1][0];
sample->tone1[1] = tone1 * PSG.channel_enable[1][1];
sample->tone2[0] = tone2 * PSG.channel_enable[2][0];
sample->tone2[1] = tone2 * PSG.channel_enable[2][1];
sample->noise[0] = noise * PSG.channel_enable[3][0];
sample->noise[1] = noise * PSG.channel_enable[3][1];

// next!
sms->apu_sample_index++;
}

static int16_t scale_psg_u8_to_s16(uint8_t input)
{
return ((input * 0xFFFFU) / 0xFU) ^ 0x8000U;
}

void SMS_apu_mixer_s16(const struct SMS_ApuSample* samples, int16_t* output, uint32_t count)
{
int16_t tone0;
int16_t tone1;
int16_t tone2;
int16_t noise;
uint32_t i;

sms->apu_callback(sms->userdata, &data);
for (i = 0; i < count; i++)
{
// left
tone0 = scale_psg_u8_to_s16(samples[i].tone0[0]);
tone1 = scale_psg_u8_to_s16(samples[i].tone1[0]);
tone2 = scale_psg_u8_to_s16(samples[i].tone2[0]);
noise = scale_psg_u8_to_s16(samples[i].noise[0]);
*output++ = (tone0 + tone1 + tone2 + noise) / 4;
// right
tone0 = scale_psg_u8_to_s16(samples[i].tone0[1]);
tone1 = scale_psg_u8_to_s16(samples[i].tone1[1]);
tone2 = scale_psg_u8_to_s16(samples[i].tone2[1]);
noise = scale_psg_u8_to_s16(samples[i].noise[1]);
*output++ = (tone0 + tone1 + tone2 + noise) / 4;
}
}

// this is called on psg_reg_write() and at the end of a frame
Expand Down
2 changes: 1 addition & 1 deletion src/core/sms_single.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "sms_bus.c"
#include "sms_z80.c"
#include "sms_joypad.c"
#include "sms_sms.c"
#include "sms.c"
#include "sms_psg.c"
#include "sms_vdp.c"
#include "sms_rom_database.c"
Expand Down
13 changes: 8 additions & 5 deletions src/core/sms_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ extern "C" {

// fwd
struct SMS_Ports;
struct SMS_ApuCallbackData;
struct SMS_ApuSample;
struct SMS_MemoryControlRegister;
struct SMS_Core;


// callback types
typedef void (*sms_apu_callback_t)(void* user, struct SMS_ApuCallbackData* data);
typedef void (*sms_apu_callback_t)(void* user, struct SMS_ApuSample* samples, uint32_t size);
typedef void (*sms_vblank_callback_t)(void* user);
typedef uint32_t (*sms_colour_callback_t)(void* user, uint8_t r, uint8_t g, uint8_t b);

Expand Down Expand Up @@ -337,7 +337,7 @@ struct SMS_Ports
uint8_t b;
};

struct SMS_ApuCallbackData
struct SMS_ApuSample
{
uint8_t tone0[2];
uint8_t tone1[2];
Expand Down Expand Up @@ -421,8 +421,11 @@ struct SMS_Core
sms_apu_callback_t apu_callback;
void* userdata;

uint32_t apu_callback_freq;
uint32_t apu_callback_counter;
struct SMS_ApuSample* apu_samples; // sample buffer
uint32_t apu_sample_size; // number of samples
uint32_t apu_sample_index; // index into the buffer
uint32_t apu_callback_freq; // sample rate
uint32_t apu_callback_counter; // how many cpu cycles until sample

// enable to have better sounding drums in most games!
bool better_drums;
Expand Down
76 changes: 0 additions & 76 deletions src/platforms/debugger/CMakeLists.txt

This file was deleted.

Loading

0 comments on commit 8b51c35

Please sign in to comment.