cassette: Allow cassette sound to be directly routed to a sound output.

This commit is contained in:
Michael Zapf 2018-08-19 21:34:36 +02:00
parent 66b9e9c18f
commit 7a2880f8ee
2 changed files with 65 additions and 8 deletions

View File

@ -13,8 +13,12 @@
#include "cassette.h"
#include "ui/uimain.h"
#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
#define LOG_WARN (1U<<1) // Warnings
#define LOG_DETAIL (1U<<2) // Details
#define VERBOSE ( LOG_WARN )
#include "logmacro.h"
// device type definition
DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette")
@ -26,6 +30,7 @@ DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette"
cassette_image_device::cassette_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, CASSETTE, tag, owner, clock),
device_image_interface(mconfig, *this),
device_sound_interface(mconfig, *this),
m_cassette(nullptr),
m_state(CASSETTE_STOPPED),
m_position(0),
@ -37,7 +42,8 @@ cassette_image_device::cassette_image_device(const machine_config &mconfig, cons
m_formats(cassette_default_formats),
m_create_opts(nullptr),
m_default_state(CASSETTE_PLAY),
m_interface(nullptr)
m_interface(nullptr),
m_stereo(false)
{
}
@ -81,7 +87,7 @@ bool cassette_image_device::is_motor_on()
void cassette_image_device::update()
{
double cur_time = device().machine().time().as_double();
double cur_time = machine().time().as_double();
if (is_motor_on())
{
@ -142,7 +148,7 @@ double cassette_image_device::input()
sample = m_value;
double_value = sample / ((double) 0x7FFFFFFF);
LOG(("cassette_input(): time_index=%g value=%g\n", m_position, double_value));
LOGMASKED(LOG_DETAIL, "cassette_input(): time_index=%g value=%g\n", m_position, double_value);
return double_value;
}
@ -168,7 +174,7 @@ double cassette_image_device::get_position()
double position = m_position;
if (is_motor_on())
position += (device().machine().time().as_double() - m_position_time)*m_speed*m_direction;
position += (machine().time().as_double() - m_position_time)*m_speed*m_direction;
return position;
}
@ -246,6 +252,8 @@ void cassette_image_device::device_start()
m_cassette = nullptr;
m_state = m_default_state;
m_value = 0;
machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), machine().sample_rate());
}
image_init_result cassette_image_device::call_create(int format_type, util::option_resolution *format_options)
@ -304,7 +312,7 @@ image_init_result cassette_image_device::internal_load(bool is_create)
/* reset the position */
m_position = 0.0;
m_position_time = device().machine().time().as_double();
m_position_time = machine().time().as_double();
/* default channel to 0, speed multiplier to 1 */
m_channel = 0;
@ -411,3 +419,46 @@ std::string cassette_image_device::call_display()
}
return result;
}
//-------------------------------------------------
// Cassette sound
//-------------------------------------------------
void cassette_image_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
cassette_state state;
double time_index;
double duration;
stream_sample_t *left_buffer = outputs[0];
stream_sample_t *right_buffer = nullptr;
int i;
if (m_stereo)
right_buffer = outputs[1];
state = (cassette_state)(get_state() & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR | CASSETTE_MASK_SPEAKER));
if (exists() && (state == (CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)))
{
cassette_image *cassette = get_image();
time_index = get_position();
duration = ((double) samples) / machine().sample_rate();
cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT);
if (m_stereo)
cassette_get_samples(cassette, 1, time_index, duration, samples, 2, right_buffer, CASSETTE_WAVEFORM_16BIT);
for (i = samples - 1; i >= 0; i--)
{
left_buffer[i] = ((int16_t *) left_buffer)[i];
if (m_stereo)
right_buffer[i] = ((int16_t *) right_buffer)[i];
}
}
else
{
memset(left_buffer, 0, sizeof(*left_buffer) * samples);
if (m_stereo)
memset(right_buffer, 0, sizeof(*right_buffer) * samples);
}
}

View File

@ -43,7 +43,8 @@ enum cassette_state
// ======================> cassette_image_device
class cassette_image_device : public device_t,
public device_image_interface
public device_image_interface,
public device_sound_interface
{
public:
// construction/destruction
@ -90,6 +91,10 @@ public:
void go_reverse();
void seek(double time, int origin);
// sound stream update overrides
void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
device_sound_interface& set_stereo() { m_stereo = true; return *this; }
protected:
bool is_motor_on();
void update();
@ -115,6 +120,7 @@ private:
const char * m_interface;
image_init_result internal_load(bool is_create);
bool m_stereo;
};
// device type definition