mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
Floppy sounds WIP. See comments in floppy.c.
This commit is contained in:
parent
f09606c87b
commit
e43612a8d5
@ -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 )
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user