Initial spindle emulation working for windows atleast

This commit is contained in:
Toni Riikonen
2025-09-06 17:35:16 +03:00
parent fb91158f5a
commit e07043bab5
24 changed files with 419 additions and 60 deletions

BIN
86box/86Box.exe Normal file

Binary file not shown.

0
src/.vs/CMake Overview Normal file
View File

View File

@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": "x64-Debug"
}

View File

@@ -0,0 +1,12 @@
{
"OutputFoldersPerTargetSystem": {
"Local Machine": [
"out\\build\\x64-Debug",
"out\\install\\x64-Debug"
]
},
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}

BIN
src/.vs/slnx.sqlite Normal file

Binary file not shown.

BIN
src/.vs/src/v17/.wsuo Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,61 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\msys64\\home\\dompp\\86Box\\src\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|D:\\msys64\\home\\dompp\\86Box\\src\\CMakeSettings.json||{10608CD5-279C-4A28-BD5F-BA2CFCE06219}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:CMakeSettings.json||{10608CD5-279C-4A28-BD5F-BA2CFCE06219}"
},
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|CMake Overview Pages||{B1CAA5B0-FEB1-4350-8AB9-F895876842F2}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 3,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{65ddf8c3-8f89-4077-a6c6-dbb8853aab13}"
},
{
"$type": "Bookmark",
"Name": "ST:11:0:{2456bd12-ecf7-4988-a4a6-67d49173f565}"
},
{
"$type": "Bookmark",
"Name": "ST:12:0:{2456bd12-ecf7-4988-a4a6-67d49173f565}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CMakeSettings.json",
"DocumentMoniker": "D:\\msys64\\home\\dompp\\86Box\\src\\CMakeSettings.json",
"RelativeDocumentMoniker": "CMakeSettings.json",
"ToolTip": "D:\\msys64\\home\\dompp\\86Box\\src\\CMakeSettings.json",
"RelativeToolTip": "CMakeSettings.json",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
"WhenOpened": "2025-08-30T19:09:23.796Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "CMake Overview Pages",
"DocumentMoniker": "CMake Overview Pages",
"ToolTip": "CMake Overview Pages",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
"WhenOpened": "2025-08-30T19:09:12.336Z",
"EditorCaption": ""
}
]
}
]
}
]
}

Binary file not shown.

15
src/CMakeSettings.json Normal file
View File

@@ -0,0 +1,15 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
}
]
}

View File

@@ -23,6 +23,8 @@
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/timer.h>
@@ -39,6 +41,43 @@
#include <86box/fdd_mfm.h>
#include <86box/fdd_td0.h>
#include <86box/fdc.h>
#include <86box/sound.h>
static int16_t *load_wav(const char *filename, int *sample_count);
// TODO:
// 1. Implement spindle motor spin-up and spin-down
// 2. Implement sound support for all drives (not only for drive 0)
static int16_t *spindlemotor_wav = NULL;
static int spindlemotor_wav_samples = 0;
static char *spindlemotor_wav_filename = "mitsumi_spindle_motor_loop_48000_16_1_PCM.wav";
static int16_t *steptrackup_wav[80];
static int steptrackup_wav_samples[80];
static int16_t *steptrackdown_wav[80];
static int steptrackdown_wav_samples[80];
static int16_t *seekmultipletracks_wav[79]; // Seek 2, 3, 4 ... 80 tracks = 79 sounds
static int seekmultipletracks_wav_samples[79];
static int spindlemotor_pos[FDD_NUM] = {};
static int spindlemotor_playing[FDD_NUM] = {};
// WAV-header
typedef struct {
char riff[4];
uint32_t size;
char wave[4];
char fmt[4];
uint32_t fmt_size;
uint16_t audio_format;
uint16_t num_channels;
uint32_t sample_rate;
uint32_t byte_rate;
uint16_t block_align;
uint16_t bits_per_sample;
char data[4];
uint32_t data_size;
} wav_header_t;
/* Flags:
Bit 0: 300 rpm supported;
@@ -461,8 +500,6 @@ fdd_load(int drive, char *fn)
FILE *fp;
int offs = 0;
fdd_log("FDD: loading drive %d with '%s'\n", drive, fn);
if (!fn)
return;
if (strstr(fn, "wp://") == fn) {
@@ -495,7 +532,6 @@ fdd_load(int drive, char *fn)
c++;
}
}
fdd_log("FDD: could not load '%s' %s\n", fn, p);
drive_empty[drive] = 1;
fdd_set_head(drive, 0);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
@@ -505,8 +541,6 @@ fdd_load(int drive, char *fn)
void
fdd_close(int drive)
{
fdd_log("FDD: closing drive %d\n", drive);
d86f_stop(drive); /* Call this first of all to make sure the 86F poll is back to idle state. */
if (loaders[driveloaders[drive]].close)
loaders[driveloaders[drive]].close(drive);
@@ -548,11 +582,16 @@ fdd_byteperiod(int drive)
void
fdd_set_motor_enable(int drive, int motor_enable)
{
/* I think here is where spin-up and spin-down should be implemented. */
if (motor_enable && !motoron[drive])
if (motor_enable && !motoron[drive]) {
// Motor starting up
spindlemotor_pos[drive] = 0;
spindlemotor_playing[drive] = 1;
timer_set_delay_u64(&fdd_poll_time[drive], fdd_byteperiod(drive));
else if (!motor_enable)
} else if (!motor_enable) {
// Motor stopping
spindlemotor_playing[drive] = 0;
timer_disable(&fdd_poll_time[drive]);
}
motoron[drive] = motor_enable;
}
@@ -675,10 +714,14 @@ fdd_init(void)
{
int i;
spindlemotor_wav = load_wav(spindlemotor_wav_filename, &spindlemotor_wav_samples);
for (i = 0; i < FDD_NUM; i++) {
drives[i].poll = 0;
drives[i].seek = 0;
drives[i].readsector = 0;
spindlemotor_pos[i] = 0;
spindlemotor_playing[i] = 0;
}
img_init();
@@ -690,6 +733,8 @@ fdd_init(void)
for (i = 0; i < FDD_NUM; i++) {
fdd_load(i, floppyfns[i]);
}
sound_fdd_thread_init();
}
void
@@ -697,3 +742,113 @@ fdd_do_writeback(int drive)
{
d86f_handler[drive].writeback(drive);
}
static int16_t *
load_wav(const char *filename, int *sample_count)
{
FILE *f = fopen(filename, "rb");
if (!f) {
return NULL;
}
wav_header_t hdr;
if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
fclose(f);
return NULL;
}
if (memcmp(hdr.riff, "RIFF", 4) || memcmp(hdr.wave, "WAVE", 4) || memcmp(hdr.fmt, "fmt ", 4) || memcmp(hdr.data, "data", 4)) {
fclose(f);
return NULL;
}
// Accept both mono and stereo, 16-bit PCM
if (hdr.audio_format != 1 || hdr.bits_per_sample != 16 || (hdr.num_channels != 1 && hdr.num_channels != 2)) {
fclose(f);
return NULL;
}
int input_samples = hdr.data_size / 2; // 2 bytes per sample
int16_t *input_data = malloc(hdr.data_size);
if (!input_data) {
fclose(f);
return NULL;
}
if (fread(input_data, 1, hdr.data_size, f) != hdr.data_size) {
free(input_data);
fclose(f);
return NULL;
}
fclose(f);
int16_t *output_data;
int output_samples;
if (hdr.num_channels == 1) {
// Convert mono to stereo
output_samples = input_samples; // Number of stereo sample pairs
output_data = malloc(input_samples * 2 * sizeof(int16_t)); // Allocate for stereo
if (!output_data) {
free(input_data);
return NULL;
}
// Convert mono to stereo by duplicating each sample
for (int i = 0; i < input_samples; i++) {
output_data[i * 2] = input_data[i]; // Left channel
output_data[i * 2 + 1] = input_data[i]; // Right channel
}
free(input_data);
} else {
// Already stereo
output_data = input_data;
output_samples = input_samples / 2; // Number of stereo sample pairs
}
if (sample_count)
*sample_count = output_samples;
return output_data;
}
void
fdd_audio_callback(int16_t *buffer, int length)
{
// Clear buffer
memset(buffer, 0, length * sizeof(int16_t));
// Check if any motor is running
int any_motor_running = 0;
for (int drive = 0; drive < FDD_NUM; drive++) {
if (motoron[drive]) {
any_motor_running = 1;
}
}
float *float_buffer = (float*)buffer;
int samples_in_buffer = length / 2;
if (any_motor_running && spindlemotor_wav && spindlemotor_wav_samples > 0) {
for (int i = 0; i < samples_in_buffer; i++) {
// Only for fdd0
int wav_pos = spindlemotor_pos[0];
// int16 -> float conversion
float left_sample = (float)spindlemotor_wav[wav_pos * 2] / 32768.0f;
float right_sample = (float)spindlemotor_wav[wav_pos * 2 + 1] / 32768.0f;
float_buffer[i * 2] = left_sample;
float_buffer[i * 2 + 1] = right_sample;
spindlemotor_pos[0]++;
// Loop back to beginning for sample, when end is reached
if (spindlemotor_pos[0] >= spindlemotor_wav_samples) {
spindlemotor_pos[0] = 0;
}
}
}
}

View File

@@ -109,6 +109,7 @@ extern void fdd_format(int drive, int side, int density, uint8_t fill);
extern int fdd_hole(int drive);
extern void fdd_stop(int drive);
extern void fdd_do_writeback(int drive);
extern void fdd_audio_callback(int16_t *buffer, int length);
extern int motorspin;
extern uint64_t motoron[FDD_NUM];

View File

@@ -103,12 +103,16 @@ extern void sound_card_reset(void);
extern void sound_cd_thread_end(void);
extern void sound_cd_thread_reset(void);
extern void sound_fdd_thread_init(void);
extern void sound_fdd_thread_end(void);
extern void closeal(void);
extern void inital(void);
extern void givealbuffer(const void *buf);
extern void givealbuffer_music(const void *buf);
extern void givealbuffer_wt(const void *buf);
extern void givealbuffer_cd(const void *buf);
extern void givealbuffer_fdd(const void *buf, const uint32_t size);
#define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base
#define sb_vibra16cl_onboard_relocate_base sb_vibra16s_onboard_relocate_base

View File

@@ -0,0 +1 @@
{"requests":[{"kind":"cache","version":2},{"kind":"cmakeFiles","version":1},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1}]}

View File

@@ -0,0 +1 @@
msvc_x64_x64

View File

@@ -38,14 +38,15 @@
#define I_WT 2
#define I_CD 3
#define I_MIDI 4
#define I_FDD 5
static int audio[5] = {-1, -1, -1, -1, -1};
static int audio[6] = {-1, -1, -1, -1, -1, -1};
#ifdef USE_NEW_API
static struct audio_swpar info[5];
#else
static audio_info_t info[5];
static audio_info_t info[6];
#endif
static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0};
static int freqs[6] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, SOUND_FREQ, 0};
void closeal(void){
int i;
@@ -152,6 +153,11 @@ void givealbuffer_wt(const void *buf){
void givealbuffer_cd(const void *buf){
givealbuffer_common(buf, I_CD, CD_BUFLEN << 1);
}
void givealbuffer_fdd(const void *buf, const uint32_t size){
givealbuffer_common(buf, I_FDD, (int) size);
}
void givealbuffer_midi(const void *buf, const uint32_t size){
givealbuffer_common(buf, I_MIDI, (int) size);
}

View File

@@ -41,8 +41,9 @@ ALuint buffers[4]; /* front and back buffers */
ALuint buffers_music[4]; /* front and back buffers */
ALuint buffers_wt[4]; /* front and back buffers */
ALuint buffers_cd[4]; /* front and back buffers */
ALuint buffers_fdd[4]; /* front and back buffers */
ALuint buffers_midi[4]; /* front and back buffers */
static ALuint source[5]; /* audio source */
static ALuint source[6]; /* audio source - CHANGED FROM 5 TO 6 */
static int midi_freq = 44100;
static int midi_buf_size = 4410;
@@ -99,8 +100,9 @@ closeal(void)
alSourceStopv(sources, source);
alDeleteSources(sources, source);
if (sources == 4)
if (sources >= 6)
alDeleteBuffers(4, buffers_midi);
alDeleteBuffers(4, buffers_fdd);
alDeleteBuffers(4, buffers_cd);
alDeleteBuffers(4, buffers_music);
alDeleteBuffers(4, buffers);
@@ -118,13 +120,15 @@ inital(void)
float *wt_buf = NULL;
float *cd_buf = NULL;
float *midi_buf = NULL;
float *fdd_buf = NULL;
int16_t *buf_int16 = NULL;
int16_t *music_buf_int16 = NULL;
int16_t *wt_buf_int16 = NULL;
int16_t *cd_buf_int16 = NULL;
int16_t *midi_buf_int16 = NULL;
int16_t *fdd_buf_int16 = NULL;
int init_midi = 0;
int init_midi = 0;
if (initialized)
return;
@@ -136,13 +140,14 @@ inital(void)
if ((strcmp(mdn, "none") != 0) && (strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME) != 0))
init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the
MIDI buffer and source, otherwise, do not. */
sources = 4 + !!init_midi;
sources = 5 + !!init_midi;
if (sound_is_float) {
buf = (float *) calloc((BUFLEN << 1), sizeof(float));
music_buf = (float *) calloc((MUSICBUFLEN << 1), sizeof(float));
wt_buf = (float *) calloc((WTBUFLEN << 1), sizeof(float));
cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float));
fdd_buf = (float *) calloc((BUFLEN << 1), sizeof(float));
if (init_midi)
midi_buf = (float *) calloc(midi_buf_size, sizeof(float));
} else {
@@ -150,48 +155,29 @@ inital(void)
music_buf_int16 = (int16_t *) calloc((MUSICBUFLEN << 1), sizeof(int16_t));
wt_buf_int16 = (int16_t *) calloc((WTBUFLEN << 1), sizeof(int16_t));
cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t));
fdd_buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t));
if (init_midi)
midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t));
}
alGenBuffers(4, buffers);
alGenBuffers(4, buffers_cd);
alGenBuffers(4, buffers_fdd);
alGenBuffers(4, buffers_music);
alGenBuffers(4, buffers_wt);
if (init_midi)
alGenBuffers(4, buffers_midi);
if (init_midi)
alGenSources(5, source);
else
alGenSources(4, source);
// Create sources: 0=main, 1=music, 2=wt, 3=cd, 4=fdd, 5=midi(optional)
alGenSources(sources, source);
alSource3f(source[0], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[0], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[0], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(source[1], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[1], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[1], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(source[2], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[2], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[2], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(source[3], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[3], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[3], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE);
if (init_midi) {
alSource3f(source[4], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[4], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[4], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[4], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[4], AL_SOURCE_RELATIVE, AL_TRUE);
// Initialize all sources
for (int i = 0; i < sources; i++) {
alSource3f(source[i], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSource3f(source[i], AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSource3f(source[i], AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSourcef(source[i], AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(source[i], AL_SOURCE_RELATIVE, AL_TRUE);
}
if (sound_is_float) {
@@ -199,6 +185,7 @@ inital(void)
memset(cd_buf, 0, CD_BUFLEN * 2 * sizeof(float));
memset(music_buf, 0, MUSICBUFLEN * 2 * sizeof(float));
memset(wt_buf, 0, WTBUFLEN * 2 * sizeof(float));
memset(fdd_buf, 0, BUFLEN * 2 * sizeof(float));
if (init_midi)
memset(midi_buf, 0, midi_buf_size * sizeof(float));
} else {
@@ -206,6 +193,7 @@ inital(void)
memset(cd_buf_int16, 0, CD_BUFLEN * 2 * sizeof(int16_t));
memset(music_buf_int16, 0, MUSICBUFLEN * 2 * sizeof(int16_t));
memset(wt_buf_int16, 0, WTBUFLEN * 2 * sizeof(int16_t));
memset(fdd_buf_int16, 0, BUFLEN * 2 * sizeof(int16_t));
if (init_midi)
memset(midi_buf_int16, 0, midi_buf_size * sizeof(int16_t));
}
@@ -216,6 +204,7 @@ inital(void)
alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, music_buf, MUSICBUFLEN * 2 * sizeof(float), MUSIC_FREQ);
alBufferData(buffers_wt[c], AL_FORMAT_STEREO_FLOAT32, wt_buf, WTBUFLEN * 2 * sizeof(float), WT_FREQ);
alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ);
alBufferData(buffers_fdd[c], AL_FORMAT_STEREO_FLOAT32, fdd_buf, BUFLEN * 2 * sizeof(float), FREQ);
if (init_midi)
alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * (int) sizeof(float), midi_freq);
} else {
@@ -223,6 +212,7 @@ inital(void)
alBufferData(buffers_music[c], AL_FORMAT_STEREO16, music_buf_int16, MUSICBUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ);
alBufferData(buffers_wt[c], AL_FORMAT_STEREO16, wt_buf_int16, WTBUFLEN * 2 * sizeof(int16_t), WT_FREQ);
alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ);
alBufferData(buffers_fdd[c], AL_FORMAT_STEREO16, fdd_buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ);
if (init_midi)
alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * (int) sizeof(int16_t), midi_freq);
}
@@ -232,14 +222,17 @@ inital(void)
alSourceQueueBuffers(source[1], 4, buffers_music);
alSourceQueueBuffers(source[2], 4, buffers_wt);
alSourceQueueBuffers(source[3], 4, buffers_cd);
alSourceQueueBuffers(source[4], 4, buffers_fdd);
if (init_midi)
alSourceQueueBuffers(source[4], 4, buffers_midi);
alSourceQueueBuffers(source[5], 4, buffers_midi);
alSourcePlay(source[0]);
alSourcePlay(source[1]);
alSourcePlay(source[2]);
alSourcePlay(source[3]);
alSourcePlay(source[4]);
if (init_midi)
alSourcePlay(source[4]);
alSourcePlay(source[5]);
if (sound_is_float) {
if (init_midi)
@@ -248,6 +241,7 @@ inital(void)
free(wt_buf);
free(music_buf);
free(buf);
free(fdd_buf);
} else {
if (init_midi)
free(midi_buf_int16);
@@ -255,6 +249,7 @@ inital(void)
free(wt_buf_int16);
free(music_buf_int16);
free(buf_int16);
free(fdd_buf_int16);
}
initialized = 1;
@@ -319,5 +314,11 @@ givealbuffer_cd(const void *buf)
void
givealbuffer_midi(const void *buf, const uint32_t size)
{
givealbuffer_common(buf, 4, (int) size, midi_freq);
givealbuffer_common(buf, 5, (int) size, midi_freq);
}
void
givealbuffer_fdd(const void *buf, const uint32_t size)
{
givealbuffer_common(buf, 4, (int) size, FREQ);
}

View File

@@ -19,7 +19,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sndio.h>
#include <86box/86box.h>
@@ -31,10 +30,11 @@
#define I_WT 2
#define I_CD 3
#define I_MIDI 4
#define I_FDD 5
static struct sio_hdl* audio[5] = {NULL, NULL, NULL, NULL, NULL};
static struct sio_par info[5];
static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0};
static struct sio_hdl* audio[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
static struct sio_par info[6];
static int freqs[6] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, SOUND_FREQ, 0 };
void closeal(void){
int i;
@@ -131,9 +131,14 @@ void givealbuffer_wt(const void *buf){
void givealbuffer_cd(const void *buf){
givealbuffer_common(buf, I_CD, CD_BUFLEN << 1);
}
void givealbuffer_midi(const void *buf, const uint32_t size){
givealbuffer_common(buf, I_MIDI, (int) size);
}
void givealbuffer_fdd(const void *buf, const uint32_t size) {
givealbuffer_common(buf, I_FDD, (int) size);
}
void al_set_midi(const int freq, UNUSED(const int buf_size)){
freqs[I_MIDI] = freq;

View File

@@ -38,6 +38,7 @@
#include <86box/timer.h>
#include <86box/snd_mpu401.h>
#include <86box/sound.h>
#include <86box/fdd.h>
typedef struct {
const device_t *device;
@@ -55,7 +56,6 @@ int wavetable_pos_global = 0;
int sound_gain = 0;
static sound_handler_t sound_handlers[8];
static sound_handler_t music_handlers[8];
static sound_handler_t wavetable_handlers[8];
@@ -92,6 +92,13 @@ static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN;
static volatile int cdaudioon = 0;
static int cd_thread_enable = 0;
static thread_t *sound_fdd_thread_h;
static event_t *sound_fdd_event;
static event_t *sound_fdd_start_event;
static int16_t fdd_out_buffer[SOUNDBUFLEN * 2];
static volatile int fddaudioon = 0;
static int fdd_thread_enable = 0;
static void (*filter_cd_audio)(int channel, double *buffer, void *priv) = NULL;
static void *filter_cd_audio_p = NULL;
@@ -595,6 +602,9 @@ sound_poll(UNUSED(void *priv))
}
}
if (fdd_thread_enable) {
thread_set_event(sound_fdd_event);
}
sound_pos_global = 0;
}
}
@@ -696,17 +706,14 @@ sound_reset(void)
inital();
timer_add(&sound_poll_timer, sound_poll, NULL, 1);
sound_handlers_num = 0;
memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t));
timer_add(&music_poll_timer, music_poll, NULL, 1);
music_handlers_num = 0;
memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t));
timer_add(&wavetable_poll_timer, wavetable_poll, NULL, 1);
wavetable_handlers_num = 0;
memset(wavetable_handlers, 0x00, 8 * sizeof(sound_handler_t));
@@ -783,3 +790,67 @@ sound_cd_thread_reset(void)
cd_thread_enable = available_cdrom_drives ? 1 : 0;
}
static void
sound_fdd_clean_buffers(void)
{
memset(fdd_out_buffer, 0, SOUNDBUFLEN * 2);
}
static void
sound_fdd_thread(UNUSED(void *param))
{
thread_set_event(sound_fdd_start_event);
while (fddaudioon) {
thread_wait_event(sound_fdd_event, -1);
thread_reset_event(sound_fdd_event);
if (!fddaudioon)
break;
static float fdd_float_buffer[SOUNDBUFLEN * 2];
memset(fdd_float_buffer, 0, sizeof(fdd_float_buffer));
fdd_audio_callback((int16_t*)fdd_float_buffer, SOUNDBUFLEN * 2);
givealbuffer_fdd(fdd_float_buffer, SOUNDBUFLEN * 2);
}
}
void
sound_fdd_thread_init(void)
{
if (!fddaudioon) {
fddaudioon = 1;
fdd_thread_enable = 1;
sound_fdd_start_event = thread_create_event();
sound_fdd_event = thread_create_event();
sound_fdd_thread_h = thread_create(sound_fdd_thread, NULL);
thread_wait_event(sound_fdd_start_event, -1);
thread_reset_event(sound_fdd_start_event);
}
}
void
sound_fdd_thread_end(void)
{
if (fddaudioon) {
fddaudioon = 0;
fdd_thread_enable = 0;
thread_set_event(sound_fdd_event);
thread_wait(sound_fdd_thread_h);
if (sound_fdd_event) {
thread_destroy_event(sound_fdd_event);
sound_fdd_event = NULL;
}
sound_fdd_thread_h = NULL;
if (sound_fdd_start_event) {
thread_destroy_event(sound_fdd_start_event);
sound_fdd_start_event = NULL;
}
}
}

View File

@@ -55,6 +55,7 @@ static IXAudio2SourceVoice *srcvoicemusic = NULL;
static IXAudio2SourceVoice *srcvoicewt = NULL;
static IXAudio2SourceVoice *srcvoicemidi = NULL;
static IXAudio2SourceVoice *srcvoicecd = NULL;
static IXAudio2SourceVoice *srcvoicefdd = NULL;
#define FREQ SOUND_FREQ
#define BUFLEN SOUNDBUFLEN
@@ -184,11 +185,18 @@ inital(void)
(void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
fmt.nSamplesPerSec = FREQ;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
(void) IXAudio2_CreateSourceVoice(xaudio2, &srcvoicefdd, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
(void) IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_Start(srcvoicewt, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_Start(srcvoicefdd, 0, XAUDIO2_COMMIT_NOW);
const char *mdn = midi_out_device_get_internal_name(midi_output_device_current);
@@ -218,6 +226,8 @@ closeal(void)
(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicewt);
(void) IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd);
(void) IXAudio2SourceVoice_Stop(srcvoicefdd, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicefdd);
if (srcvoicemidi) {
(void) IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
(void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
@@ -225,13 +235,14 @@ closeal(void)
}
IXAudio2SourceVoice_DestroyVoice(srcvoicewt);
IXAudio2SourceVoice_DestroyVoice(srcvoicecd);
IXAudio2SourceVoice_DestroyVoice(srcvoicefdd);
IXAudio2SourceVoice_DestroyVoice(srcvoicemusic);
IXAudio2SourceVoice_DestroyVoice(srcvoice);
IXAudio2MasteringVoice_DestroyVoice(mastervoice);
IXAudio2_Release(xaudio2);
srcvoice = srcvoicecd = srcvoicemidi = NULL;
mastervoice = NULL;
xaudio2 = NULL;
srcvoice = srcvoicecd = srcvoicemidi = srcvoicefdd = NULL;
mastervoice = NULL;
xaudio2 = NULL;
#if defined(_WIN32) && !defined(USE_FAUDIO)
dynld_close(xaudio2_handle);
@@ -291,6 +302,18 @@ givealbuffer_cd(const void *buf)
givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1);
}
void
givealbuffer_fdd(const void *buf, const uint32_t size)
{
if (!initialized)
return;
if (!srcvoicefdd)
return;
givealbuffer_common(buf, srcvoicefdd, size);
}
void
al_set_midi(const int freq, const int buf_size)
{
@@ -324,4 +347,4 @@ void
givealbuffer_midi(const void *buf, const uint32_t size)
{
givealbuffer_common(buf, srcvoicemidi, size);
}
}