Floppy sounds WIP. See comments in floppy.c.

This commit is contained in:
Michael Zapf 2015-08-20 20:09:07 +02:00
parent f09606c87b
commit e43612a8d5
7 changed files with 239 additions and 8 deletions

View File

@ -670,9 +670,13 @@ MACHINE_CONFIG_FRAGMENT( bwg_fdc )
MCFG_MM58274C_DAY1(0) // sunday
MCFG_FLOPPY_DRIVE_ADD("0", bwg_floppies, "525dd", snug_bwg_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("1", bwg_floppies, "525dd", snug_bwg_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("2", bwg_floppies, NULL, snug_bwg_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("3", bwg_floppies, NULL, snug_bwg_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MACHINE_CONFIG_END
ROM_START( bwg_fdc )

View File

@ -1027,9 +1027,13 @@ MACHINE_CONFIG_FRAGMENT( ti99_hfdc )
MCFG_HDC92X4_DMA_OUT_CALLBACK(WRITE8(myarc_hfdc_device, write_buffer))
MCFG_FLOPPY_DRIVE_ADD("f1", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("f2", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("f3", hfdc_floppies, NULL, myarc_hfdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("f4", hfdc_floppies, NULL, myarc_hfdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
// NB: Hard disks don't go without image (other than floppy drives)
MCFG_MFM_HARDDISK_CONN_ADD("h1", hfdc_harddisks, NULL, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT)

View File

@ -407,8 +407,11 @@ MACHINE_CONFIG_FRAGMENT( ti_fdc )
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(ti_fdc_device, fdc_irq_w))
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(ti_fdc_device, fdc_drq_w))
MCFG_FLOPPY_DRIVE_ADD("0", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("1", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("2", tifdc_floppies, NULL, ti_fdc_device::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MACHINE_CONFIG_END
ROM_START( ti_fdc )

View File

@ -18,7 +18,9 @@
*/
// Show step operation
#define TRACE_STEP 0
#define TRACE_STEP 1
#define FLOPSND_TAG "floppysound"
// device type definition
const device_type FLOPPY_CONNECTOR = &device_creator<floppy_connector>;
@ -123,7 +125,8 @@ const floppy_format_type floppy_image_device::default_floppy_formats[] = {
floppy_connector::floppy_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, FLOPPY_CONNECTOR, "Floppy drive connector abstraction", tag, owner, clock, "floppy_connector", __FILE__),
device_slot_interface(mconfig, *this)
device_slot_interface(mconfig, *this),
m_enable_sound(false)
{
}
@ -144,7 +147,10 @@ void floppy_connector::device_config_complete()
{
floppy_image_device *dev = dynamic_cast<floppy_image_device *>(get_card_device());
if(dev)
{
dev->set_formats(formats);
dev->enable_sound(m_enable_sound);
}
}
floppy_image_device *floppy_connector::get_device()
@ -161,7 +167,8 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
device_image_interface(mconfig, *this),
device_slot_card_interface(mconfig, *this),
image(NULL),
fif_list(NULL)
fif_list(NULL),
m_make_sound(false)
{
extension_list[0] = '\0';
m_err = IMAGE_ERROR_INVALIDIMAGE;
@ -304,12 +311,20 @@ void floppy_image_device::device_start()
setup_characteristics();
if (m_make_sound) m_sound_out = subdevice<floppy_sound_device>(FLOPSND_TAG);
save_item(NAME(cyl));
save_item(NAME(subcyl));
}
void floppy_image_device::device_reset()
{
if (m_make_sound)
{
// Have we loaded all samples? Otherwise mute the floppy.
m_make_sound = m_sound_out->samples_loaded();
}
revolution_start_time = attotime::never;
revolution_count = 0;
mon = 1;
@ -358,6 +373,7 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename)
bool floppy_image_device::call_load()
{
io_generic io;
// Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs.
io.file = (device_image_interface *)this;
io.procs = &image_ioprocs;
@ -490,6 +506,8 @@ void floppy_image_device::mon_w(int state)
cur_ready_cb(this, ready);
}
}
if (m_make_sound) m_sound_out->motor(state==0);
}
attotime floppy_image_device::time_next_index()
@ -581,6 +599,8 @@ void floppy_image_device::stp_w(int state)
}
}
subcyl = 0;
// Do we want a stepper sound?
if (m_make_sound) m_sound_out->step(state==0);
}
}
@ -1032,6 +1052,148 @@ void ui_menu_control_floppy_image::handle()
}
}
//===================================================================
// Floppy sound
//
// In order to enable floppy sound you must add the line
// MCFG_FLOPPY_DRIVE_SOUND(true)
// after MCFG_FLOPPY_DRIVE_ADD
// and you must put audio samples (44100Hz, mono) with names as
// shown in floppy_sample_names into the directory samples/floppy
// Sound will be disabled when these samples are missing.
//
// MZ, Aug 2015
//===================================================================
floppy_sound_device::floppy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: samples_device(mconfig, FLOPPYSOUND, "Floppy sound", tag, owner, clock, "flopsnd", __FILE__)
{
m_motor = false;
m_step = false;
m_loaded = false;
}
void floppy_sound_device::device_start()
{
// Read audio samples. The samples are stored in the list m_samples.
m_loaded = load_samples();
// The per-floppy stream. If we don't have all samples, don't allocate a stream.
if (m_loaded) m_sound = machine().sound().stream_alloc(*this, 0, 1, clock());
// Of course, we can read the length from the sample_t, but we want to
// be able to fine-tune it, for instance, choose different start and end points
m_samplestart_motor = 0;
m_sampleend_motor = 8820; // 200ms
m_samplestart_step = 0;
m_sampleend_step = 2205; // 50ms
// Mintime says how long the sound persists after the initiating signal
// is cleared (important for short step pulses)
m_motor_mintime = 8820;
m_step_mintime = 1500;
// Number of updates until the sample stops
m_motor_time = 0;
m_step_time = 0;
// Initialize position
m_samplepos_step = m_samplestart_step;
m_samplepos_motor = m_samplestart_motor;
}
void floppy_sound_device::motor(bool state)
{
m_sound->update();
// We do not reset the motor sample on state==true because we don't want
// the sound to "jump"
if (state==true) m_motor_time = m_motor_mintime;
m_motor = state;
}
void floppy_sound_device::step(bool state)
{
m_sound->update(); // required
if (state==true)
{
m_step_time = m_step_mintime;
m_samplepos_step = m_samplestart_step;
}
m_step = state;
}
//-------------------------------------------------
// sound_stream_update - update the sound stream
//-------------------------------------------------
void floppy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// We are using only one stream, unlike the parent class
// Also, there is no need for interpolation, as we only expect
// one sample rate of 44100 for all samples
INT16 out = 0;
stream_sample_t *samplebuffer = outputs[0];
sample_t& motor_sample = m_sample[0];
sample_t& step_sample = m_sample[1];
while (samples-- > 0)
{
// Motor sound
if (m_motor_time > 0)
{
if (m_samplepos_motor < m_sampleend_motor)
// Stream value
out = motor_sample.data[m_samplepos_motor++];
else
m_samplepos_motor = m_samplestart_motor;
// When the motor is turned off, count down the samples
if (!m_motor) m_motor_time--;
}
// Stepper sound
if (m_step_time > 0)
{
if (m_samplepos_step < m_sampleend_step)
// Mix it into the stream value
out = out + step_sample.data[m_samplepos_step++];
else
m_samplepos_step = m_samplestart_step;
// When the step is turned off, count down the samples
if (!m_step) m_step_time--;
}
// Write to the stream buffer
*(samplebuffer++) = out;
}
}
static const char *const floppy_sample_names[] =
{
"*floppy",
"flop_35_motor",
"flop_35_step",
0
};
#define FLOPSPK "flopsndout"
MACHINE_CONFIG_FRAGMENT( floppy_img )
MCFG_SPEAKER_STANDARD_MONO(FLOPSPK)
MCFG_SOUND_ADD(FLOPSND_TAG, FLOPPYSOUND, 44100)
MCFG_SAMPLES_NAMES(floppy_sample_names)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, FLOPSPK, 0.75)
MACHINE_CONFIG_END
machine_config_constructor floppy_image_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( floppy_img );
}
const device_type FLOPPYSOUND = &device_creator<floppy_sound_device>;
//**************************************************************************
// GENERIC FLOPPY DRIVE DEFINITIONS

View File

@ -20,12 +20,16 @@
#include "formats/cqm_dsk.h"
#include "formats/dsk_dsk.h"
#include "ui/imgcntrl.h"
#include "sound/samples.h"
#define MCFG_FLOPPY_DRIVE_ADD(_tag, _slot_intf, _def_slot, _formats) \
MCFG_DEVICE_ADD(_tag, FLOPPY_CONNECTOR, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
static_cast<floppy_connector *>(device)->set_formats(_formats);
#define MCFG_FLOPPY_DRIVE_SOUND(_doit) \
static_cast<floppy_connector *>(device)->enable_sound(_doit);
#define DECLARE_FLOPPY_FORMATS(_name) \
static const floppy_format_type _name []
@ -44,6 +48,7 @@
FLOPPY_DSK_FORMAT, \
NULL };
class floppy_sound_device;
/***************************************************************************
TYPE DEFINITIONS
@ -129,6 +134,9 @@ public:
static const floppy_format_type default_floppy_formats[];
// Enable sound
void enable_sound(bool doit) { m_make_sound = doit; }
protected:
// device-level overrides
virtual void device_config_complete();
@ -136,6 +144,8 @@ protected:
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
virtual machine_config_constructor device_mconfig_additions() const;
virtual void setup_characteristics() = 0;
floppy_image_format_t *input_format;
@ -187,6 +197,10 @@ protected:
void write_zone(UINT32 *buf, int &cells, int &index, UINT32 spos, UINT32 epos, UINT32 mg);
void commit_image();
attotime get_next_index_time(std::vector<UINT32> &buf, int index, int delta, attotime base);
// Sound
bool m_make_sound;
floppy_sound_device* m_sound_out;
};
class ui_menu_control_floppy_image : public ui_menu_control_device_image {
@ -249,6 +263,43 @@ DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55f, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55g, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(alps_3255190x, "floppy_5_25")
extern const device_type FLOPPYSOUND;
/*
Floppy drive sound
*/
class floppy_sound_device : public samples_device
{
public:
floppy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void motor(bool on);
void step(bool on);
bool samples_loaded() { return m_loaded; }
protected:
void device_start();
private:
// device_sound_interface overrides
void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
sound_stream* m_sound;
bool m_loaded;
int m_sampleend_motor;
int m_samplepos_motor;
int m_samplestart_motor;
int m_motor_mintime; // min time for the samples; sound persists for that time
int m_motor_time;
bool m_motor;
int m_sampleend_step;
int m_samplestart_step;
int m_samplepos_step;
int m_step_mintime;
int m_step_time;
bool m_step;
};
class floppy_connector: public device_t,
public device_slot_interface
@ -259,6 +310,7 @@ public:
void set_formats(const floppy_format_type *formats);
floppy_image_device *get_device();
void enable_sound(bool doit) { m_enable_sound = doit; }
protected:
virtual void device_start();
@ -266,6 +318,7 @@ protected:
private:
const floppy_format_type *formats;
bool m_enable_sound;
};

View File

@ -595,13 +595,15 @@ bool samples_device::read_flac_sample(emu_file &file, sample_t &sample)
//-------------------------------------------------
// load_samples - load all the samples in our
// attached interface
// Returns true when all samples were successfully read, else false
//-------------------------------------------------
void samples_device::load_samples()
bool samples_device::load_samples()
{
bool ok = true;
// if the user doesn't want to use samples, bail
if (!machine().options().samples())
return;
return false;
// iterate over ourself
const char *basename = machine().basename();
@ -631,6 +633,10 @@ void samples_device::load_samples()
if (filerr == FILERR_NONE)
read_sample(file, m_sample[index]);
else if (filerr == FILERR_NOT_FOUND)
osd_printf_warning("Sample '%s' NOT FOUND\n", samplename);
{
logerror("%s: Sample '%s' NOT FOUND\n", tag(), samplename);
ok = false;
}
}
return ok;
}

View File

@ -92,7 +92,6 @@ protected:
// device_sound_interface overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private:
// internal classes
struct channel_t
{
@ -111,7 +110,7 @@ private:
// internal helpers
static bool read_wav_sample(emu_file &file, sample_t &sample);
static bool read_flac_sample(emu_file &file, sample_t &sample);
void load_samples();
bool load_samples();
// internal state
std::vector<channel_t> m_channel;