Teac 5.25" drive samples added. Added per drive audio selection to FDD settings.

This commit is contained in:
Toni Riikonen
2025-09-21 23:00:16 +03:00
parent 297660d7f8
commit 2763ea5ad3
12 changed files with 240 additions and 61 deletions

View File

@@ -1437,6 +1437,15 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
ini_section_delete_var(cat, temp);
}
sprintf(temp, "fdd_%02i_audio", c + 1);
int def_prof = FDD_AUDIO_PROFILE_NONE;
int prof = ini_section_get_int(cat, temp, def_prof);
if (prof < 0 || prof >= FDD_AUDIO_PROFILE_MAX)
prof = def_prof;
fdd_set_audio_profile(c, prof);
if (prof == def_prof)
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
fdd_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
@@ -3422,6 +3431,14 @@ save_floppy_and_cdrom_drives(void)
else
save_image_file(cat, temp, fdd_image_history[c][i]);
}
sprintf(temp, "fdd_%02i_audio", c + 1);
int def_prof = FDD_AUDIO_PROFILE_NONE;
int prof = fdd_get_audio_profile(c);
if (prof == def_prof)
ini_section_delete_var(cat, temp);
else
ini_section_set_int(cat, temp, prof);
}
for (c = 0; c < CDROM_NUM; c++) {

View File

@@ -89,6 +89,7 @@ pc_timer_t fdd_seek_timer[FDD_NUM];
static int fdd_notfound = 0;
static int driveloaders[FDD_NUM];
static int fdd_audio_profile[FDD_NUM] = { 0 };
int writeprot[FDD_NUM];
int fwriteprot[FDD_NUM];
@@ -223,6 +224,24 @@ fdd_log(const char *fmt, ...)
# define fdd_log(fmt, ...)
#endif
void
fdd_set_audio_profile(int drive, int profile)
{
if (drive < 0 || drive >= FDD_NUM)
return;
if (profile < 0 || profile >= FDD_AUDIO_PROFILE_MAX)
profile = 0;
fdd_audio_profile[drive] = profile;
}
int
fdd_get_audio_profile(int drive)
{
if (drive < 0 || drive >= FDD_NUM)
return 0;
return fdd_audio_profile[drive];
}
char *
fdd_getname(int type)
{

View File

@@ -62,37 +62,51 @@ typedef struct {
audio_sample_t multi_track_seek;
} drive_audio_samples_t;
/* 5.25" Teac FD-55GFR sample set */
static drive_audio_samples_t samples_teac = {
.spindlemotor_start = {
.filename = "TeacFD-55GFR_5.25_1.2MB_motor_start_48000_16_1_PCM.wav",
.buffer = NULL, .samples = 0, .volume = 3.0f
},
.spindlemotor_loop = {
.filename = "TeacFD-55GFR_5.25_1.2MB_motor_loop_48000_16_1_PCM.wav",
.buffer = NULL, .samples = 0, .volume = 3.0f
},
.spindlemotor_stop = {
.filename = "TeacFD-55GFR_5.25_1.2MB_motor_stop_48000_16_1_PCM.wav",
.buffer = NULL, .samples = 0, .volume = 3.0f
},
.single_track_step = {
.filename = "TeacFD-55GFR_5.25_1.2MB_track_step_48000_16_1_PCM.wav",
.buffer = NULL, .samples = 0, .volume = 2.0f
},
.multi_track_seek = {
.filename = "TeacFD-55GFR_5.25_1.2MB_seekupdown_80_tracks1100ms_48000_16_1_PCM.wav",
.buffer = NULL, .samples = 0, .volume = 2.0f
}
};
/* 3.5" drive audio samples (Mitsumi) */
static drive_audio_samples_t samples_35 = {
.spindlemotor_start = {
.filename = "mitsumi_spindle_motor_start_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 0.2f
.buffer = NULL, .samples = 0, .volume = 0.2f
},
.spindlemotor_loop = {
.filename = "mitsumi_spindle_motor_loop_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 0.2f
.buffer = NULL, .samples = 0, .volume = 0.2f
},
.spindlemotor_stop = {
.filename = "mitsumi_spindle_motor_stop_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 0.2f
.buffer = NULL, .samples = 0, .volume = 0.2f
},
.single_track_step = {
.filename = "mitsumi_track_step_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 1.0f
.buffer = NULL, .samples = 0, .volume = 1.0f
},
.multi_track_seek = {
.filename = "mitsumi_seek_80_tracks_495ms_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 1.0f
.buffer = NULL, .samples = 0, .volume = 1.0f
}
};
@@ -100,33 +114,23 @@ static drive_audio_samples_t samples_35 = {
static drive_audio_samples_t samples_525 = {
.spindlemotor_start = {
.filename = "Panasonic_JU-475-5_5.25_1.2MB_motor_start_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 1.0f
.buffer = NULL, .samples = 0, .volume = 1.0f
},
.spindlemotor_loop = {
.filename = "Panasonic_JU-475-5_5.25_1.2MB_motor_loop_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 1.0f
.buffer = NULL, .samples = 0, .volume = 1.0f
},
.spindlemotor_stop = {
.filename = "Panasonic_JU-475-5_5.25_1.2MB_motor_stop_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 1.0f
.buffer = NULL, .samples = 0, .volume = 1.0f
},
.single_track_step = {
.filename = "Panasonic_JU-475-5_5.25_1.2MB_track_step_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 2.0f
.buffer = NULL, .samples = 0, .volume = 2.0f
},
.multi_track_seek = {
.filename = "Panasonic_JU-475-5_5.25_1.2MB_seekup_40_tracks_285ms_5ms_per_track_48000_16_1_PCM.wav",
.buffer = NULL,
.samples = 0,
.volume = 2.0f
.buffer = NULL, .samples = 0, .volume = 2.0f
}
};
@@ -145,18 +149,24 @@ static multi_seek_state_t multi_seek_state[FDD_NUM] = {};
extern uint64_t motoron[FDD_NUM];
extern char exe_path[2048]; /* path (dir) of executable */
extern int fdd_get_audio_profile(int drive); /* from fdd.h */
/* Forward declaration */
static int16_t *load_wav(const char *filename, int *sample_count);
/* Helper function to get drive-specific audio samples */
static drive_audio_samples_t *
get_drive_samples(int drive)
{
/* Check if drive is 5.25" */
if (fdd_is_525(drive)) {
return &samples_525;
} else {
return &samples_35;
switch (fdd_get_audio_profile(drive)) {
case FDD_AUDIO_PROFILE_PANASONIC:
return &samples_525;
case FDD_AUDIO_PROFILE_TEAC:
return &samples_teac;
case FDD_AUDIO_PROFILE_MITSUMI:
return &samples_35;
default:
return NULL;
}
}
@@ -180,11 +190,13 @@ load_wav(const char *filename, int *sample_count)
}
}
path_append_filename(full_path, exe_path, "samples");
path_append_filename(full_path, exe_path, "roms");
path_append_filename(full_path, full_path, "samples");
path_append_filename(full_path, full_path, "fdd");
path_append_filename(full_path, full_path, filename);
f = fopen(full_path, "rb");
if (!f) {
path_append_filename(full_path, full_path, "samples");
path_append_filename(full_path, exe_path, filename);
f = fopen(full_path, "rb");
if (!f)
@@ -271,6 +283,12 @@ fdd_audio_init(void)
samples_525.single_track_step.buffer = load_wav(samples_525.single_track_step.filename, &samples_525.single_track_step.samples);
samples_525.multi_track_seek.buffer = load_wav(samples_525.multi_track_seek.filename, &samples_525.multi_track_seek.samples);
samples_teac.spindlemotor_start.buffer = load_wav(samples_teac.spindlemotor_start.filename, &samples_teac.spindlemotor_start.samples);
samples_teac.spindlemotor_loop.buffer = load_wav(samples_teac.spindlemotor_loop.filename, &samples_teac.spindlemotor_loop.samples);
samples_teac.spindlemotor_stop.buffer = load_wav(samples_teac.spindlemotor_stop.filename, &samples_teac.spindlemotor_stop.samples);
samples_teac.single_track_step.buffer = load_wav(samples_teac.single_track_step.filename, &samples_teac.single_track_step.samples);
samples_teac.multi_track_seek.buffer = load_wav(samples_teac.multi_track_seek.filename, &samples_teac.multi_track_seek.samples);
/* Initialize audio state for all drives */
for (i = 0; i < FDD_NUM; i++) {
spindlemotor_pos[i] = 0;
@@ -351,6 +369,32 @@ fdd_audio_close(void)
samples_525.multi_track_seek.samples = 0;
}
if (samples_teac.spindlemotor_start.buffer) {
free(samples_teac.spindlemotor_start.buffer);
samples_teac.spindlemotor_start.buffer = NULL;
samples_teac.spindlemotor_start.samples = 0;
}
if (samples_teac.spindlemotor_loop.buffer) {
free(samples_teac.spindlemotor_loop.buffer);
samples_teac.spindlemotor_loop.buffer = NULL;
samples_teac.spindlemotor_loop.samples = 0;
}
if (samples_teac.spindlemotor_stop.buffer) {
free(samples_teac.spindlemotor_stop.buffer);
samples_teac.spindlemotor_stop.buffer = NULL;
samples_teac.spindlemotor_stop.samples = 0;
}
if (samples_teac.single_track_step.buffer) {
free(samples_teac.single_track_step.buffer);
samples_teac.single_track_step.buffer = NULL;
samples_teac.single_track_step.samples = 0;
}
if (samples_teac.multi_track_seek.buffer) {
free(samples_teac.multi_track_seek.buffer);
samples_teac.multi_track_seek.buffer = NULL;
samples_teac.multi_track_seek.samples = 0;
}
/* End sound thread */
sound_fdd_thread_end();
}
@@ -362,6 +406,8 @@ fdd_audio_set_motor_enable(int drive, int motor_enable)
return;
drive_audio_samples_t *samples = get_drive_samples(drive);
if (!samples)
return;
if (motor_enable && !motoron[drive]) {
/* Motor starting up */
@@ -416,7 +462,7 @@ fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track)
return; /* Use single step for 1 track movements */
drive_audio_samples_t *samples = get_drive_samples(drive);
if (!samples->multi_track_seek.buffer || samples->multi_track_seek.samples == 0)
if (!samples || !samples->multi_track_seek.buffer || samples->multi_track_seek.samples == 0)
return; /* No multi-track seek sample loaded */
/* Check if a seek is already active */
@@ -475,6 +521,8 @@ fdd_audio_callback(int16_t *buffer, int length)
/* Process audio for all drives */
for (int drive = 0; drive < FDD_NUM; drive++) {
drive_audio_samples_t *samples = get_drive_samples(drive);
if (!samples)
continue;
for (int i = 0; i < samples_in_buffer; i++) {
float left_sample = 0.0f;

View File

@@ -25,6 +25,13 @@
#define FLOPPY_IMAGE_HISTORY 10
#define SEEK_RECALIBRATE -999
/* Per-drive audio profiles */
#define FDD_AUDIO_PROFILE_NONE 0
#define FDD_AUDIO_PROFILE_MITSUMI 1
#define FDD_AUDIO_PROFILE_PANASONIC 2
#define FDD_AUDIO_PROFILE_TEAC 3
#define FDD_AUDIO_PROFILE_MAX 4
#ifdef __cplusplus
extern "C" {
#endif
@@ -55,6 +62,10 @@ extern int fdd_get_check_bpb(int drive);
extern void fdd_set_type(int drive, int type);
extern int fdd_get_type(int drive);
/* New audio profile accessors */
extern void fdd_set_audio_profile(int drive, int profile);
extern int fdd_get_audio_profile(int drive);
extern int fdd_get_flags(int drive);
extern int fdd_get_densel(int drive);

View File

@@ -127,11 +127,12 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
++i;
}
model = new QStandardItemModel(0, 3, this);
model = new QStandardItemModel(0, 4, this);
ui->tableViewFloppy->setModel(model);
model->setHeaderData(0, Qt::Horizontal, tr("Type"));
model->setHeaderData(1, Qt::Horizontal, tr("Turbo"));
model->setHeaderData(2, Qt::Horizontal, tr("Check BPB"));
model->setHeaderData(3, Qt::Horizontal, tr("Audio"));
model->insertRows(0, FDD_NUM);
/* Floppy drives category */
@@ -141,6 +142,26 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
setFloppyType(model, idx, type);
model->setData(idx.siblingAtColumn(1), fdd_get_turbo(i) > 0 ? tr("On") : tr("Off"));
model->setData(idx.siblingAtColumn(2), fdd_get_check_bpb(i) > 0 ? tr("On") : tr("Off"));
int prof = fdd_get_audio_profile(i);
QString profName;
switch (prof) {
case FDD_AUDIO_PROFILE_PANASONIC:
profName = tr("Panasonic");
break;
case FDD_AUDIO_PROFILE_TEAC:
profName = tr("Teac");
break;
case FDD_AUDIO_PROFILE_MITSUMI:
profName = tr("Mitsumi");
break;
default:
profName = tr("None");
break;
}
auto audioIdx = model->index(i, 3);
model->setData(audioIdx, profName);
model->setData(audioIdx, prof, Qt::UserRole);
}
ui->tableViewFloppy->resizeColumnsToContents();
@@ -148,7 +169,22 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged,
this, &SettingsFloppyCDROM::onFloppyRowChanged);
#ifndef DISABLE_FDD_AUDIO
ui->comboBoxFloppyAudio->setVisible(true);
ui->comboBoxFloppyAudio->addItem(tr("None"), FDD_AUDIO_PROFILE_NONE);
ui->comboBoxFloppyAudio->addItem(tr("Generic Mitsumi 3.5\" 1.44MB"), FDD_AUDIO_PROFILE_MITSUMI);
ui->comboBoxFloppyAudio->addItem(tr("Panasonic JU-475-5 5.25\" 1.2MB"), FDD_AUDIO_PROFILE_PANASONIC);
ui->comboBoxFloppyAudio->addItem(tr("Teac FD-55GFR 5.25\" 1.2MB"), FDD_AUDIO_PROFILE_TEAC);
ui->comboBoxFloppyAudio->setSizeAdjustPolicy(QComboBox::AdjustToContents);
#else
ui->comboBoxFloppyAudio->setVisible(false);
#endif
// Set initial selection and trigger the row changed event to update controls
ui->tableViewFloppy->setCurrentIndex(model->index(0, 0));
// Manually trigger the row changed event to ensure audio selection is updated
onFloppyRowChanged(model->index(0, 0));
Harddrives::populateCDROMBuses(ui->comboBoxBus->model());
model = ui->comboBoxSpeed->model();
@@ -213,12 +249,6 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
ui->comboBoxCDROMType->setEnabled(eligibleRows > 1);
ui->comboBoxCDROMType->setCurrentIndex(-1);
ui->comboBoxCDROMType->setCurrentIndex(selectedTypeRow);
#ifndef DISABLE_FDD_AUDIO
ui->checkBoxFloppySounds->setVisible(true);
ui->checkBoxFloppySounds->setChecked(fdd_sounds_enabled > 0);
#else
ui->checkBoxFloppySounds->setVisible(false);
#endif
}
SettingsFloppyCDROM::~SettingsFloppyCDROM()
@@ -234,6 +264,9 @@ SettingsFloppyCDROM::save()
fdd_set_type(i, model->index(i, 0).data(Qt::UserRole).toInt());
fdd_set_turbo(i, model->index(i, 1).data() == tr("On") ? 1 : 0);
fdd_set_check_bpb(i, model->index(i, 2).data() == tr("On") ? 1 : 0);
#ifndef DISABLE_FDD_AUDIO
fdd_set_audio_profile(i, model->index(i, 3).data(Qt::UserRole).toInt());
#endif
}
/* Removable devices category */
@@ -255,7 +288,7 @@ SettingsFloppyCDROM::save()
#ifdef DISABLE_FDD_AUDIO
fdd_sounds_enabled = 0;
#else
fdd_sounds_enabled = ui->checkBoxFloppySounds->isChecked() ? 1 : 0;
fdd_sounds_enabled = 1;
#endif
}
@@ -266,6 +299,10 @@ SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex &current)
ui->comboBoxFloppyType->setCurrentIndex(type);
ui->checkBoxTurboTimings->setChecked(current.siblingAtColumn(1).data() == tr("On"));
ui->checkBoxCheckBPB->setChecked(current.siblingAtColumn(2).data() == tr("On"));
int prof = current.siblingAtColumn(3).data(Qt::UserRole).toInt();
int comboIndex = ui->comboBoxFloppyAudio->findData(prof);
ui->comboBoxFloppyAudio->setCurrentIndex(comboIndex);
}
void
@@ -325,7 +362,7 @@ void
SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1)
{
auto idx = ui->tableViewFloppy->selectionModel()->currentIndex();
ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ?
ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ?
tr("On") : tr("Off"));
}
@@ -333,15 +370,10 @@ void
SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1)
{
auto idx = ui->tableViewFloppy->selectionModel()->currentIndex();
ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ?
ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ?
tr("On") : tr("Off"));
}
void
SettingsFloppyCDROM::on_checkBoxFloppySounds_stateChanged(int arg1)
{
fdd_sounds_enabled = (arg1 == Qt::Checked) ? 1 : 0;
}
void
SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index)
@@ -350,6 +382,34 @@ SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index)
ui->tableViewFloppy->selectionModel()->currentIndex(), index);
}
void
SettingsFloppyCDROM::on_comboBoxFloppyAudio_activated(int)
{
auto idx = ui->tableViewFloppy->selectionModel()->currentIndex();
int prof = ui->comboBoxFloppyAudio->currentData().toInt();
QString profName;
switch (prof) {
case FDD_AUDIO_PROFILE_NONE:
profName = tr("None");
break;
case FDD_AUDIO_PROFILE_PANASONIC:
profName = tr("Panasonic");
break;
case FDD_AUDIO_PROFILE_TEAC:
profName = tr("Teac");
break;
case FDD_AUDIO_PROFILE_MITSUMI:
profName = tr("Mitsumi");
break;
default:
profName = tr("None");
break;
}
auto audioIdx = idx.siblingAtColumn(3);
ui->tableViewFloppy->model()->setData(audioIdx, profName);
ui->tableViewFloppy->model()->setData(audioIdx, prof, Qt::UserRole);
}
void SettingsFloppyCDROM::reloadBusChannels() {
auto selected = ui->comboBoxChannel->currentIndex();
Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass);

View File

@@ -25,7 +25,7 @@ private slots:
void on_comboBoxFloppyType_activated(int index);
void on_checkBoxTurboTimings_stateChanged(int arg1);
void on_checkBoxCheckBPB_stateChanged(int arg1);
void on_checkBoxFloppySounds_stateChanged(int arg1);
void on_comboBoxFloppyAudio_activated(int index);
void onCDROMRowChanged(const QModelIndex &current);
void on_comboBoxBus_activated(int index);

View File

@@ -100,11 +100,35 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxFloppySounds">
<property name="text">
<string>Enable floppy sounds for all drives</string>
</property>
</widget>
<layout class="QHBoxLayout" name="audioLayout">
<item>
<widget class="QLabel" name="labelFloppyAudio">
<property name="text">
<string>Audio:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxFloppyAudio">
<property name="maxVisibleItems">
<number>10</number>
</property>
</widget>
</item>
<item>
<spacer name="audioSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
@@ -216,7 +240,7 @@
<tabstop>comboBoxFloppyType</tabstop>
<tabstop>checkBoxTurboTimings</tabstop>
<tabstop>checkBoxCheckBPB</tabstop>
<tabstop>checkBoxFloppySounds</tabstop>
<tabstop>comboBoxFloppyAudio</tabstop>
<tabstop>tableViewCDROM</tabstop>
<tabstop>comboBoxBus</tabstop>
<tabstop>comboBoxChannel</tabstop>