diff options
author | 2020-10-02 14:01:03 +1000 | |
---|---|---|
committer | 2020-10-02 14:01:03 +1000 | |
commit | d32834f1f7811494f312be32b05757695d2b7700 (patch) | |
tree | 3c1d53812875f8e5189d3e961e9d7644aa9259ce /src | |
parent | 0bfc5ed542f9c42b509be8635dabc825581c2d53 (diff) |
formats/cassimg.cpp: Finish encapsulation of cassette_image class.
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/imagedev/cassette.cpp | 12 | ||||
-rw-r--r-- | src/devices/sound/wave.cpp | 2 | ||||
-rw-r--r-- | src/lib/formats/atom_tap.cpp | 6 | ||||
-rw-r--r-- | src/lib/formats/cassimg.cpp | 268 | ||||
-rw-r--r-- | src/lib/formats/cassimg.h | 112 | ||||
-rw-r--r-- | src/lib/formats/coco_cas.cpp | 18 | ||||
-rw-r--r-- | src/lib/formats/sc3000_bit.cpp | 6 | ||||
-rw-r--r-- | src/lib/formats/sord_cas.cpp | 10 | ||||
-rw-r--r-- | src/lib/formats/thom_cas.cpp | 6 | ||||
-rw-r--r-- | src/lib/formats/wavfile.cpp | 10 | ||||
-rw-r--r-- | src/tools/castool.cpp | 2 |
11 files changed, 226 insertions, 226 deletions
diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index 8b408355ed4..5d17f822e60 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -26,8 +26,8 @@ DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette" // cassette_image_device - constructor //------------------------------------------------- -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), +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), @@ -256,7 +256,7 @@ image_init_result cassette_image_device::internal_load(bool is_create) if (is_create || (length()==0)) // empty existing images are fine to write over. { // creating an image - err = cassette_image::create((void *)image, &image_ioprocs, &cassette_image::wavfile_format, m_create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, m_cassette); + err = cassette_image::create((void *)image, &image_ioprocs, &cassette_image::wavfile_format, m_create_opts, cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT, m_cassette); if (err != cassette_image::error::SUCCESS) goto error; } @@ -271,8 +271,8 @@ image_init_result cassette_image_device::internal_load(bool is_create) // try opening the cassette int cassette_flags = is_readonly() - ? CASSETTE_FLAG_READONLY - : (CASSETTE_FLAG_READWRITE | CASSETTE_FLAG_SAVEONEXIT); + ? cassette_image::FLAG_READONLY + : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT); err = cassette_image::open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, m_cassette); // special case - if we failed due to readwrite not being supported, make the image be read only and retry @@ -416,7 +416,7 @@ void cassette_image_device::sound_stream_update(sound_stream &stream, std::vecto for (int ch = 0; ch < outputs.size(); ch++) { - cassette->get_samples(0, time_index, duration, outputs[0].samples(), 2, &m_samples[0], CASSETTE_WAVEFORM_16BIT); + cassette->get_samples(0, time_index, duration, outputs[0].samples(), 2, &m_samples[0], cassette_image::WAVEFORM_16BIT); for (int sampindex = 0; sampindex < outputs[ch].samples(); sampindex++) outputs[ch].put_int(sampindex, m_samples[sampindex], 32768); } diff --git a/src/devices/sound/wave.cpp b/src/devices/sound/wave.cpp index 58307ec3f97..99c56615171 100644 --- a/src/devices/sound/wave.cpp +++ b/src/devices/sound/wave.cpp @@ -62,7 +62,7 @@ void wave_device::sound_stream_update(sound_stream &stream, std::vector<read_str for (int ch = 0; ch < 2; ch++) { - cassette->get_samples(ch, time_index, duration, outputs[ch].samples(), 2, &m_sample_buf[0], CASSETTE_WAVEFORM_16BIT); + cassette->get_samples(ch, time_index, duration, outputs[ch].samples(), 2, &m_sample_buf[0], cassette_image::WAVEFORM_16BIT); for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) outputs[ch].put_int(sampindex, m_sample_buf[sampindex], 32768); } diff --git a/src/lib/formats/atom_tap.cpp b/src/lib/formats/atom_tap.cpp index 9d2ac3dc627..cfe83bc1bae 100644 --- a/src/lib/formats/atom_tap.cpp +++ b/src/lib/formats/atom_tap.cpp @@ -62,7 +62,7 @@ static const cassette_image::Modulation atom_tap_modulation = { - CASSETTE_MODULATION_SINEWAVE, + cassette_image::MODULATION_SINEWAVE, 1200.0 - 300, 1200.0, 1200.0 + 300, 2400.0 - 600, 2400.0, 2400.0 + 600 }; @@ -84,7 +84,7 @@ static uint8_t cassette_image_read_uint8(cassette_image *cassette, uint64_t offs static cassette_image::error atom_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette->modulation_identify(&atom_tap_modulation, opts); + return cassette->modulation_identify(atom_tap_modulation, opts); } /*------------------------------------------------- @@ -93,7 +93,7 @@ static cassette_image::error atom_tap_identify(cassette_image *cassette, cassett #define MODULATE(_value) \ for (int i = 0; i < (_value ? 8 : 4); i++) { \ - err = cassette->put_modulated_data_bit(0, time_index, _value, &atom_tap_modulation, &time_displacement);\ + err = cassette->put_modulated_data_bit(0, time_index, _value, atom_tap_modulation, &time_displacement);\ if (err != cassette_image::error::SUCCESS) return err;\ time_index += time_displacement;\ } diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp index 37ca1bd1dfa..25b060e0311 100644 --- a/src/lib/formats/cassimg.cpp +++ b/src/lib/formats/cassimg.cpp @@ -74,35 +74,67 @@ constexpr int16_t interpolate16(int32_t value) +constexpr size_t my_round(double d) +{ + return size_t(d + 0.5); +} + + + +/********************************************************************* + waveform accesses to/from the raw image +*********************************************************************/ + +const int8_t *choose_wave(const cassette_image::Modulation &modulation, size_t &wave_bytes_length) +{ + static const int8_t square_wave[] = { -128, 127 }; + static const int8_t sine_wave[] = { 0, 48, 89, 117, 127, 117, 89, 48, 0, -48, -89, -117, -127, -117, -89, -48 }; + + if (modulation.flags & cassette_image::MODULATION_SINEWAVE) + { + wave_bytes_length = ARRAY_LENGTH(sine_wave); + return sine_wave; + } + else + { + wave_bytes_length = ARRAY_LENGTH(square_wave); + return square_wave; + } +} + +} // anonymous namespace + + + /********************************************************************* initialization and termination *********************************************************************/ -cassette_image::error try_identify_format(const cassette_image::Format &format, cassette_image *image, const std::string &extension, int flags, cassette_image::Options &opts) +cassette_image::error cassette_image::try_identify_format(const Format &format, const std::string &extension, int flags, Options &opts) { // is this the right extension? if (!extension.empty() && !image_find_extension(format.extensions, extension.c_str())) - return cassette_image::error::INVALID_IMAGE; + return error::INVALID_IMAGE; // invoke format->identify - opts = cassette_image::Options(); - cassette_image::error err = format.identify(image, &opts); - if (err != cassette_image::error::SUCCESS) + opts = Options(); + error err = format.identify(this, &opts); + if (err != error::SUCCESS) return err; // is this a read only format, but the cassette was not opened read only? - if (((flags & CASSETTE_FLAG_READONLY) == 0) && (format.save == nullptr)) - return cassette_image::error::READ_WRITE_UNSUPPORTED; + if (((flags & FLAG_READONLY) == 0) && (format.save == nullptr)) + return error::READ_WRITE_UNSUPPORTED; // success! - return cassette_image::error::SUCCESS; + return error::SUCCESS; } -cassette_image::error cassette_perform_save(cassette_image *cassette) +cassette_image::error cassette_image::perform_save() { - cassette_image::Info info = cassette->get_info(); - return cassette->format->save(cassette, &info); + Info info = get_info(); + return m_format->save(this, &info); } @@ -111,7 +143,7 @@ cassette_image::error cassette_perform_save(cassette_image *cassette) waveform accesses *********************************************************************/ -struct manipulation_ranges +struct cassette_image::manipulation_ranges { int channel_first; int channel_last; @@ -121,95 +153,63 @@ struct manipulation_ranges -constexpr size_t my_round(double d) -{ - return size_t(d + 0.5); -} - - - -cassette_image::error compute_manipulation_ranges(cassette_image *cassette, int channel, - double time_index, double sample_period, manipulation_ranges *ranges) +cassette_image::error cassette_image::compute_manipulation_ranges(int channel, + double time_index, double sample_period, manipulation_ranges &ranges) const { if (channel < 0) { - ranges->channel_first = 0; - ranges->channel_last = cassette->channels - 1; + ranges.channel_first = 0; + ranges.channel_last = m_channels - 1; } else { - ranges->channel_first = channel; - ranges->channel_last = channel; + ranges.channel_first = channel; + ranges.channel_last = channel; } - ranges->sample_first = my_round(time_index * cassette->sample_frequency); - ranges->sample_last = my_round((time_index + sample_period) * cassette->sample_frequency); + ranges.sample_first = my_round(time_index * m_sample_frequency); + ranges.sample_last = my_round((time_index + sample_period) * m_sample_frequency); - if (ranges->sample_last > ranges->sample_first) - ranges->sample_last--; + if (ranges.sample_last > ranges.sample_first) + ranges.sample_last--; - return cassette_image::error::SUCCESS; + return error::SUCCESS; } -cassette_image::error lookup_sample(cassette_image *cassette, int channel, size_t sample, int32_t **ptr) +cassette_image::error cassette_image::lookup_sample(int channel, size_t sample, int32_t *&ptr) { - *ptr = nullptr; - size_t sample_blocknum = (sample / SAMPLES_PER_BLOCK) * cassette->channels + channel; + ptr = nullptr; + size_t sample_blocknum = (sample / SAMPLES_PER_BLOCK) * m_channels + channel; size_t sample_index = sample % SAMPLES_PER_BLOCK; - /* is this block beyond the edge of our waveform? */ - if (sample_blocknum >= cassette->blocks.size()) - cassette->blocks.resize(sample_blocknum + 1); - - if (!cassette->blocks[sample_blocknum]) - cassette->blocks[sample_blocknum] = make_unique_clear<int32_t []>(SAMPLES_PER_BLOCK); - - *ptr = &cassette->blocks[sample_blocknum][sample_index]; - return cassette_image::error::SUCCESS; -} - - - -/********************************************************************* - waveform accesses to/from the raw image -*********************************************************************/ + // is this block beyond the edge of our waveform? + if (sample_blocknum >= m_blocks.size()) + m_blocks.resize(sample_blocknum + 1); -const int8_t *choose_wave(const cassette_image::Modulation *modulation, size_t *wave_bytes_length) -{ - static const int8_t square_wave[] = { -128, 127 }; - static const int8_t sine_wave[] = { 0, 48, 89, 117, 127, 117, 89, 48, 0, -48, -89, -117, -127, -117, -89, -48 }; + if (!m_blocks[sample_blocknum]) + m_blocks[sample_blocknum] = make_unique_clear<int32_t []>(SAMPLES_PER_BLOCK); - if (modulation->flags & CASSETTE_MODULATION_SINEWAVE) - { - *wave_bytes_length = ARRAY_LENGTH(sine_wave); - return sine_wave; - } - else - { - *wave_bytes_length = ARRAY_LENGTH(square_wave); - return square_wave; - } + ptr = &m_blocks[sample_blocknum][sample_index]; + return error::SUCCESS; } -} // anonymous namespace - cassette_image::cassette_image(const Format *format, void *file, const io_procs *procs, int flags) { - this->format = format; - this->io.file = file; - this->io.procs = procs; - this->flags = flags; + m_format = format; + m_io.file = file; + m_io.procs = procs; + m_flags = flags; } cassette_image::~cassette_image() { - if ((flags & CASSETTE_FLAG_DIRTY) && (flags & CASSETTE_FLAG_SAVEONEXIT)) + if ((m_flags & CASSETTE_FLAG_DIRTY) && (m_flags & FLAG_SAVEONEXIT)) save(); } @@ -242,7 +242,7 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p for (int i = 0; !format && formats[i]; i++) { // try this format - error err = try_identify_format(*formats[i], cassette.get(), extension, flags, opts); + error err = cassette->try_identify_format(*formats[i], extension, flags, opts); if (err != error::SUCCESS && err != error::INVALID_IMAGE) return err; @@ -254,11 +254,11 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p // have we found a proper format if (!format) return error::INVALID_IMAGE; - cassette->format = format; + cassette->m_format = format; // read the options - cassette->channels = opts.channels; - cassette->sample_frequency = opts.sample_frequency; + cassette->m_channels = opts.channels; + cassette->m_sample_frequency = opts.sample_frequency; // load the image error err = format->load(cassette.get()); @@ -266,7 +266,7 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p return err; /* success */ - cassette->flags &= ~CASSETTE_FLAG_DIRTY; + cassette->m_flags &= ~CASSETTE_FLAG_DIRTY; outcassette = std::move(cassette); return error::SUCCESS; } @@ -279,7 +279,7 @@ cassette_image::error cassette_image::create(void *file, const io_procs *procs, static const Options default_options = { 1, 16, 44100 }; // cannot create to a read only image - if (flags & CASSETTE_FLAG_READONLY) + if (flags & FLAG_READONLY) return error::INVALID_IMAGE; // is this a good format? @@ -296,8 +296,8 @@ cassette_image::error cassette_image::create(void *file, const io_procs *procs, catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } // read the options - cassette->channels = opts->channels; - cassette->sample_frequency = opts->sample_frequency; + cassette->m_channels = opts->channels; + cassette->m_sample_frequency = opts->sample_frequency; outcassette = std::move(cassette); return error::SUCCESS; @@ -307,14 +307,14 @@ cassette_image::error cassette_image::create(void *file, const io_procs *procs, cassette_image::error cassette_image::save() { - if (!format || !format->save) + if (!m_format || !m_format->save) return error::UNSUPPORTED; - error err = cassette_perform_save(this); + error err = perform_save(); if (err != error::SUCCESS) return err; - flags &= ~CASSETTE_FLAG_DIRTY; + m_flags &= ~CASSETTE_FLAG_DIRTY; return error::SUCCESS; } @@ -323,10 +323,10 @@ cassette_image::error cassette_image::save() cassette_image::Info cassette_image::get_info() const { Info result; - result.channels = channels; - result.sample_count = sample_count; - result.sample_frequency = sample_frequency; - result.bits_per_sample = (int)waveform_bytes_per_sample(flags) * 8; + result.channels = m_channels; + result.sample_count = m_sample_count; + result.sample_frequency = m_sample_frequency; + result.bits_per_sample = (int)waveform_bytes_per_sample(m_flags) * 8; return result; } @@ -334,12 +334,12 @@ cassette_image::Info cassette_image::get_info() const void cassette_image::change(void *file, const io_procs *procs, const Format *format, int flags) { - if ((flags & CASSETTE_FLAG_READONLY) == 0) + if ((flags & FLAG_READONLY) == 0) flags |= CASSETTE_FLAG_DIRTY; - this->io.file = file; - this->io.procs = procs; - this->format = format; - this->flags = flags; + m_io.file = file; + m_io.procs = procs; + m_format = format; + m_flags = flags; } @@ -350,21 +350,21 @@ void cassette_image::change(void *file, const io_procs *procs, const Format *for void cassette_image::image_read(void *buffer, uint64_t offset, size_t length) { - io_generic_read(&io, buffer, offset, length); + io_generic_read(&m_io, buffer, offset, length); } void cassette_image::image_write(const void *buffer, uint64_t offset, size_t length) { - io_generic_write(&io, buffer, offset, length); + io_generic_write(&m_io, buffer, offset, length); } uint64_t cassette_image::image_size() { - return io_generic_size(&io); + return io_generic_size(&m_io); } @@ -382,9 +382,9 @@ cassette_image::error cassette_image::get_samples(int channel, { error err; manipulation_ranges ranges; - const int32_t *source_ptr; + int32_t *source_ptr; - err = compute_manipulation_ranges(this, channel, time_index, sample_period, &ranges); + err = compute_manipulation_ranges(channel, time_index, sample_period, ranges); if (err != error::SUCCESS) return err; @@ -397,7 +397,7 @@ cassette_image::error cassette_image::get_samples(int channel, /* find the sample that we are putting */ double d = map_double(ranges.sample_last + 1 - ranges.sample_first, 0, sample_count, sample_index) + ranges.sample_first; size_t cassette_sample_index = (size_t) d; - err = lookup_sample(this, channel, cassette_sample_index, (int32_t **) &source_ptr); + err = lookup_sample(channel, cassette_sample_index, source_ptr); if (err != error::SUCCESS) return err; @@ -412,20 +412,20 @@ cassette_image::error cassette_image::get_samples(int channel, dest_ptr += sample_index * sample_spacing; int16_t word; int32_t dword; - switch(waveform_bytes_per_sample(waveform_flags)) + switch (waveform_bytes_per_sample(waveform_flags)) { case 1: *((int8_t *) dest_ptr) = interpolate8(sum); break; case 2: word = interpolate16(sum); - if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + if (waveform_flags & WAVEFORM_ENDIAN_FLIP) word = swapendian_int16(word); *((int16_t *) dest_ptr) = word; break; case 4: dword = sum; - if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + if (waveform_flags & WAVEFORM_ENDIAN_FLIP) dword = swapendian_int32(dword); *((int32_t *) dest_ptr) = dword; break; @@ -449,13 +449,13 @@ cassette_image::error cassette_image::put_samples(int channel, if (sample_period == 0) return error::SUCCESS; - err = compute_manipulation_ranges(this, channel, time_index, sample_period, &ranges); + err = compute_manipulation_ranges(channel, time_index, sample_period, ranges); if (err != error::SUCCESS) return err; - if (this->sample_count < ranges.sample_last+1) - this->sample_count = ranges.sample_last + 1; - flags |= CASSETTE_FLAG_DIRTY; + if (m_sample_count < ranges.sample_last+1) + m_sample_count = ranges.sample_last + 1; + m_flags |= CASSETTE_FLAG_DIRTY; if (LOG_PUT_SAMPLES) { @@ -477,20 +477,20 @@ cassette_image::error cassette_image::put_samples(int channel, int32_t dword; switch(waveform_bytes_per_sample(waveform_flags)) { case 1: - if (waveform_flags & CASSETTE_WAVEFORM_UNSIGNED) + if (waveform_flags & WAVEFORM_UNSIGNED) dest_value = extrapolate8((int8_t)(*source_ptr - 128)); else dest_value = extrapolate8(*((int8_t *) source_ptr)); break; case 2: word = *((int16_t *) source_ptr); - if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + if (waveform_flags & WAVEFORM_ENDIAN_FLIP) word = swapendian_int16(word); dest_value = extrapolate16(word); break; case 4: dword = *((int32_t *) source_ptr); - if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + if (waveform_flags & WAVEFORM_ENDIAN_FLIP) dword = swapendian_int32(dword); dest_value = dword; break; @@ -501,7 +501,7 @@ cassette_image::error cassette_image::put_samples(int channel, for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++) { /* find the sample that we are putting */ - err = lookup_sample(this, channel, sample_index, &dest_ptr); + err = lookup_sample(channel, sample_index, dest_ptr); if (err != error::SUCCESS) return err; *dest_ptr = dest_value; @@ -516,7 +516,7 @@ cassette_image::error cassette_image::get_sample(int channel, double time_index, double sample_period, int32_t *sample) { return get_samples(channel, time_index, - sample_period, 1, 0, sample, CASSETTE_WAVEFORM_32BIT); + sample_period, 1, 0, sample, WAVEFORM_32BIT); } @@ -525,7 +525,7 @@ cassette_image::error cassette_image::put_sample(int channel, double time_index, double sample_period, int32_t sample) { return put_samples(channel, time_index, - sample_period, 1, 0, &sample, CASSETTE_WAVEFORM_32BIT); + sample_period, 1, 0, &sample, WAVEFORM_32BIT); } @@ -602,20 +602,20 @@ cassette_image::error cassette_image::write_samples(int channels, double time_in -cassette_image::error cassette_image::modulation_identify(const Modulation *modulation, Options *opts) +cassette_image::error cassette_image::modulation_identify(const Modulation &modulation, Options *opts) { size_t wave_bytes_length; - choose_wave(modulation, &wave_bytes_length); + choose_wave(modulation, wave_bytes_length); opts->bits_per_sample = 8; opts->channels = 1; - opts->sample_frequency = uint32_t(std::max(modulation->zero_frequency_high, modulation->one_frequency_high) * wave_bytes_length * 2); + opts->sample_frequency = uint32_t(std::max(modulation.zero_frequency_high, modulation.one_frequency_high) * wave_bytes_length * 2); return error::SUCCESS; } cassette_image::error cassette_image::put_modulated_data(int channel, double time_index, - const void *data, size_t data_length, const Modulation *modulation, + const void *data, size_t data_length, const Modulation &modulation, double *time_displacement) { error err; @@ -623,16 +623,16 @@ cassette_image::error cassette_image::put_modulated_data(int channel, double tim size_t wave_bytes_length; double total_displacement = 0.0; - const int8_t *wave_bytes = choose_wave(modulation, &wave_bytes_length); + const int8_t *wave_bytes = choose_wave(modulation, wave_bytes_length); while (data_length--) { uint8_t b = *(data_bytes++); for (int i = 0; i < 8; i++) { - double pulse_frequency = (b & (1 << i)) ? modulation->one_frequency_canonical : modulation->zero_frequency_canonical; + double pulse_frequency = (b & (1 << i)) ? modulation.one_frequency_canonical : modulation.zero_frequency_canonical; double pulse_period = 1 / pulse_frequency; - err = put_samples(0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT); + err = put_samples(0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, WAVEFORM_8BIT); if (err != error::SUCCESS) goto done; time_index += pulse_period; @@ -650,7 +650,7 @@ done: cassette_image::error cassette_image::put_modulated_filler(int channel, double time_index, - uint8_t filler, size_t filler_length, const Modulation *modulation, + uint8_t filler, size_t filler_length, const Modulation &modulation, double *time_displacement) { error err; @@ -674,7 +674,7 @@ cassette_image::error cassette_image::put_modulated_filler(int channel, double t cassette_image::error cassette_image::read_modulated_data(int channel, double time_index, - uint64_t offset, uint64_t length, const Modulation *modulation, + uint64_t offset, uint64_t length, const Modulation &modulation, double *time_displacement) { uint8_t *buffer; @@ -717,24 +717,24 @@ cassette_image::error cassette_image::read_modulated_data(int channel, double ti cassette_image::error cassette_image::put_modulated_data_bit(int channel, double time_index, - uint8_t data, const Modulation *modulation, + uint8_t data, const Modulation &modulation, double *time_displacement) { error err; size_t wave_bytes_length; double total_displacement = 0.0; - const int8_t *wave_bytes = choose_wave(modulation, &wave_bytes_length); + const int8_t *wave_bytes = choose_wave(modulation, wave_bytes_length); - double pulse_frequency = (data) ? modulation->one_frequency_canonical : modulation->zero_frequency_canonical; + double pulse_frequency = (data) ? modulation.one_frequency_canonical : modulation.zero_frequency_canonical; double pulse_period = 1 / pulse_frequency; - err = put_samples(0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT); - if (err != cassette_image::error::SUCCESS) + err = put_samples(0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, WAVEFORM_8BIT); + if (err != error::SUCCESS) goto done; time_index += pulse_period; total_displacement += pulse_period; - err = cassette_image::error::SUCCESS; + err = error::SUCCESS; done: if (time_displacement) @@ -754,7 +754,7 @@ cassette_image::error cassette_image::legacy_identify(Options *opts, opts->channels = 1; opts->bits_per_sample = 16; opts->sample_frequency = legacy_args->sample_frequency; - return cassette_image::error::SUCCESS; + return error::SUCCESS; } @@ -864,7 +864,7 @@ cassette_image::error cassette_image::legacy_construct(const LegacyWaveFiller *l /* specify the wave */ err = put_samples(0, 0.0, ((double) pos) / args.sample_frequency, - pos, 2, &samples[0], CASSETTE_WAVEFORM_16BIT); + pos, 2, &samples[0], WAVEFORM_16BIT); if (err != error::SUCCESS) goto done; @@ -893,16 +893,16 @@ void cassette_image::dump(const char *filename) if (!f) return; - io_generic saved_io = io; - const Format *saved_format = format; + io_generic saved_io = m_io; + const Format *saved_format = m_format; - io.file = f; - io.procs = &stdio_ioprocs_noclose; - format = &wavfile_format; - cassette_perform_save(this); + m_io.file = f; + m_io.procs = &stdio_ioprocs_noclose; + m_format = &wavfile_format; + perform_save(); - io = saved_io; - format = saved_format; + m_io = saved_io; + m_format = saved_format; fclose(f); } diff --git a/src/lib/formats/cassimg.h b/src/lib/formats/cassimg.h index 4553fcb9b27..ed71c49cbf5 100644 --- a/src/lib/formats/cassimg.h +++ b/src/lib/formats/cassimg.h @@ -22,7 +22,7 @@ #include <vector> #ifndef LOG_FORMATS -#define LOG_FORMATS if (0) printf +#define LOG_FORMATS(...) do { if (0) osd_printf_info(__VA_ARGS__); } while (false) #endif // hack to get around rogues that define this @@ -32,58 +32,51 @@ /*************************************************************************** - Constants + Type definitions ***************************************************************************/ -enum : int -{ - CASSETTE_FLAG_READWRITE = 0, - CASSETTE_FLAG_READONLY = 1, - CASSETTE_FLAG_NOSAVEONEXIT = 0, - CASSETTE_FLAG_SAVEONEXIT = 2 -}; - -enum : int -{ - CASSETTE_WAVEFORM_8BIT = 0, - CASSETTE_WAVEFORM_16BIT = 2, - CASSETTE_WAVEFORM_16BIT_FLIP = 3, - CASSETTE_WAVEFORM_32BIT = 4, - CASSETTE_WAVEFORM_32BIT_FLIP = 5, - CASSETTE_WAVEFORM_ENDIAN_FLIP = 1, - CASSETTE_WAVEFORM_UNSIGNED = 8 -}; - -enum : int +class cassette_image { - CASSETTE_MODULATION_SQUAREWAVE = 0, - CASSETTE_MODULATION_SINEWAVE = 1 -}; +public: + enum : int + { + FLAG_READWRITE = 0, + FLAG_READONLY = 1, + FLAG_NOSAVEONEXIT = 0, + FLAG_SAVEONEXIT = 2 + }; + enum : int + { + WAVEFORM_8BIT = 0, + WAVEFORM_16BIT = 2, + WAVEFORM_16BIT_FLIP = 3, + WAVEFORM_32BIT = 4, + WAVEFORM_32BIT_FLIP = 5, + WAVEFORM_ENDIAN_FLIP = 1, + WAVEFORM_UNSIGNED = 8, #ifdef LSB_FIRST -#define CASSETTE_WAVEFORM_16BITBE CASSETTE_WAVEFORM_16BIT_FLIP -#define CASSETTE_WAVEFORM_16BITLE CASSETTE_WAVEFORM_16BIT -#define CASSETTE_WAVEFORM_32BITBE CASSETTE_WAVEFORM_32BIT_FLIP -#define CASSETTE_WAVEFORM_32BITLE CASSETTE_WAVEFORM_32BIT + WAVEFORM_16BITBE = WAVEFORM_16BIT_FLIP, + WAVEFORM_16BITLE = WAVEFORM_16BIT, + WAVEFORM_32BITBE = WAVEFORM_32BIT_FLIP, + WAVEFORM_32BITLE = WAVEFORM_32BIT #else -#define CASSETTE_WAVEFORM_16BITBE CASSETTE_WAVEFORM_16BIT -#define CASSETTE_WAVEFORM_16BITLE CASSETTE_WAVEFORM_16BIT_FLIP -#define CASSETTE_WAVEFORM_32BITBE CASSETTE_WAVEFORM_32BIT -#define CASSETTE_WAVEFORM_32BITLE CASSETTE_WAVEFORM_32BIT_FLIP + WAVEFORM_16BITBE = WAVEFORM_16BIT, + WAVEFORM_16BITLE = WAVEFORM_16BIT_FLIP, + WAVEFORM_32BITBE = WAVEFORM_32BIT, + WAVEFORM_32BITLE = WAVEFORM_32BIT_FLIP #endif + }; + enum : int + { + MODULATION_SQUAREWAVE = 0, + MODULATION_SINEWAVE = 1 + }; -/*************************************************************************** - - Type definitions - -***************************************************************************/ -class cassette_image -{ -public: enum class error { SUCCESS, // no error @@ -167,19 +160,19 @@ public: double sample_period, size_t sample_count, uint64_t offset, int waveform_flags); // modulation support - error modulation_identify(const Modulation *modulation, + error modulation_identify(const Modulation &modulation, Options *opts); error put_modulated_data(int channel, double time_index, - const void *data, size_t data_length, const Modulation *modulation, + const void *data, size_t data_length, const Modulation &modulation, double *time_displacement); error put_modulated_filler(int channel, double time_index, - uint8_t filler, size_t filler_length, const Modulation *modulation, + uint8_t filler, size_t filler_length, const Modulation &modulation, double *time_displacement); error read_modulated_data(int channel, double time_index, - uint64_t offset, uint64_t length, const Modulation *modulation, + uint64_t offset, uint64_t length, const Modulation &modulation, double *time_displacement); error put_modulated_data_bit(int channel, double time_index, - uint8_t data, const Modulation *modulation, + uint8_t data, const Modulation &modulation, double *time_displacement); /* legacy code support */ @@ -202,25 +195,32 @@ public: static error create(void *file, const io_procs *procs, const cassette_image::Format *format, const cassette_image::Options *opts, int flags, ptr &outcassette); - const Format *format = nullptr; - io_generic io; - - int channels = 0; - int flags = 0; - uint32_t sample_frequency = 0; - - std::vector<std::unique_ptr<int32_t []> > blocks; - size_t sample_count = 0; - // builtin formats static const Format wavfile_format; private: + struct manipulation_ranges; + cassette_image(const Format *format, void *file, const io_procs *procs, int flags); cassette_image(const cassette_image &) = delete; cassette_image(cassette_image &&) = delete; cassette_image &operator=(const cassette_image &) = delete; cassette_image &operator=(cassette_image &&) = delete; + + error try_identify_format(const Format &format, const std::string &extension, int flags, Options &opts); + error perform_save(); + error compute_manipulation_ranges(int channel, double time_index, double sample_period, manipulation_ranges &ranges) const; + error lookup_sample(int channel, size_t sample, int32_t *&ptr); + + const Format *m_format = nullptr; + io_generic m_io; + + int m_channels = 0; + int m_flags = 0; + uint32_t m_sample_frequency = 0; + + std::vector<std::unique_ptr<int32_t []> > m_blocks; + size_t m_sample_count = 0; }; /* macros for specifying format lists */ diff --git a/src/lib/formats/coco_cas.cpp b/src/lib/formats/coco_cas.cpp index 75c68aae2a6..c0ed5d616ff 100644 --- a/src/lib/formats/coco_cas.cpp +++ b/src/lib/formats/coco_cas.cpp @@ -49,7 +49,7 @@ static int synccount; const cassette_image::Modulation coco_cas_modulation = { - CASSETTE_MODULATION_SINEWAVE, + cassette_image::MODULATION_SINEWAVE, 600.0, 1200.0, 1500.0, 1500.0, 2400.0, 3000.0 }; @@ -58,7 +58,7 @@ const cassette_image::Modulation coco_cas_modulation = static cassette_image::error coco_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette->modulation_identify(&coco_cas_modulation, opts); + return cassette->modulation_identify(coco_cas_modulation, opts); } @@ -192,7 +192,7 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) 0x3C, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A }; time_index = 10.0; - return cassette_put_modulated_data(cassette, 0, time_index, dummy_bytes, sizeof(dummy_bytes), &coco_cas_modulation, &time_displacement); + return cassette_put_modulated_data(cassette, 0, time_index, dummy_bytes, sizeof(dummy_bytes), coco_cas_modulation, &time_displacement); } #endif @@ -220,7 +220,7 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) time_index += silence; /* sync data */ - err = cassette->put_modulated_filler(0, time_index, 0x55, 128, &coco_cas_modulation, &time_displacement); + err = cassette->put_modulated_filler(0, time_index, 0x55, 128, coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; @@ -228,26 +228,26 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) else if (synccount != 0) /* If we have multiple sync bytes in cas file, make sure they */ { /* are passed through */ /* sync data */ - err = cassette->put_modulated_filler(0, time_index, 0x55, synccount, &coco_cas_modulation, &time_displacement); + err = cassette->put_modulated_filler(0, time_index, 0x55, synccount, coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; } /* now fill in the magic bytes */ - err = cassette->put_modulated_data(0, time_index, magic_bytes, sizeof(magic_bytes), &coco_cas_modulation, &time_displacement); + err = cassette->put_modulated_data(0, time_index, magic_bytes, sizeof(magic_bytes), coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; /* now fill in the block */ - err = cassette->put_modulated_data(0, time_index, block, block_length, &coco_cas_modulation, &time_displacement); + err = cassette->put_modulated_data(0, time_index, block, block_length, coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; /* and the last magic byte */ - err = cassette->put_modulated_filler(0, time_index, 0x55, 1, &coco_cas_modulation, &time_displacement); + err = cassette->put_modulated_filler(0, time_index, 0x55, 1, coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; @@ -256,7 +256,7 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) } /* all futher data is undecipherable, so output it verbatim */ - err = cassette->read_modulated_data(0, time_index, offset, image_size - offset, &coco_cas_modulation, &time_displacement); + err = cassette->read_modulated_data(0, time_index, offset, image_size - offset, coco_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; diff --git a/src/lib/formats/sc3000_bit.cpp b/src/lib/formats/sc3000_bit.cpp index 636d93543c6..ab0828e709a 100644 --- a/src/lib/formats/sc3000_bit.cpp +++ b/src/lib/formats/sc3000_bit.cpp @@ -28,7 +28,7 @@ static const cassette_image::Modulation sc3000_bit_modulation = { - CASSETTE_MODULATION_SINEWAVE, + cassette_image::MODULATION_SINEWAVE, 1200.0 - 300, 1200.0, 1200.0 + 300, 2400.0 - 600, 2400.0, 2400.0 + 600 }; @@ -39,7 +39,7 @@ static const cassette_image::Modulation sc3000_bit_modulation = static cassette_image::error sc3000_bit_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette->modulation_identify(&sc3000_bit_modulation, opts); + return cassette->modulation_identify(sc3000_bit_modulation, opts); } /*------------------------------------------------- @@ -48,7 +48,7 @@ static cassette_image::error sc3000_bit_identify(cassette_image *cassette, casse #define MODULATE(_value) \ for (int i = 0; i < (_value ? 2 : 1); i++) { \ - err = cassette->put_modulated_data_bit(0, time_index, _value, &sc3000_bit_modulation, &time_displacement);\ + err = cassette->put_modulated_data_bit(0, time_index, _value, sc3000_bit_modulation, &time_displacement);\ if (err != cassette_image::error::SUCCESS) return err;\ time_index += time_displacement;\ } diff --git a/src/lib/formats/sord_cas.cpp b/src/lib/formats/sord_cas.cpp index ba4ad1faa24..f90daafd248 100644 --- a/src/lib/formats/sord_cas.cpp +++ b/src/lib/formats/sord_cas.cpp @@ -20,7 +20,7 @@ static const uint8_t SORDM5_CAS_HEADER[6] = { 'S', 'O', 'R', 'D', 'M', '5'}; static const cassette_image::Modulation sordm5_cas_modulation = { - CASSETTE_MODULATION_SINEWAVE, + cassette_image::MODULATION_SINEWAVE, 1575.0 - 300, 1575.0, 1575.0 + 300, 3150.0 - 600, 3150.0, 3150.0 + 600 }; @@ -34,7 +34,7 @@ static uint8_t cassette_image_read_uint8( cassette_image *cassette, uint64_t off static cassette_image::error sordm5_tap_identify( cassette_image *cassette, cassette_image::Options *opts) { - return cassette->modulation_identify(&sordm5_cas_modulation, opts); + return cassette->modulation_identify(sordm5_cas_modulation, opts); } static cassette_image::error sordm5_tap_load( cassette_image *cassette) @@ -79,7 +79,7 @@ static cassette_image::error sordm5_tap_load( cassette_image *cassette) } // add sync if (block_type == 'H') filler_length = 2.4 * (3150 / 8); else filler_length = 0.15 * (3150 / 8); - err = cassette->put_modulated_filler(0, time_index, 0xFF, filler_length, &sordm5_cas_modulation, &time_displacement); + err = cassette->put_modulated_filler(0, time_index, 0xFF, filler_length, sordm5_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; // process block @@ -108,13 +108,13 @@ static cassette_image::error sordm5_tap_load( cassette_image *cassette) bit = (byte >> (j-2)) & 1; } // add bit - err = cassette->put_modulated_data_bit(0, time_index, bit, &sordm5_cas_modulation, &time_displacement); + err = cassette->put_modulated_data_bit(0, time_index, bit, sordm5_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; } } // mark end of block - err = cassette->put_modulated_data_bit(0, time_index, 1, &sordm5_cas_modulation, &time_displacement); + err = cassette->put_modulated_data_bit(0, time_index, 1, sordm5_cas_modulation, &time_displacement); if (err != cassette_image::error::SUCCESS) return err; time_index += time_displacement; // next block diff --git a/src/lib/formats/thom_cas.cpp b/src/lib/formats/thom_cas.cpp index 5ca6e6cde95..0d0cc4fc4eb 100644 --- a/src/lib/formats/thom_cas.cpp +++ b/src/lib/formats/thom_cas.cpp @@ -87,7 +87,7 @@ static uint8_t* to7_k7_bits; static const cassette_image::Modulation to7_k7_modulation = { - CASSETTE_MODULATION_SQUAREWAVE, + cassette_image::MODULATION_SQUAREWAVE, 4000.0, 4500.0, 5000.0, 5500.0, 6300.0, 7500.0 }; @@ -96,7 +96,7 @@ static const cassette_image::Modulation to7_k7_modulation = static cassette_image::error to7_k7_identify ( cassette_image *cass, cassette_image::Options *opts ) { - cassette_image::error e = cass->modulation_identify( &to7_k7_modulation, opts ); + cassette_image::error e = cass->modulation_identify( to7_k7_modulation, opts ); return e; } @@ -133,7 +133,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) { \ cassette_image::error err; \ err = cass->put_samples( 0, time, (PERIOD), 2, 1, \ - square_wave, CASSETTE_WAVEFORM_8BIT ); \ + square_wave, cassette_image::WAVEFORM_8BIT ); \ if ( err != cassette_image::error::SUCCESS ) \ return err; \ time += (PERIOD); \ diff --git a/src/lib/formats/wavfile.cpp b/src/lib/formats/wavfile.cpp index 1ab9598ac9a..74976ef997e 100644 --- a/src/lib/formats/wavfile.cpp +++ b/src/lib/formats/wavfile.cpp @@ -120,13 +120,13 @@ static cassette_image::error wavfile_process(cassette_image *cassette, cassette_ switch(opts->bits_per_sample) { case 8: - waveform_flags = CASSETTE_WAVEFORM_8BIT | CASSETTE_WAVEFORM_UNSIGNED; // 8-bits wav are stored unsigned + waveform_flags = cassette_image::WAVEFORM_8BIT | cassette_image::WAVEFORM_UNSIGNED; // 8-bits wav are stored unsigned break; case 16: - waveform_flags = CASSETTE_WAVEFORM_16BITLE; + waveform_flags = cassette_image::WAVEFORM_16BITLE; break; case 32: - waveform_flags = CASSETTE_WAVEFORM_32BITLE; + waveform_flags = cassette_image::WAVEFORM_32BITLE; break; default: return cassette_image::error::INVALID_IMAGE; @@ -186,7 +186,7 @@ static cassette_image::error wavfile_save(cassette_image *cassette, const casset uint16_t bits_per_sample; uint32_t data_size; size_t bytes_per_sample = 2; - int waveform_flags = CASSETTE_WAVEFORM_16BITLE; + int waveform_flags = cassette_image::WAVEFORM_16BITLE; uint16_t block_align; bits_per_sample = (uint16_t) (bytes_per_sample * 8); @@ -263,7 +263,7 @@ void wavfile_testload(const char *fname) if (!f) return; - if (cassette_open(f, &stdio_ioprocs, &wavfile_format, CASSETTE_FLAG_READONLY, &cassette)) + if (cassette_open(f, &stdio_ioprocs, &wavfile_format, cassette_image::FLAG_READONLY, &cassette)) { fclose(f); return; diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp index b67d9b4e303..e03a15203d5 100644 --- a/src/tools/castool.cpp +++ b/src/tools/castool.cpp @@ -194,7 +194,7 @@ int CLIB_DECL main(int argc, char *argv[]) return -1; } - if (cassette_image::open_choices(f, &stdio_ioprocs, get_extension(argv[3]), selected_formats, CASSETTE_FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) { + if (cassette_image::open_choices(f, &stdio_ioprocs, get_extension(argv[3]), selected_formats, cassette_image::FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) { fprintf(stderr, "Invalid format of input file.\n"); fclose(f); return -1; |