diff options
Diffstat (limited to 'src')
61 files changed, 1209 insertions, 1358 deletions
diff --git a/src/devices/bus/adamnet/ddp.cpp b/src/devices/bus/adamnet/ddp.cpp index 6e05689cb29..b4a17e909cd 100644 --- a/src/devices/bus/adamnet/ddp.cpp +++ b/src/devices/bus/adamnet/ddp.cpp @@ -58,7 +58,7 @@ void adam_digital_data_pack_device::adam_ddp_mem(address_map &map) map(0xf800, 0xffff).rom().region(M6801_TAG, 0); } -static const struct CassetteOptions adam_cassette_options = +static const cassette_image::Options adam_cassette_options = { 2, /* channels */ 16, /* bits per sample */ diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index 38f5fcfb059..8b408355ed4 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -83,13 +83,13 @@ void cassette_image_device::update() switch (int(m_state & CASSETTE_MASK_UISTATE)) // cast to int to suppress unhandled enum value warning { case CASSETTE_RECORD: - cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value); + m_cassette->put_sample(m_channel, m_position, new_position - m_position, m_value); break; case CASSETTE_PLAY: if (m_cassette) { - cassette_get_sample(m_cassette, m_channel, new_position, 0.0, &m_value); + m_cassette->get_sample(m_channel, new_position, 0.0, &m_value); // See if reached end of tape double length = get_length(); if (new_position > length) @@ -167,9 +167,7 @@ double cassette_image_device::get_position() double cassette_image_device::get_length() { - struct CassetteInfo info; - - cassette_get_info(m_cassette, &info); + cassette_image::Info info = m_cassette->get_info(); return ((double) info.sample_count) / info.sample_frequency; } @@ -258,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_create((void *)image, &image_ioprocs, &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_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, m_cassette); if (err != cassette_image::error::SUCCESS) goto error; } @@ -275,7 +273,7 @@ image_init_result cassette_image_device::internal_load(bool is_create) int cassette_flags = is_readonly() ? CASSETTE_FLAG_READONLY : (CASSETTE_FLAG_READWRITE | CASSETTE_FLAG_SAVEONEXIT); - err = cassette_open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, &m_cassette); + 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 if (err == cassette_image::error::READ_WRITE_UNSUPPORTED) @@ -337,8 +335,7 @@ void cassette_image_device::call_unload() update(); /* close out the cassette */ - cassette_close(m_cassette); - m_cassette = nullptr; + m_cassette.reset(); /* set to default state, but only change the UI state */ change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE); @@ -419,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(cassette, 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_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/imagedev/cassette.h b/src/devices/imagedev/cassette.h index ae3af3c6429..e36b61d688d 100644 --- a/src/devices/imagedev/cassette.h +++ b/src/devices/imagedev/cassette.h @@ -53,8 +53,8 @@ public: cassette_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); virtual ~cassette_image_device(); - void set_formats(const struct CassetteFormat* const *formats) { m_formats = formats; } - void set_create_opts(const struct CassetteOptions *create_opts) { m_create_opts = create_opts; } + void set_formats(const cassette_image::Format* const *formats) { m_formats = formats; } + void set_create_opts(const cassette_image::Options *create_opts) { m_create_opts = create_opts; } void set_default_state(cassette_state default_state) { m_default_state = default_state; } void set_interface(const char *interface) { m_interface = interface; } @@ -92,7 +92,7 @@ public: void set_speaker(int state) { change_state(state ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER); } int speaker_on() { return ((m_state & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_ENABLED) ? 1 : 0; } - cassette_image *get_image() { return m_cassette; } + cassette_image *get_image() { return m_cassette.get(); } double get_position(); double get_length(); void set_speed(double speed); @@ -117,7 +117,7 @@ protected: void update(); private: - cassette_image *m_cassette; + cassette_image::ptr m_cassette; cassette_state m_state; double m_position; double m_position_time; @@ -126,8 +126,8 @@ private: double m_speed; // speed multiplier for tape speeds other than standard 1.875ips (used in adam driver) int m_direction; // direction select char m_extension_list[256]; - const struct CassetteFormat* const *m_formats; - const struct CassetteOptions *m_create_opts; + const cassette_image::Format* const *m_formats; + const cassette_image::Options *m_create_opts; cassette_state m_default_state; const char * m_interface; diff --git a/src/devices/sound/tiasound.cpp b/src/devices/sound/tiasound.cpp index 37881135722..87fa657bfab 100644 --- a/src/devices/sound/tiasound.cpp +++ b/src/devices/sound/tiasound.cpp @@ -90,16 +90,127 @@ namespace { -struct tia +class tia { - /* structures to hold the 6 tia sound control bytes */ - uint8_t AUDC[2]; /* AUDCx (15, 16) */ - uint8_t AUDF[2]; /* AUDFx (17, 18) */ - int16_t AUDV[2]; /* AUDVx (19, 1A) */ +public: + tia(device_t &device, int clock, int sample_rate, int gain) : + tia_gain(gain) // set the gain factor (normally use TIA_DEFAULT_GAIN) + { + // fill the polynomials + poly_init(Bit4, 4, 4, 3); + poly_init(Bit5, 5, 5, 3); + poly_init(Bit9, 9, 9, 5); + + // calculate the sample 'divide by N' value based on the playback freq. + Samp_n_max = ((uint16_t)(uint32_t)clock << 8) / sample_rate; + Samp_n_cnt = Samp_n_max; /* initialize all bits of the sample counter */ + + if (Samp_n_max < 256) // we need to use oversampling for sample_rate > clock_rate + { + Samp_n_max = ((uint16_t)(uint32_t)sample_rate << 8) / clock; + Samp_n_cnt = Samp_n_max; + oversampling = true; + } - int16_t Outvol[2]; /* last output volume for each channel */ + device.save_item(NAME(AUDC)); + device.save_item(NAME(AUDF)); + device.save_item(NAME(AUDV)); + device.save_item(NAME(Outvol)); + device.save_item(NAME(P4)); + device.save_item(NAME(P5)); + device.save_item(NAME(P9)); + device.save_item(NAME(Div_n_cnt)); + device.save_item(NAME(Div_n_max)); + device.save_item(NAME(Div_3_cnt)); + device.save_item(NAME(Samp_n_cnt)); + device.save_item(NAME(oversampling)); + } - int tia_gain; /* initialized in tia_sound_init() */ + void write(offs_t offset, uint8_t data) + { + // determine which address was changed + uint8_t chan; + switch (offset) + { + case AUDC0: + AUDC[0] = data & 0x0f; + chan = 0; + break; + + case AUDC1: + AUDC[1] = data & 0x0f; + chan = 1; + break; + + case AUDF0: + AUDF[0] = data & 0x1f; + chan = 0; + break; + + case AUDF1: + AUDF[1] = data & 0x1f; + chan = 1; + break; + + case AUDV0: + AUDV[0] = ((data & 0x0f) << AUDV_SHIFT); + chan = 0; + break; + + case AUDV1: + AUDV[1] = ((data & 0x0f) << AUDV_SHIFT); + chan = 1; + break; + + default: + return; + } + + // an AUDC value of 0 is a special case + uint16_t new_val; + if (AUDC[chan] == SET_TO_1 || AUDC[chan] == POLY5_POLY5) + { + // indicate the clock is zero so no processing will occur + new_val = 0; + + // and set the output to the selected volume + Outvol[chan] = AUDV[chan]; + } + else + { + // otherwise calculate the 'divide by N' value + new_val = AUDF[chan] + 1; + + // if bits 2 & 3 are set, then multiply the 'div by n' count by 3 + if ((AUDC[chan] & DIV3_MASK) == DIV3_MASK && AUDC[chan] != POLY5_DIV3) + { + new_val *= 3; + } + } + + // only reset those channels that have changed + if (new_val != Div_n_max[chan]) + { + // reset the divide by n counters + Div_n_max[chan] = new_val; + + // if the channel is now volume only or was volume only + if ((Div_n_cnt[chan] == 0) || (new_val == 0)) + { + // reset the counter (otherwise let it complete the previous) + Div_n_cnt[chan] = new_val; + } + } + } + + // structures to hold the 6 tia sound control bytes + uint8_t AUDC[2] = { 0, 0 }; // AUDCx (15, 16) + uint8_t AUDF[2] = { 0, 0 }; // AUDFx (17, 18) + int16_t AUDV[2] = { 0, 0 }; // AUDVx (19, 1A) + + int16_t Outvol[2] = { 0, 0 }; // last output volume for each channel + + int tia_gain; // initialized in tia_sound_init() /* Initialze the bit patterns for the polynomials. */ @@ -115,23 +226,41 @@ struct tia uint8_t Bit9[POLY9_SIZE]; - uint8_t P4[2]; /* Position pointer for the 4-bit POLY array */ - uint8_t P5[2]; /* Position pointer for the 5-bit POLY array */ - uint16_t P9[2]; /* Position pointer for the 9-bit POLY array */ + uint8_t P4[2] = { 0, 0 }; // Position pointer for the 4-bit POLY array + uint8_t P5[2] = { 0, 0 }; // Position pointer for the 5-bit POLY array + uint16_t P9[2] = { 0, 0 }; // Position pointer for the 9-bit POLY array - uint8_t Div_n_cnt[2]; /* Divide by n counter. one for each channel */ - uint8_t Div_n_max[2]; /* Divide by n maximum, one for each channel */ - uint8_t Div_3_cnt[2]; /* Div 3 counter, used for POLY5_DIV3 mode */ + uint8_t Div_n_cnt[2] = { 0, 0 }; // Divide by n counter. one for each channel + uint8_t Div_n_max[2] = { 0, 0 }; // Divide by n maximum, one for each channel + uint8_t Div_3_cnt[2] = { 3, 3 }; // Div 3 counter, used for POLY5_DIV3 mode /* In my routines, I treat the sample output as another divide by N counter. */ /* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ /* which has 8 binary digits to the right of the decimal point. */ - uint16_t Samp_n_max; /* Sample max, multiplied by 256 */ - uint16_t Samp_n_cnt; /* Sample cnt. */ + uint16_t Samp_n_max; // Sample max, multiplied by 256 + uint16_t Samp_n_cnt; // Sample cnt. + + bool oversampling = false; // Added oversampling for sample_rate > clock_rate + +private: + template <unsigned N> + static void poly_init(uint8_t (&poly)[N], int size, int f0, int f1) + { + const int mask = (1 << size) - 1; + int x = mask; + + for (int i = 0; i < mask; i++) + { + const int bit0 = ((size - f0) ? (x >> (size - f0)) : x) & 0x01; + const int bit1 = ((size - f1) ? (x >> (size - f1)) : x) & 0x01; + poly[i] = x & 1; + /* calculate next bit */ + x = (x >> 1) | ((bit0 ^ bit1) << ( size - 1) ); + } + } - int oversampling; /* Added oversampling for sample_rate > clock_rate */ }; @@ -163,88 +292,9 @@ constexpr uint8_t Div31[POLY5_SIZE] = /* */ /*****************************************************************************/ -void tia_write(void *_chip, offs_t offset, uint8_t data) +void tia_write(void *chip, offs_t offset, uint8_t data) { - struct tia *chip = (struct tia *)_chip; - uint16_t new_val; - uint8_t chan; - - /* determine which address was changed */ - switch (offset) - { - case AUDC0: - chip->AUDC[0] = data & 0x0f; - chan = 0; - break; - - case AUDC1: - chip->AUDC[1] = data & 0x0f; - chan = 1; - break; - - case AUDF0: - chip->AUDF[0] = data & 0x1f; - chan = 0; - break; - - case AUDF1: - chip->AUDF[1] = data & 0x1f; - chan = 1; - break; - - case AUDV0: - chip->AUDV[0] = ((data & 0x0f) << AUDV_SHIFT); - chan = 0; - break; - - case AUDV1: - chip->AUDV[1] = ((data & 0x0f) << AUDV_SHIFT); - chan = 1; - break; - - default: - chan = 255; - break; - } - - /* if the output value changed */ - if (chan != 255) - { - /* an AUDC value of 0 is a special case */ - if (chip->AUDC[chan] == SET_TO_1 || chip->AUDC[chan] == POLY5_POLY5) - { - /* indicate the clock is zero so no processing will occur */ - new_val = 0; - - /* and set the output to the selected volume */ - chip->Outvol[chan] = chip->AUDV[chan]; - } - else - { - /* otherwise calculate the 'divide by N' value */ - new_val = chip->AUDF[chan] + 1; - - /* if bits 2 & 3 are set, then multiply the 'div by n' count by 3 */ - if ((chip->AUDC[chan] & DIV3_MASK) == DIV3_MASK && chip->AUDC[chan] != POLY5_DIV3) - { - new_val *= 3; - } - } - - /* only reset those channels that have changed */ - if (new_val != chip->Div_n_max[chan]) - { - /* reset the divide by n counters */ - chip->Div_n_max[chan] = new_val; - - /* if the channel is now volume only or was volume only */ - if ((chip->Div_n_cnt[chan] == 0) || (new_val == 0)) - { - /* reset the counter (otherwise let it complete the previous) */ - chip->Div_n_cnt[chan] = new_val; - } - } - } + reinterpret_cast<tia *>(chip)->write(offset, data); } @@ -266,7 +316,7 @@ void tia_write(void *_chip, offs_t offset, uint8_t data) void tia_process(void *_chip, write_stream_view &buffer) { - struct tia *chip = (struct tia *)_chip; + tia *chip = (tia *)_chip; uint8_t audc0, audc1; uint8_t div_n_cnt0, div_n_cnt1; uint8_t p5_0, p5_1; @@ -513,37 +563,6 @@ void tia_process(void *_chip, write_stream_view &buffer) } -static void poly_init(uint8_t *poly, int size, int f0, int f1) -{ - int mask = (1 << size) - 1; - int i, x = mask; - - for (i = 0; i < mask; i++) - { - int bit0 = ( ( size - f0 ) ? ( x >> ( size - f0 ) ) : x ) & 0x01; - int bit1 = ( ( size - f1 ) ? ( x >> ( size - f1 ) ) : x ) & 0x01; - poly[i] = x & 1; - /* calculate next bit */ - x = ( x >> 1 ) | ( ( bit0 ^ bit1 ) << ( size - 1) ); - } -} - -static void tia_save_state(device_t *device, tia *tia) -{ - device->save_item(NAME(tia->AUDC)); - device->save_item(NAME(tia->AUDF)); - device->save_item(NAME(tia->AUDV)); - device->save_item(NAME(tia->Outvol)); - device->save_item(NAME(tia->P4)); - device->save_item(NAME(tia->P5)); - device->save_item(NAME(tia->P9)); - device->save_item(NAME(tia->Div_n_cnt)); - device->save_item(NAME(tia->Div_n_max)); - device->save_item(NAME(tia->Div_3_cnt)); - device->save_item(NAME(tia->Samp_n_cnt)); - device->save_item(NAME(tia->oversampling)); -} - /*****************************************************************************/ /* Module: tia_sh_start() */ /* Purpose: to handle the power-up initialization functions */ @@ -561,52 +580,11 @@ static void tia_save_state(device_t *device, tia *tia) void *tia_sound_init(device_t *device, int clock, int sample_rate, int gain) { - struct tia *chip; - int chan; - - chip = global_alloc_clear<struct tia>(); - - /* set the gain factor (normally use TIA_DEFAULT_GAIN) */ - chip->tia_gain = gain; - - /* fill the polynomials */ - poly_init(chip->Bit4, 4, 4, 3); - poly_init(chip->Bit5, 5, 5, 3); - poly_init(chip->Bit9, 9, 9, 5); - - /* calculate the sample 'divide by N' value based on the playback freq. */ - chip->Samp_n_max = ((uint16_t)(uint32_t)clock << 8) / sample_rate; - chip->Samp_n_cnt = chip->Samp_n_max; /* initialize all bits of the sample counter */ - - if (chip->Samp_n_max < 256) /* we need to use oversampling for sample_rate > clock_rate */ - { - chip->Samp_n_max = ((uint16_t)(uint32_t)sample_rate << 8) / clock; - chip->Samp_n_cnt = chip->Samp_n_max; - chip->oversampling = 1; - } - - /* initialize the local globals */ - for (chan = CHAN1; chan <= CHAN2; chan++) - { - chip->Outvol[chan] = 0; - chip->Div_n_cnt[chan] = 0; - chip->Div_n_max[chan] = 0; - chip->Div_3_cnt[chan] = 3; - chip->AUDC[chan] = 0; - chip->AUDF[chan] = 0; - chip->AUDV[chan] = 0; - chip->P4[chan] = 0; - chip->P5[chan] = 0; - chip->P9[chan] = 0; - } - - tia_save_state(device, chip); - - return chip; + return new tia(*device, clock, sample_rate, gain); } void tia_sound_free(void *chip) { - global_free((struct tia *)chip); + delete(reinterpret_cast<tia *>(chip)); } diff --git a/src/devices/sound/wave.cpp b/src/devices/sound/wave.cpp index 330e861ca20..58307ec3f97 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(cassette, 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_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/a26_cas.cpp b/src/lib/formats/a26_cas.cpp index 0074da6aba3..09d7e2479e5 100644 --- a/src/lib/formats/a26_cas.cpp +++ b/src/lib/formats/a26_cas.cpp @@ -6,10 +6,10 @@ Atari 2600 SuperCharger support */ -#include <cassert> - #include "formats/a26_cas.h" +#include <cassert> + #define A26_CAS_SIZE 8448 #define A26_WAV_FREQUENCY 44100 @@ -132,7 +132,7 @@ static int a26_cas_to_wav_size( const uint8_t *casdata, int caslen ) { return a26_cas_do_work( nullptr, casdata ); } -static const struct CassetteLegacyWaveFiller a26_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller a26_legacy_fill_wave = { a26_cas_fill_wave, -1, 0, @@ -142,21 +142,21 @@ static const struct CassetteLegacyWaveFiller a26_legacy_fill_wave = { 0 }; -static cassette_image::error a26_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { +static cassette_image::error a26_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { uint64_t size; - size = cassette_image_size( cassette ); + size = cassette->image_size( ); if ( size == A26_CAS_SIZE ) { - return cassette_legacy_identify( cassette, opts, &a26_legacy_fill_wave ); + return cassette->legacy_identify( opts, &a26_legacy_fill_wave ); } return cassette_image::error::INVALID_IMAGE; } static cassette_image::error a26_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &a26_legacy_fill_wave ); + return cassette->legacy_construct( &a26_legacy_fill_wave ); } -static const struct CassetteFormat a26_cassette_format = { +static const cassette_image::Format a26_cassette_format = { "a26", a26_cassette_identify, a26_cassette_load, diff --git a/src/lib/formats/ace_tap.cpp b/src/lib/formats/ace_tap.cpp index 522050f612a..1619280b66b 100644 --- a/src/lib/formats/ace_tap.cpp +++ b/src/lib/formats/ace_tap.cpp @@ -10,10 +10,10 @@ For more information see: ********************************************************************/ -#include <cassert> - #include "ace_tap.h" +#include <cassert> + #define SMPLO -32768 #define SILENCE 0 @@ -155,7 +155,7 @@ static int ace_tap_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller ace_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller ace_legacy_fill_wave = { ace_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -167,19 +167,19 @@ static const struct CassetteLegacyWaveFiller ace_legacy_fill_wave = }; -static cassette_image::error ace_tap_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error ace_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &ace_legacy_fill_wave); + return cassette->legacy_identify(opts, &ace_legacy_fill_wave); } static cassette_image::error ace_tap_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &ace_legacy_fill_wave); + return cassette->legacy_construct(&ace_legacy_fill_wave); } -static const struct CassetteFormat ace_tap_format = +static const cassette_image::Format ace_tap_format = { "tap", ace_tap_identify, diff --git a/src/lib/formats/adam_cas.cpp b/src/lib/formats/adam_cas.cpp index 5d24eed2543..4c678bb0796 100644 --- a/src/lib/formats/adam_cas.cpp +++ b/src/lib/formats/adam_cas.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Curt Coder +#include "adam_cas.h" #include <cassert> -#include "cassimg.h" -#include "adam_cas.h" // This code will reproduce the timing of an adam tape played back on a standard tape deck with a 1 7/8ips speed. #define CASS_AMP 0x1fffffff @@ -50,7 +49,7 @@ Data is phase encoded, with 70us bit cells with a transition at 31us for a 1 and ****************************************************************/ -static cassette_image::error coladam_ddp_identify ( cassette_image *cass, struct CassetteOptions *opts ) +static cassette_image::error coladam_ddp_identify ( cassette_image *cass, cassette_image::Options *opts ) { opts -> bits_per_sample = 16; opts -> channels = 2; @@ -67,14 +66,14 @@ cassette_image::error coladam_put_byte(cassette_image *cass, int channel, double { if(byte & 0x80) { - err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD1, -CASS_AMP*(*prev_sign) ); + err = cass->put_sample( channel, *time_index, COL_ADAM_PERIOD1, -CASS_AMP*(*prev_sign) ); (*time_index) += COL_ADAM_PERIOD1; - err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD2, CASS_AMP*(*prev_sign) ); + err = cass->put_sample( channel, *time_index, COL_ADAM_PERIOD2, CASS_AMP*(*prev_sign) ); (*time_index) += COL_ADAM_PERIOD2; } else { - err = cassette_put_sample( cass, channel, *time_index, COL_ADAM_PERIOD, -CASS_AMP*(*prev_sign) ); + err = cass->put_sample( channel, *time_index, COL_ADAM_PERIOD, -CASS_AMP*(*prev_sign) ); (*prev_sign) *=-1; (*time_index) += COL_ADAM_PERIOD; } @@ -146,12 +145,12 @@ static cassette_image::error coladam_ddp_load( cassette_image *cass ) for (block = 0; block < 128; block++) { - cassette_image_read( cass, buffer, 0x20000+0x400*block, 0x400 ); + cass->image_read( buffer, 0x20000+0x400*block, 0x400 ); err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type); } for (block = 128; block < 131; block++) { - cassette_image_read( cass, buffer, 0x3f400+0x400*(block-128), 0x400 ); + cass->image_read( buffer, 0x3f400+0x400*(block-128), 0x400 ); err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type); } @@ -165,17 +164,17 @@ static cassette_image::error coladam_ddp_load( cassette_image *cass ) { for (block = 0; block < 64; block++) { - cassette_image_read( cass, buffer, 0x10000+0x400*block, 0x400 ); + cass->image_read( buffer, 0x10000+0x400*block, 0x400 ); err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type); } for (block = 64; block < 128; block++) { - cassette_image_read( cass, buffer, 0x00000+0x400*(block-64), 0x400 ); + cass->image_read( buffer, 0x00000+0x400*(block-64), 0x400 ); err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type); } for (block = 128; block < 131; block++) { - cassette_image_read( cass, buffer, 0x0f400+0x400*(block-128), 0x400 ); + cass->image_read( buffer, 0x0f400+0x400*(block-128), 0x400 ); err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type); } } @@ -188,12 +187,12 @@ static cassette_image::error coladam_ddp_load( cassette_image *cass ) } for (block = 0; block < 128; block++) { - cassette_image_read( cass, buffer, 0x400*block, 0x400 ); + cass->image_read( buffer, 0x400*block, 0x400 ); err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type); } for (block = 128; block < 131; block++) { - cassette_image_read( cass, buffer, 0x1f400+0x400*(block-128), 0x400 ); + cass->image_read( buffer, 0x1f400+0x400*(block-128), 0x400 ); err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type); } } @@ -203,7 +202,7 @@ static cassette_image::error coladam_ddp_load( cassette_image *cass ) -static const struct CassetteFormat coladam_ddp = +static const cassette_image::Format coladam_ddp = { "ddp", coladam_ddp_identify, coladam_ddp_load, nullptr /* no save */ }; CASSETTE_FORMATLIST_START(coleco_adam_cassette_formats) diff --git a/src/lib/formats/apf_apt.cpp b/src/lib/formats/apf_apt.cpp index 28793f0f853..e820090ef04 100644 --- a/src/lib/formats/apf_apt.cpp +++ b/src/lib/formats/apf_apt.cpp @@ -34,10 +34,10 @@ e. A checksum byte (8-bit addition) ********************************************************************/ -#include <cassert> - #include "formats/apf_apt.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -184,7 +184,7 @@ static int apf_cpf_calculate_size_in_samples(const uint8_t *bytes, int length) //********************************************************************************* -static const struct CassetteLegacyWaveFiller apf_cpf_fill_intf = +static const cassette_image::LegacyWaveFiller apf_cpf_fill_intf = { apf_cpf_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -195,17 +195,17 @@ static const struct CassetteLegacyWaveFiller apf_cpf_fill_intf = 0 /* trailer_samples */ }; -static cassette_image::error apf_cpf_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error apf_cpf_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &apf_cpf_fill_intf); + return cassette->legacy_identify(opts, &apf_cpf_fill_intf); } static cassette_image::error apf_cpf_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &apf_cpf_fill_intf); + return cassette->legacy_construct(&apf_cpf_fill_intf); } -static const struct CassetteFormat apf_cpf_format = +static const cassette_image::Format apf_cpf_format = { "cas,cpf", apf_cpf_identify, @@ -215,7 +215,7 @@ static const struct CassetteFormat apf_cpf_format = //********************************************************************************* -static const struct CassetteLegacyWaveFiller apf_apt_fill_intf = +static const cassette_image::LegacyWaveFiller apf_apt_fill_intf = { apf_apt_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -226,17 +226,17 @@ static const struct CassetteLegacyWaveFiller apf_apt_fill_intf = 0 /* trailer_samples */ }; -static cassette_image::error apf_apt_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error apf_apt_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &apf_apt_fill_intf); + return cassette->legacy_identify(opts, &apf_apt_fill_intf); } static cassette_image::error apf_apt_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &apf_apt_fill_intf); + return cassette->legacy_construct(&apf_apt_fill_intf); } -static const struct CassetteFormat apf_apt_format = +static const cassette_image::Format apf_apt_format = { "apt", apf_apt_identify, diff --git a/src/lib/formats/atom_tap.cpp b/src/lib/formats/atom_tap.cpp index 212208a6d37..9d2ac3dc627 100644 --- a/src/lib/formats/atom_tap.cpp +++ b/src/lib/formats/atom_tap.cpp @@ -40,11 +40,12 @@ */ -#include <cassert> - #include "atom_tap.h" #include "csw_cas.h" #include "uef_cas.h" + +#include <cassert> + /*************************************************************************** PARAMETERS ***************************************************************************/ @@ -59,7 +60,7 @@ CassetteModulation atom_tap_modulation -------------------------------------------------*/ -static const struct CassetteModulation atom_tap_modulation = +static const cassette_image::Modulation atom_tap_modulation = { CASSETTE_MODULATION_SINEWAVE, 1200.0 - 300, 1200.0, 1200.0 + 300, @@ -73,7 +74,7 @@ static const struct CassetteModulation atom_tap_modulation = static uint8_t cassette_image_read_uint8(cassette_image *cassette, uint64_t offset) { uint8_t data; - cassette_image_read(cassette, &data, offset, 1); + cassette->image_read(&data, offset, 1); return data; } @@ -81,9 +82,9 @@ static uint8_t cassette_image_read_uint8(cassette_image *cassette, uint64_t offs atom_tap_identify - identify cassette -------------------------------------------------*/ -static cassette_image::error atom_tap_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error atom_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_modulation_identify( cassette, &atom_tap_modulation, opts); + return cassette->modulation_identify(&atom_tap_modulation, opts); } /*------------------------------------------------- @@ -92,7 +93,7 @@ static cassette_image::error atom_tap_identify(cassette_image *cassette, struct #define MODULATE(_value) \ for (int i = 0; i < (_value ? 8 : 4); i++) { \ - err = cassette_put_modulated_data_bit(cassette, 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;\ } @@ -102,7 +103,7 @@ static cassette_image::error atom_tap_identify(cassette_image *cassette, struct static cassette_image::error atom_tap_load(cassette_image *cassette) { cassette_image::error err; - uint64_t image_size = cassette_image_size(cassette); + uint64_t image_size = cassette->image_size(); uint64_t image_pos = 0; double time_index = 0.0; double time_displacement; @@ -134,7 +135,7 @@ static cassette_image::error atom_tap_load(cassette_image *cassette) CassetteFormat atom_tap_cassette_format -------------------------------------------------*/ -const struct CassetteFormat atom_tap_format = +const cassette_image::Format atom_tap_format = { "tap", atom_tap_identify, diff --git a/src/lib/formats/camplynx_cas.cpp b/src/lib/formats/camplynx_cas.cpp index e802be4426f..5945650ca0a 100644 --- a/src/lib/formats/camplynx_cas.cpp +++ b/src/lib/formats/camplynx_cas.cpp @@ -191,7 +191,7 @@ static int camplynx_cassette_calculate_size_in_samples(const uint8_t *bytes, int return camplynx_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller lynx48k_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller lynx48k_legacy_fill_wave = { camplynx_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -202,7 +202,7 @@ static const struct CassetteLegacyWaveFiller lynx48k_legacy_fill_wave = 0 /* trailer_samples */ }; -static const struct CassetteLegacyWaveFiller lynx128k_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller lynx128k_legacy_fill_wave = { camplynx_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -213,27 +213,27 @@ static const struct CassetteLegacyWaveFiller lynx128k_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error lynx48k_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error lynx48k_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &lynx48k_legacy_fill_wave); + return cassette->legacy_identify(opts, &lynx48k_legacy_fill_wave); } -static cassette_image::error lynx128k_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error lynx128k_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &lynx128k_legacy_fill_wave); + return cassette->legacy_identify(opts, &lynx128k_legacy_fill_wave); } static cassette_image::error lynx48k_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &lynx48k_legacy_fill_wave); + return cassette->legacy_construct(&lynx48k_legacy_fill_wave); } static cassette_image::error lynx128k_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &lynx128k_legacy_fill_wave); + return cassette->legacy_construct(&lynx128k_legacy_fill_wave); } -static const struct CassetteFormat lynx48k_cassette_image_format = +static const cassette_image::Format lynx48k_cassette_image_format = { "tap", lynx48k_cassette_identify, @@ -241,7 +241,7 @@ static const struct CassetteFormat lynx48k_cassette_image_format = nullptr }; -static const struct CassetteFormat lynx128k_cassette_image_format = +static const cassette_image::Format lynx128k_cassette_image_format = { "tap", lynx128k_cassette_identify, diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp index 4f5d9320754..37ca1bd1dfa 100644 --- a/src/lib/formats/cassimg.cpp +++ b/src/lib/formats/cassimg.cpp @@ -8,12 +8,12 @@ *********************************************************************/ -#include <cstring> -#include <cassert> - -#include "imageutl.h" #include "cassimg.h" +#include "imageutl.h" + #include <algorithm> +#include <cassert> +#include <cstring> /* debugging parameters */ @@ -28,21 +28,22 @@ CASSETTE_FORMATLIST_START(cassette_default_formats) CASSETTE_FORMATLIST_END +namespace { /********************************************************************* helper code *********************************************************************/ -static double map_double(double d, uint64_t low, uint64_t high, uint64_t value) +constexpr double map_double(double d, uint64_t low, uint64_t high, uint64_t value) { return d * (value - low) / (high - low); } -static size_t waveform_bytes_per_sample(int waveform_flags) +constexpr size_t waveform_bytes_per_sample(int waveform_flags) { - return (size_t) (1 << ((waveform_flags & 0x06) / 2)); + return size_t(1 << ((waveform_flags & 0x06) / 2)); } @@ -51,24 +52,24 @@ static size_t waveform_bytes_per_sample(int waveform_flags) extrapolation and interpolation *********************************************************************/ -static int32_t extrapolate8(int8_t value) +constexpr int32_t extrapolate8(int8_t value) { - return ((int32_t) value) << 24; + return int32_t(value) << 24; } -static int32_t extrapolate16(int16_t value) +constexpr int32_t extrapolate16(int16_t value) { - return ((int32_t) value) << 16; + return int32_t(value) << 16; } -static int8_t interpolate8(int32_t value) +constexpr int8_t interpolate8(int32_t value) { - return (int8_t) (value >> 24); + return int8_t(value >> 24); } -static int16_t interpolate16(int32_t value) +constexpr int16_t interpolate16(int32_t value) { - return (int16_t) (value >> 16); + return int16_t(value >> 16); } @@ -77,41 +78,14 @@ static int16_t interpolate16(int32_t value) initialization and termination *********************************************************************/ -static cassette_image *cassette_init(const struct CassetteFormat *format, void *file, const struct io_procs *procs, int flags) -{ - cassette_image *cassette; - - cassette = global_alloc_clear<cassette_image>(); - cassette->format = format; - cassette->io.file = file; - cassette->io.procs = procs; - cassette->flags = flags; - return cassette; -} - - - -static void cassette_finishinit(cassette_image::error err, cassette_image *cassette, cassette_image **outcassette) -{ - if (cassette && ((err != cassette_image::error::SUCCESS) || !outcassette)) - { - cassette_close(cassette); - cassette = nullptr; - } - if (outcassette) - *outcassette = cassette; -} - - - -static cassette_image::error try_identify_format(const struct CassetteFormat &format, cassette_image *image, const std::string &extension, int flags, struct CassetteOptions &opts) +cassette_image::error try_identify_format(const cassette_image::Format &format, cassette_image *image, const std::string &extension, int flags, cassette_image::Options &opts) { // is this the right extension? if (!extension.empty() && !image_find_extension(format.extensions, extension.c_str())) return cassette_image::error::INVALID_IMAGE; // invoke format->identify - memset(&opts, 0, sizeof(opts)); + opts = cassette_image::Options(); cassette_image::error err = format.identify(image, &opts); if (err != cassette_image::error::SUCCESS) return err; @@ -125,287 +99,272 @@ static cassette_image::error try_identify_format(const struct CassetteFormat &fo } +cassette_image::error cassette_perform_save(cassette_image *cassette) +{ + cassette_image::Info info = cassette->get_info(); + return cassette->format->save(cassette, &info); +} + + -cassette_image::error cassette_open_choices(void *file, const struct io_procs *procs, const std::string &extension, - const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette) +/********************************************************************* + waveform accesses +*********************************************************************/ + +struct manipulation_ranges { - cassette_image::error err; - cassette_image *cassette; - const struct CassetteFormat *format; - struct CassetteOptions opts = {0, }; - int i; + int channel_first; + int channel_last; + size_t sample_first; + size_t sample_last; +}; - /* if not specified, use the dummy arguments */ - if (!formats) - formats = cassette_default_formats; - /* create the cassette object */ - cassette = cassette_init(nullptr, file, procs, flags); - if (!cassette) - { - err = cassette_image::error::OUT_OF_MEMORY; - goto done; - } - /* identify the image */ - format = nullptr; - for (i = 0; !format && formats[i]; i++) - { - // try this format - err = try_identify_format(*formats[i], cassette, extension, flags, opts); - if (err != cassette_image::error::SUCCESS && err != cassette_image::error::INVALID_IMAGE) - goto done; +constexpr size_t my_round(double d) +{ + return size_t(d + 0.5); +} - // did we succeed? - if (err == cassette_image::error::SUCCESS) - format = formats[i]; - } - /* have we found a proper format */ - if (!format) + +cassette_image::error compute_manipulation_ranges(cassette_image *cassette, int channel, + double time_index, double sample_period, manipulation_ranges *ranges) +{ + if (channel < 0) { - err = cassette_image::error::INVALID_IMAGE; - goto done; + ranges->channel_first = 0; + ranges->channel_last = cassette->channels - 1; + } + else + { + ranges->channel_first = channel; + ranges->channel_last = channel; } - cassette->format = format; - - /* read the options */ - cassette->channels = opts.channels; - cassette->sample_frequency = opts.sample_frequency; - /* load the image */ - err = format->load(cassette); - if (err != cassette_image::error::SUCCESS) - goto done; + ranges->sample_first = my_round(time_index * cassette->sample_frequency); + ranges->sample_last = my_round((time_index + sample_period) * cassette->sample_frequency); - /* success */ - cassette->flags &= ~CASSETTE_FLAG_DIRTY; - err = cassette_image::error::SUCCESS; + if (ranges->sample_last > ranges->sample_first) + ranges->sample_last--; -done: - cassette_finishinit(err, cassette, outcassette); - return err; + return cassette_image::error::SUCCESS; } -cassette_image::error cassette_open(void *file, const struct io_procs *procs, - const struct CassetteFormat *format, int flags, cassette_image **outcassette) +cassette_image::error lookup_sample(cassette_image *cassette, int channel, size_t sample, int32_t **ptr) { - const struct CassetteFormat *formats[2]; - formats[0] = format; - formats[1] = nullptr; - return cassette_open_choices(file, procs, nullptr, formats, flags, outcassette); -} + *ptr = nullptr; + size_t sample_blocknum = (sample / SAMPLES_PER_BLOCK) * cassette->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); -cassette_image::error cassette_create(void *file, const struct io_procs *procs, const struct CassetteFormat *format, - const struct CassetteOptions *opts, int flags, cassette_image **outcassette) -{ - cassette_image::error err; - cassette_image *cassette; - static const struct CassetteOptions default_options = { 1, 16, 44100 }; + *ptr = &cassette->blocks[sample_blocknum][sample_index]; + return cassette_image::error::SUCCESS; +} - /* cannot create to a read only image */ - if (flags & CASSETTE_FLAG_READONLY) - return cassette_image::error::INVALID_IMAGE; - /* is this a good format? */ - if (format->save == nullptr) - return cassette_image::error::INVALID_IMAGE; - /* normalize arguments */ - if (!opts) - opts = &default_options; +/********************************************************************* + waveform accesses to/from the raw image +*********************************************************************/ - /* create the cassette object */ - cassette = cassette_init(format, file, procs, flags); - if (!cassette) +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_MODULATION_SINEWAVE) { - err = cassette_image::error::OUT_OF_MEMORY; - goto done; + *wave_bytes_length = ARRAY_LENGTH(sine_wave); + return sine_wave; + } + else + { + *wave_bytes_length = ARRAY_LENGTH(square_wave); + return square_wave; } - - /* read the options */ - cassette->channels = opts->channels; - cassette->sample_frequency = opts->sample_frequency; - - err = cassette_image::error::SUCCESS; - -done: - cassette_finishinit(err, cassette, outcassette); - return err; } +} // anonymous namespace -static cassette_image::error cassette_perform_save(cassette_image *cassette) + +cassette_image::cassette_image(const Format *format, void *file, const io_procs *procs, int flags) { - struct CassetteInfo info; - cassette_get_info(cassette, &info); - return cassette->format->save(cassette, &info); + this->format = format; + this->io.file = file; + this->io.procs = procs; + this->flags = flags; } -cassette_image::error cassette_save(cassette_image *cassette) +cassette_image::~cassette_image() { - cassette_image::error err; - - if (!cassette->format || !cassette->format->save) - return cassette_image::error::UNSUPPORTED; - - err = cassette_perform_save(cassette); - if (err != cassette_image::error::SUCCESS) - return err; - - cassette->flags &= ~CASSETTE_FLAG_DIRTY; - return cassette_image::error::SUCCESS; + if ((flags & CASSETTE_FLAG_DIRTY) && (flags & CASSETTE_FLAG_SAVEONEXIT)) + save(); } -void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info) +cassette_image::error cassette_image::open(void *file, const io_procs *procs, + const Format *format, int flags, ptr &outcassette) { - memset(info, 0, sizeof(*info)); - info->channels = cassette->channels; - info->sample_count = cassette->sample_count; - info->sample_frequency = cassette->sample_frequency; - info->bits_per_sample = (int) waveform_bytes_per_sample(cassette->flags) * 8; + const Format *const formats[2] = { format, nullptr }; + return open_choices(file, procs, nullptr, formats, flags, outcassette); } -void cassette_close(cassette_image *cassette) +cassette_image::error cassette_image::open_choices(void *file, const io_procs *procs, const std::string &extension, + const Format *const *formats, int flags, ptr &outcassette) { - if (cassette) + // if not specified, use the dummy arguments + if (!formats) + formats = cassette_default_formats; + + // create the cassette object + ptr cassette; + try { cassette.reset(new cassette_image(nullptr, file, procs, flags)); } + catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } + + // identify the image + const Format *format = nullptr; + Options opts; + for (int i = 0; !format && formats[i]; i++) { - if ((cassette->flags & CASSETTE_FLAG_DIRTY) && (cassette->flags & CASSETTE_FLAG_SAVEONEXIT)) - cassette_save(cassette); - for (auto & elem : cassette->blocks) - { - global_free(elem); - } - global_free(cassette); + // try this format + error err = try_identify_format(*formats[i], cassette.get(), extension, flags, opts); + if (err != error::SUCCESS && err != error::INVALID_IMAGE) + return err; + + // did we succeed? + if (err == error::SUCCESS) + format = formats[i]; } -} + // have we found a proper format + if (!format) + return error::INVALID_IMAGE; + cassette->format = format; + // read the options + cassette->channels = opts.channels; + cassette->sample_frequency = opts.sample_frequency; -void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags) -{ - if ((flags & CASSETTE_FLAG_READONLY) == 0) - flags |= CASSETTE_FLAG_DIRTY; - cassette->io.file = file; - cassette->io.procs = procs; - cassette->format = format; - cassette->flags = flags; -} + // load the image + error err = format->load(cassette.get()); + if (err != error::SUCCESS) + return err; + /* success */ + cassette->flags &= ~CASSETTE_FLAG_DIRTY; + outcassette = std::move(cassette); + return error::SUCCESS; +} -/********************************************************************* - calls for accessing the raw cassette image -*********************************************************************/ -void cassette_image_read(cassette_image *cassette, void *buffer, uint64_t offset, size_t length) +cassette_image::error cassette_image::create(void *file, const io_procs *procs, const Format *format, + const Options *opts, int flags, ptr &outcassette) { - io_generic_read(&cassette->io, buffer, offset, length); -} + static const Options default_options = { 1, 16, 44100 }; + // cannot create to a read only image + if (flags & CASSETTE_FLAG_READONLY) + return error::INVALID_IMAGE; + // is this a good format? + if (format->save == nullptr) + return error::INVALID_IMAGE; -void cassette_image_write(cassette_image *cassette, const void *buffer, uint64_t offset, size_t length) -{ - io_generic_write(&cassette->io, buffer, offset, length); -} + // normalize arguments + if (!opts) + opts = &default_options; + // create the cassette object + ptr cassette; + try { cassette.reset(new cassette_image(format, file, procs, flags)); } + catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } + // read the options + cassette->channels = opts->channels; + cassette->sample_frequency = opts->sample_frequency; -uint64_t cassette_image_size(cassette_image *cassette) -{ - return io_generic_size(&cassette->io); + outcassette = std::move(cassette); + return error::SUCCESS; } -/********************************************************************* - waveform accesses -*********************************************************************/ - -struct manipulation_ranges +cassette_image::error cassette_image::save() { - int channel_first; - int channel_last; - size_t sample_first; - size_t sample_last; -}; + if (!format || !format->save) + return error::UNSUPPORTED; + + error err = cassette_perform_save(this); + if (err != error::SUCCESS) + return err; + + flags &= ~CASSETTE_FLAG_DIRTY; + return error::SUCCESS; +} -static size_t my_round(double d) +cassette_image::Info cassette_image::get_info() const { - size_t result; - d += 0.5; - result = (size_t) d; + 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; return result; } -static cassette_image::error compute_manipulation_ranges(cassette_image *cassette, int channel, - double time_index, double sample_period, struct manipulation_ranges *ranges) +void cassette_image::change(void *file, const io_procs *procs, const Format *format, int flags) { - if (channel < 0) - { - ranges->channel_first = 0; - ranges->channel_last = cassette->channels - 1; - } - else - { - ranges->channel_first = channel; - ranges->channel_last = channel; - } + if ((flags & CASSETTE_FLAG_READONLY) == 0) + flags |= CASSETTE_FLAG_DIRTY; + this->io.file = file; + this->io.procs = procs; + this->format = format; + this->flags = flags; +} - ranges->sample_first = my_round(time_index * cassette->sample_frequency); - ranges->sample_last = my_round((time_index + sample_period) * cassette->sample_frequency); - if (ranges->sample_last > ranges->sample_first) - ranges->sample_last--; - return cassette_image::error::SUCCESS; +/********************************************************************* + calls for accessing the raw cassette image +*********************************************************************/ + +void cassette_image::image_read(void *buffer, uint64_t offset, size_t length) +{ + io_generic_read(&io, buffer, offset, length); } -static cassette_image::error lookup_sample(cassette_image *cassette, int channel, size_t sample, int32_t **ptr) +void cassette_image::image_write(const void *buffer, uint64_t offset, size_t length) { - *ptr = nullptr; - size_t sample_blocknum = (sample / SAMPLES_PER_BLOCK) * cassette->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()) { - size_t osize = cassette->blocks.size(); - cassette->blocks.resize(sample_blocknum + 1); - memset(&cassette->blocks[osize], 0, (cassette->blocks.size()-osize)*sizeof(cassette->blocks[0])); - } + io_generic_write(&io, buffer, offset, length); +} - if (cassette->blocks[sample_blocknum] == nullptr) - cassette->blocks[sample_blocknum] = global_alloc(sample_block); - sample_block &block = *cassette->blocks[sample_blocknum]; - /* is this sample access off the current block? */ - if (sample_index >= block.size()) { - size_t osize = block.size(); - block.resize(SAMPLES_PER_BLOCK); - memset(&block[osize], 0, (SAMPLES_PER_BLOCK-osize)*sizeof(block[0])); - } - - *ptr = &block[sample_index]; - return cassette_image::error::SUCCESS; +uint64_t cassette_image::image_size() +{ + return io_generic_size(&io); } @@ -417,38 +376,29 @@ static cassette_image::error lookup_sample(cassette_image *cassette, int channel // Note: In normal use, the sample_spacing is the same as the sample size (in bytes) // But it can be larger to help do an interleaved write to samples // (see cassette_write_samples) -cassette_image::error cassette_get_samples(cassette_image *cassette, int channel, +cassette_image::error cassette_image::get_samples(int channel, double time_index, double sample_period, size_t sample_count, size_t sample_spacing, void *samples, int waveform_flags) { - cassette_image::error err; - struct manipulation_ranges ranges; - size_t sample_index; - size_t cassette_sample_index; - uint8_t *dest_ptr; + error err; + manipulation_ranges ranges; const int32_t *source_ptr; - double d; - int16_t word; - int32_t dword; - int64_t sum; - - assert(cassette); - err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges); - if (err != cassette_image::error::SUCCESS) + err = compute_manipulation_ranges(this, channel, time_index, sample_period, &ranges); + if (err != error::SUCCESS) return err; - for (sample_index = 0; sample_index < sample_count; sample_index++) + for (size_t sample_index = 0; sample_index < sample_count; sample_index++) { - sum = 0; + int64_t sum = 0; for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++) { /* find the sample that we are putting */ - d = map_double(ranges.sample_last + 1 - ranges.sample_first, 0, sample_count, sample_index) + ranges.sample_first; - cassette_sample_index = (size_t) d; - err = lookup_sample(cassette, channel, cassette_sample_index, (int32_t **) &source_ptr); - if (err != cassette_image::error::SUCCESS) + 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); + if (err != error::SUCCESS) return err; sum += *source_ptr; @@ -458,61 +408,54 @@ cassette_image::error cassette_get_samples(cassette_image *cassette, int channel sum /= (ranges.channel_last + 1 - ranges.channel_first); /* and write out the result */ - dest_ptr = (uint8_t*)samples; + uint8_t *dest_ptr = (uint8_t*)samples; dest_ptr += sample_index * sample_spacing; + int16_t word; + int32_t dword; 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) - word = swapendian_int16(word); - *((int16_t *) dest_ptr) = word; - break; - case 4: - dword = sum; - if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) - dword = swapendian_int32(dword); - *((int32_t *) dest_ptr) = dword; - break; + case 1: + *((int8_t *) dest_ptr) = interpolate8(sum); + break; + case 2: + word = interpolate16(sum); + if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + word = swapendian_int16(word); + *((int16_t *) dest_ptr) = word; + break; + case 4: + dword = sum; + if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP) + dword = swapendian_int32(dword); + *((int32_t *) dest_ptr) = dword; + break; } } - return cassette_image::error::SUCCESS; + return error::SUCCESS; } // Note: In normal use, the sample_spacing is the same as the sample size (in bytes) // But it can be larger to help do an interleaved read from samples // (see cassette_read_samples) -cassette_image::error cassette_put_samples(cassette_image *cassette, int channel, +cassette_image::error cassette_image::put_samples(int channel, double time_index, double sample_period, size_t sample_count, size_t sample_spacing, const void *samples, int waveform_flags) { - cassette_image::error err; - struct manipulation_ranges ranges; - size_t sample_index; + error err; + manipulation_ranges ranges; int32_t *dest_ptr; - int32_t dest_value; - int16_t word; - int32_t dword; - const uint8_t *source_ptr; - double d; - - if (!cassette) - return cassette_image::error::SUCCESS; if (sample_period == 0) - return cassette_image::error::SUCCESS; + return error::SUCCESS; - err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges); - if (err != cassette_image::error::SUCCESS) + err = compute_manipulation_ranges(this, channel, time_index, sample_period, &ranges); + if (err != error::SUCCESS) return err; - if (cassette->sample_count < ranges.sample_last+1) - cassette->sample_count = ranges.sample_last + 1; - cassette->flags |= CASSETTE_FLAG_DIRTY; + if (this->sample_count < ranges.sample_last+1) + this->sample_count = ranges.sample_last + 1; + flags |= CASSETTE_FLAG_DIRTY; if (LOG_PUT_SAMPLES) { @@ -521,14 +464,17 @@ cassette_image::error cassette_put_samples(cassette_image *cassette, int channel (int)ranges.sample_first, (int)ranges.sample_last); } - for (sample_index = ranges.sample_first; sample_index <= ranges.sample_last; sample_index++) + for (size_t sample_index = ranges.sample_first; sample_index <= ranges.sample_last; sample_index++) { /* figure out the source pointer */ - d = map_double(sample_count, ranges.sample_first, ranges.sample_last + 1, sample_index); - source_ptr = (const uint8_t*)samples; + double d = map_double(sample_count, ranges.sample_first, ranges.sample_last + 1, sample_index); + const uint8_t *source_ptr = (const uint8_t*)samples; source_ptr += ((size_t) d) * sample_spacing; /* compute the value that we are writing */ + int32_t dest_value; + int16_t word; + int32_t dword; switch(waveform_bytes_per_sample(waveform_flags)) { case 1: if (waveform_flags & CASSETTE_WAVEFORM_UNSIGNED) @@ -549,36 +495,36 @@ cassette_image::error cassette_put_samples(cassette_image *cassette, int channel dest_value = dword; break; default: - return cassette_image::error::INTERNAL; + return error::INTERNAL; } for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++) { /* find the sample that we are putting */ - err = lookup_sample(cassette, channel, sample_index, &dest_ptr); - if (err != cassette_image::error::SUCCESS) + err = lookup_sample(this, channel, sample_index, &dest_ptr); + if (err != error::SUCCESS) return err; *dest_ptr = dest_value; } } - return cassette_image::error::SUCCESS; + return error::SUCCESS; } -cassette_image::error cassette_get_sample(cassette_image *cassette, int channel, +cassette_image::error cassette_image::get_sample(int channel, double time_index, double sample_period, int32_t *sample) { - return cassette_get_samples(cassette, channel, time_index, + return get_samples(channel, time_index, sample_period, 1, 0, sample, CASSETTE_WAVEFORM_32BIT); } -cassette_image::error cassette_put_sample(cassette_image *cassette, int channel, +cassette_image::error cassette_image::put_sample(int channel, double time_index, double sample_period, int32_t sample) { - return cassette_put_samples(cassette, channel, time_index, + return put_samples(channel, time_index, sample_period, 1, 0, &sample, CASSETTE_WAVEFORM_32BIT); } @@ -588,153 +534,112 @@ cassette_image::error cassette_put_sample(cassette_image *cassette, int channel, waveform accesses to/from the raw image *********************************************************************/ -cassette_image::error cassette_read_samples(cassette_image *cassette, int channels, double time_index, +cassette_image::error cassette_image::read_samples(int channels, double time_index, double sample_period, size_t sample_count, uint64_t offset, int waveform_flags) { - cassette_image::error err; - size_t chunk_sample_count; - size_t bytes_per_sample; - size_t sample_spacing; + error err; size_t samples_loaded = 0; - double chunk_time_index; - double chunk_sample_period; - int channel; uint8_t buffer[8192]; - bytes_per_sample = waveform_bytes_per_sample(waveform_flags); - sample_spacing = bytes_per_sample * channels; + size_t bytes_per_sample = waveform_bytes_per_sample(waveform_flags); + size_t sample_spacing = bytes_per_sample * channels; - while(samples_loaded < sample_count) + while (samples_loaded < sample_count) { - chunk_sample_count = std::min(sizeof(buffer) / sample_spacing, (sample_count - samples_loaded)); - chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count); - chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_loaded); + size_t chunk_sample_count = std::min(sizeof(buffer) / sample_spacing, (sample_count - samples_loaded)); + double chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count); + double chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_loaded); - cassette_image_read(cassette, buffer, offset, chunk_sample_count * sample_spacing); + image_read(buffer, offset, chunk_sample_count * sample_spacing); - for (channel = 0; channel < channels; channel++) + for (int channel = 0; channel < channels; channel++) { - err = cassette_put_samples(cassette, channel, chunk_time_index, chunk_sample_period, + err = put_samples(channel, chunk_time_index, chunk_sample_period, chunk_sample_count, sample_spacing, &buffer[channel * bytes_per_sample], waveform_flags); - if (err != cassette_image::error::SUCCESS) + if (err != error::SUCCESS) return err; } offset += chunk_sample_count * sample_spacing; samples_loaded += chunk_sample_count; } - return cassette_image::error::SUCCESS; + return error::SUCCESS; } -cassette_image::error cassette_write_samples(cassette_image *cassette, int channels, double time_index, +cassette_image::error cassette_image::write_samples(int channels, double time_index, double sample_period, size_t sample_count, uint64_t offset, int waveform_flags) { - cassette_image::error err; - size_t chunk_sample_count; - size_t bytes_per_sample; - size_t sample_spacing; + error err; size_t samples_saved = 0; - double chunk_time_index; - double chunk_sample_period; - int channel; uint8_t buffer[8192]; - bytes_per_sample = waveform_bytes_per_sample(waveform_flags); - sample_spacing = bytes_per_sample * channels; + size_t bytes_per_sample = waveform_bytes_per_sample(waveform_flags); + size_t sample_spacing = bytes_per_sample * channels; - while(samples_saved < sample_count) + while (samples_saved < sample_count) { - chunk_sample_count = std::min(sizeof(buffer) / sample_spacing, (sample_count - samples_saved)); - chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count); - chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_saved); + size_t chunk_sample_count = std::min(sizeof(buffer) / sample_spacing, (sample_count - samples_saved)); + double chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count); + double chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_saved); - for (channel = 0; channel < channels; channel++) + for (int channel = 0; channel < channels; channel++) { - err = cassette_get_samples(cassette, channel, chunk_time_index, chunk_sample_period, + err = get_samples(channel, chunk_time_index, chunk_sample_period, chunk_sample_count, sample_spacing, &buffer[channel * bytes_per_sample], waveform_flags); - if (err != cassette_image::error::SUCCESS) + if (err != error::SUCCESS) return err; } - cassette_image_write(cassette, buffer, offset, chunk_sample_count * sample_spacing); + image_write(buffer, offset, chunk_sample_count * sample_spacing); offset += chunk_sample_count * sample_spacing; samples_saved += chunk_sample_count; } - return cassette_image::error::SUCCESS; -} - - - -/********************************************************************* - waveform accesses to/from the raw image -*********************************************************************/ - -static const int8_t *choose_wave(const struct CassetteModulation *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_MODULATION_SINEWAVE) - { - *wave_bytes_length = ARRAY_LENGTH(sine_wave); - return sine_wave; - } - else - { - *wave_bytes_length = ARRAY_LENGTH(square_wave); - return square_wave; - } + return error::SUCCESS; } -cassette_image::error cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation, - struct CassetteOptions *opts) +cassette_image::error cassette_image::modulation_identify(const Modulation *modulation, Options *opts) { size_t 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); - return cassette_image::error::SUCCESS; + 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_put_modulated_data(cassette_image *cassette, int channel, double time_index, - const void *data, size_t data_length, const struct CassetteModulation *modulation, +cassette_image::error cassette_image::put_modulated_data(int channel, double time_index, + const void *data, size_t data_length, const Modulation *modulation, double *time_displacement) { - cassette_image::error err; + error err; const uint8_t *data_bytes = (const uint8_t *)data; - const int8_t *wave_bytes; size_t wave_bytes_length; double total_displacement = 0.0; - double pulse_period; - double pulse_frequency; - uint8_t b; - int i; - wave_bytes = choose_wave(modulation, &wave_bytes_length); + const int8_t *wave_bytes = choose_wave(modulation, &wave_bytes_length); - while(data_length--) + while (data_length--) { - b = *(data_bytes++); - for (i = 0; i < 8; i++) + uint8_t b = *(data_bytes++); + for (int i = 0; i < 8; i++) { - pulse_frequency = (b & (1 << i)) ? modulation->one_frequency_canonical : modulation->zero_frequency_canonical; - pulse_period = 1 / pulse_frequency; - err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT); - if (err != cassette_image::error::SUCCESS) + 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); + 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) @@ -744,18 +649,18 @@ done: -cassette_image::error cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index, - uint8_t filler, size_t filler_length, const struct CassetteModulation *modulation, +cassette_image::error cassette_image::put_modulated_filler(int channel, double time_index, + uint8_t filler, size_t filler_length, const Modulation *modulation, double *time_displacement) { - cassette_image::error err; + error err; double delta; double total_displacement = 0.0; - while(filler_length--) + while (filler_length--) { - err = cassette_put_modulated_data(cassette, channel, time_index, &filler, 1, modulation, &delta); - if (err != cassette_image::error::SUCCESS) + err = put_modulated_data(channel, time_index, &filler, 1, modulation, &delta); + if (err != error::SUCCESS) return err; total_displacement += delta; time_index += delta; @@ -763,24 +668,19 @@ cassette_image::error cassette_put_modulated_filler(cassette_image *cassette, in if (time_displacement) *time_displacement = total_displacement; - return cassette_image::error::SUCCESS; + return error::SUCCESS; } -cassette_image::error cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index, - uint64_t offset, uint64_t length, const struct CassetteModulation *modulation, +cassette_image::error cassette_image::read_modulated_data(int channel, double time_index, + uint64_t offset, uint64_t length, const Modulation *modulation, double *time_displacement) { - cassette_image::error err; - uint8_t buffer_stack[1024]; uint8_t *buffer; - uint8_t *alloc_buffer = nullptr; - double delta; - double total_displacement = 0.0; - size_t this_length; + uint8_t buffer_stack[1024]; + std::unique_ptr<uint8_t []> alloc_buffer; size_t buffer_length; - if (length <= sizeof(buffer_stack)) { buffer = buffer_stack; @@ -789,23 +689,21 @@ cassette_image::error cassette_read_modulated_data(cassette_image *cassette, int else { buffer_length = std::min<uint64_t>(length, 100000); - alloc_buffer = (uint8_t*)malloc(buffer_length); - if (!alloc_buffer) - { - err = cassette_image::error::OUT_OF_MEMORY; - goto done; - } - buffer = alloc_buffer; + try { alloc_buffer = std::make_unique<uint8_t []>(buffer_length); } + catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } + buffer = alloc_buffer.get(); } - while(length > 0) + double delta; + double total_displacement = 0.0; + while (length > 0) { - this_length = (std::min<uint64_t>)(length, buffer_length); - cassette_image_read(cassette, buffer, offset, this_length); + size_t this_length = std::min<uint64_t>(length, buffer_length); + image_read(buffer, offset, this_length); - err = cassette_put_modulated_data(cassette, channel, time_index, buffer, this_length, modulation, &delta); - if (err != cassette_image::error::SUCCESS) - goto done; + error err = put_modulated_data(channel, time_index, buffer, this_length, modulation, &delta); + if (err != error::SUCCESS) + return err; total_displacement += delta; time_index += delta; length -= this_length; @@ -813,32 +711,24 @@ cassette_image::error cassette_read_modulated_data(cassette_image *cassette, int if (time_displacement) *time_displacement = total_displacement; - err = cassette_image::error::SUCCESS; - -done: - if (alloc_buffer) - free(alloc_buffer); - return err; + return error::SUCCESS; } -cassette_image::error cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index, - uint8_t data, const struct CassetteModulation *modulation, +cassette_image::error cassette_image::put_modulated_data_bit(int channel, double time_index, + uint8_t data, const Modulation *modulation, double *time_displacement) { - cassette_image::error err; - const int8_t *wave_bytes; + error err; size_t wave_bytes_length; double total_displacement = 0.0; - double pulse_period; - double pulse_frequency; - wave_bytes = choose_wave(modulation, &wave_bytes_length); + const int8_t *wave_bytes = choose_wave(modulation, &wave_bytes_length); - pulse_frequency = (data) ? modulation->one_frequency_canonical : modulation->zero_frequency_canonical; - pulse_period = 1 / pulse_frequency; - err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT); + 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) goto done; time_index += pulse_period; @@ -858,8 +748,8 @@ done: waveform accesses to/from the raw image *********************************************************************/ -cassette_image::error cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts, - const struct CassetteLegacyWaveFiller *legacy_args) +cassette_image::error cassette_image::legacy_identify(Options *opts, + const LegacyWaveFiller *legacy_args) { opts->channels = 1; opts->bits_per_sample = 16; @@ -869,56 +759,52 @@ cassette_image::error cassette_legacy_identify(cassette_image *cassette, struct -cassette_image::error cassette_legacy_construct(cassette_image *cassette, - const struct CassetteLegacyWaveFiller *legacy_args) +cassette_image::error cassette_image::legacy_construct(const LegacyWaveFiller *legacy_args) { - cassette_image::error err; + error err; int length; int sample_count; std::vector<uint8_t> bytes; - std::vector<uint8_t> chunk; std::vector<int16_t> samples; int pos = 0; uint64_t offset = 0; - uint64_t size; - struct CassetteLegacyWaveFiller args; /* sanity check the args */ assert(legacy_args->header_samples >= -1); assert(legacy_args->trailer_samples >= 0); assert(legacy_args->fill_wave); - size = cassette_image_size(cassette); + uint64_t size = image_size(); /* normalize the args */ - args = *legacy_args; + LegacyWaveFiller args = *legacy_args; if (args.chunk_size == 0) args.chunk_size = 1; else if (args.chunk_size < 0) - args.chunk_size = cassette_image_size(cassette); + args.chunk_size = image_size(); if (args.sample_frequency == 0) args.sample_frequency = 11025; /* allocate a buffer for the binary data */ - chunk.resize(args.chunk_size); + std::vector<uint8_t> chunk(args.chunk_size); /* determine number of samples */ if (args.chunk_sample_calc != nullptr) { if (size > 0x7FFFFFFF) { - err = cassette_image::error::OUT_OF_MEMORY; + err = error::OUT_OF_MEMORY; goto done; } bytes.resize(size); - cassette_image_read(cassette, &bytes[0], 0, size); + image_read(&bytes[0], 0, size); sample_count = args.chunk_sample_calc(&bytes[0], (int)size); // chunk_sample_calc functions report errors by returning negative numbers if (sample_count < 0) { - err = cassette_image::error::INVALID_IMAGE; + err = error::INVALID_IMAGE; goto done; } @@ -941,22 +827,22 @@ cassette_image::error cassette_legacy_construct(cassette_image *cassette, length = args.fill_wave(&samples[pos], sample_count - pos, CODE_HEADER); if (length < 0) { - err = cassette_image::error::INVALID_IMAGE; + err = error::INVALID_IMAGE; goto done; } pos += length; } /* convert the file data to samples */ - while((pos < sample_count) && (offset < size)) + while ((pos < sample_count) && (offset < size)) { - cassette_image_read(cassette, &chunk[0], offset, args.chunk_size); + image_read(&chunk[0], offset, args.chunk_size); offset += args.chunk_size; length = args.fill_wave(&samples[pos], sample_count - pos, &chunk[0]); if (length < 0) { - err = cassette_image::error::INVALID_IMAGE; + err = error::INVALID_IMAGE; goto done; } pos += length; @@ -970,23 +856,23 @@ cassette_image::error cassette_legacy_construct(cassette_image *cassette, length = args.fill_wave(&samples[pos], sample_count - pos, CODE_TRAILER); if (length < 0) { - err = cassette_image::error::INVALID_IMAGE; + err = error::INVALID_IMAGE; goto done; } pos += length; } /* specify the wave */ - err = cassette_put_samples(cassette, 0, 0.0, ((double) pos) / args.sample_frequency, + err = put_samples(0, 0.0, ((double) pos) / args.sample_frequency, pos, 2, &samples[0], CASSETTE_WAVEFORM_16BIT); - if (err != cassette_image::error::SUCCESS) + if (err != error::SUCCESS) goto done; /* success! */ - err = cassette_image::error::SUCCESS; + err = error::SUCCESS; #if DUMP_CASSETTES - cassette_dump(cassette, "C:\\TEMP\\CASDUMP.WAV"); + dump("C:\\TEMP\\CASDUMP.WAV"); #endif done: @@ -1001,26 +887,22 @@ done: A debugging call to dump a cassette image to a disk based wave file *********************************************************************/ -void cassette_dump(cassette_image *image, const char *filename) +void cassette_image::dump(const char *filename) { - FILE *f; - struct io_generic saved_io; - const struct CassetteFormat *saved_format; - - f = fopen(filename, "wb"); + FILE *f = fopen(filename, "wb"); if (!f) return; - memcpy(&saved_io, &image->io, sizeof(saved_io)); - saved_format = image->format; + io_generic saved_io = io; + const Format *saved_format = format; - image->io.file = f; - image->io.procs = &stdio_ioprocs_noclose; - image->format = &wavfile_format; - cassette_perform_save(image); + io.file = f; + io.procs = &stdio_ioprocs_noclose; + format = &wavfile_format; + cassette_perform_save(this); - memcpy(&image->io, &saved_io, sizeof(saved_io)); - image->format = saved_format; + io = saved_io; + format = saved_format; fclose(f); } diff --git a/src/lib/formats/cassimg.h b/src/lib/formats/cassimg.h index 5199c0e4a04..4553fcb9b27 100644 --- a/src/lib/formats/cassimg.h +++ b/src/lib/formats/cassimg.h @@ -14,9 +14,10 @@ #include "ioprocs.h" -#include "osdcore.h" #include "coretmpl.h" +#include "osdcore.h" +#include <memory> #include <string> #include <vector> @@ -35,21 +36,30 @@ ***************************************************************************/ -#define CASSETTE_FLAG_READWRITE 0 -#define CASSETTE_FLAG_READONLY 1 -#define CASSETTE_FLAG_NOSAVEONEXIT 0 -#define CASSETTE_FLAG_SAVEONEXIT 2 +enum : int +{ + CASSETTE_FLAG_READWRITE = 0, + CASSETTE_FLAG_READONLY = 1, + CASSETTE_FLAG_NOSAVEONEXIT = 0, + CASSETTE_FLAG_SAVEONEXIT = 2 +}; -#define CASSETTE_WAVEFORM_8BIT 0 -#define CASSETTE_WAVEFORM_16BIT 2 -#define CASSETTE_WAVEFORM_16BIT_FLIP 3 -#define CASSETTE_WAVEFORM_32BIT 4 -#define CASSETTE_WAVEFORM_32BIT_FLIP 5 -#define CASSETTE_WAVEFORM_ENDIAN_FLIP 1 -#define CASSETTE_WAVEFORM_UNSIGNED 8 +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 +}; -#define CASSETTE_MODULATION_SQUAREWAVE 0 -#define CASSETTE_MODULATION_SINEWAVE 1 +enum : int +{ + CASSETTE_MODULATION_SQUAREWAVE = 0, + CASSETTE_MODULATION_SINEWAVE = 1 +}; #ifdef LSB_FIRST @@ -71,25 +81,9 @@ ***************************************************************************/ -typedef std::vector<int32_t> sample_block; - -struct CassetteOptions -{ - int channels; - int bits_per_sample; - uint32_t sample_frequency; -}; - -struct CassetteInfo -{ - int channels; - int bits_per_sample; - uint32_t sample_frequency; - size_t sample_count; -}; - -struct cassette_image +class cassette_image { +public: enum class error { SUCCESS, // no error @@ -100,133 +94,149 @@ struct cassette_image READ_WRITE_UNSUPPORTED // read/write is not supported by this image format }; - const struct CassetteFormat *format; - struct io_generic io; + using ptr = std::unique_ptr<cassette_image>; - int channels; - int flags; - uint32_t sample_frequency; + struct Options + { + int channels = 0; + int bits_per_sample = 0; + uint32_t sample_frequency = 0; + }; - std::vector<sample_block *> blocks; - size_t sample_count; -}; + struct Info + { + int channels = 0; + int bits_per_sample = 0; + uint32_t sample_frequency = 0; + size_t sample_count = 0; + }; -struct CassetteFormat -{ - const char *extensions; - cassette_image::error (*identify)(cassette_image *cassette, struct CassetteOptions *opts); - cassette_image::error (*load)(cassette_image *cassette); - cassette_image::error (*save)(cassette_image *cassette, const struct CassetteInfo *info); -}; + struct Format + { + const char *extensions = nullptr; + error (*identify)(cassette_image *cassette, Options *opts) = nullptr; + error (*load)(cassette_image *cassette) = nullptr; + error (*save)(cassette_image *cassette, const Info *info) = nullptr; + }; -/* used for the core modulation code */ -struct CassetteModulation -{ - int flags; - double zero_frequency_low; - double zero_frequency_canonical; - double zero_frequency_high; - double one_frequency_low; - double one_frequency_canonical; - double one_frequency_high; -}; + /* used for the core modulation code */ + struct Modulation + { + int flags = 0; + double zero_frequency_low = 0; + double zero_frequency_canonical = 0; + double zero_frequency_high = 0; + double one_frequency_low = 0; + double one_frequency_canonical = 0; + double one_frequency_high = 0; + }; -/* code to adapt existing legacy fill_wave functions */ -struct CassetteLegacyWaveFiller -{ - int (*fill_wave)(int16_t *, int, uint8_t *); - int chunk_size; - int chunk_samples; - int (*chunk_sample_calc)(const uint8_t *bytes, int length); - uint32_t sample_frequency; - int header_samples; - int trailer_samples; -}; + /* code to adapt existing legacy fill_wave functions */ + struct LegacyWaveFiller + { + int (*fill_wave)(int16_t *, int, uint8_t *) = nullptr; + int chunk_size = 0; + int chunk_samples = 0; + int (*chunk_sample_calc)(const uint8_t *bytes, int length) = nullptr; + uint32_t sample_frequency = 0; + int header_samples = 0; + int trailer_samples = 0; + }; -/* builtin formats */ -extern const struct CassetteFormat wavfile_format; + ~cassette_image(); + + // calls for accessing the raw cassette image + void image_read(void *buffer, uint64_t offset, size_t length); + void image_write(const void *buffer, uint64_t offset, size_t length); + uint64_t image_size(); + + // waveform accesses + error get_samples(int channel, + double time_index, double sample_period, size_t sample_count, size_t sample_spacing, + void *samples, int waveform_flags); + error put_samples(int channel, + double time_index, double sample_period, size_t sample_count, size_t sample_spacing, + const void *samples, int waveform_flags); + error get_sample(int channel, double time_index, double sample_period, int32_t *sample); + error put_sample(int channel, double time_index, double sample_period, int32_t sample); + + // waveform accesses to/from the raw image - these are only used by lib\formats\wavfile.cpp + error read_samples(int channels, double time_index, + double sample_period, size_t sample_count, uint64_t offset, int waveform_flags); + error write_samples(int channels, double time_index, + double sample_period, size_t sample_count, uint64_t offset, int waveform_flags); + + // modulation support + 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, + double *time_displacement); + error put_modulated_filler(int channel, double time_index, + 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, + double *time_displacement); + error put_modulated_data_bit(int channel, double time_index, + uint8_t data, const Modulation *modulation, + double *time_displacement); + + /* legacy code support */ +#define CODE_HEADER ((uint8_t*)-1) +#define CODE_TRAILER ((uint8_t*)-2) + error legacy_identify(Options *opts, const LegacyWaveFiller *legacy_args); + error legacy_construct(const LegacyWaveFiller *legacy_args); + + /* debug calls */ + void dump(const char *filename); + + error save(); + void change(void *file, const io_procs *procs, const Format *format, int flags); + Info get_info() const; + + static error open(void *file, const io_procs *procs, + const Format *format, int flags, ptr &outcassette); + static error open_choices(void *file, const io_procs *procs, const std::string &extension, + const Format *const *formats, int flags, ptr &outcassette); + 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: + 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; +}; /* macros for specifying format lists */ #define CASSETTE_FORMATLIST_EXTERN(name) \ - extern const struct CassetteFormat *const name[] + extern const cassette_image::Format *const name[] #define CASSETTE_FORMATLIST_START(name) \ - const struct CassetteFormat *const name[] = \ + const cassette_image::Format *const name[] = \ { \ - &wavfile_format, + &cassette_image::wavfile_format, #define CASSETTE_FORMAT(name) \ &(name), #define CASSETTE_FORMATLIST_END \ - nullptr \ + nullptr \ }; CASSETTE_FORMATLIST_EXTERN(cassette_default_formats); -/*************************************************************************** - - Prototypes - -***************************************************************************/ - -cassette_image::error cassette_open(void *file, const struct io_procs *procs, - const struct CassetteFormat *format, int flags, cassette_image **outcassette); -cassette_image::error cassette_open_choices(void *file, const struct io_procs *procs, const std::string &extension, - const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette); -cassette_image::error cassette_create(void *file, const struct io_procs *procs, const struct CassetteFormat *format, - const struct CassetteOptions *opts, int flags, cassette_image **outcassette); -cassette_image::error cassette_save(cassette_image *cassette); -void cassette_close(cassette_image *cassette); -void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags); -void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info); - -/* calls for accessing the raw cassette image */ -void cassette_image_read(cassette_image *cassette, void *buffer, uint64_t offset, size_t length); -void cassette_image_write(cassette_image *cassette, const void *buffer, uint64_t offset, size_t length); -uint64_t cassette_image_size(cassette_image *cassette); - -/* waveform accesses */ -cassette_image::error cassette_get_samples(cassette_image *cassette, int channel, - double time_index, double sample_period, size_t sample_count, size_t sample_spacing, - void *samples, int waveform_flags); -cassette_image::error cassette_put_samples(cassette_image *cassette, int channel, - double time_index, double sample_period, size_t sample_count, size_t sample_spacing, - const void *samples, int waveform_flags); -cassette_image::error cassette_get_sample(cassette_image *cassette, int channel, - double time_index, double sample_period, int32_t *sample); -cassette_image::error cassette_put_sample(cassette_image *cassette, int channel, - double time_index, double sample_period, int32_t sample); - -/* waveform accesses to/from the raw image - these are only used by lib\formats\wavfile.cpp */ -cassette_image::error cassette_read_samples(cassette_image *cassette, int channels, double time_index, - double sample_period, size_t sample_count, uint64_t offset, int waveform_flags); -cassette_image::error cassette_write_samples(cassette_image *cassette, int channels, double time_index, - double sample_period, size_t sample_count, uint64_t offset, int waveform_flags); - -/* modulation support */ -cassette_image::error cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation, - struct CassetteOptions *opts); -cassette_image::error cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index, - const void *data, size_t data_length, const struct CassetteModulation *modulation, - double *time_displacement); -cassette_image::error cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index, - uint8_t filler, size_t filler_length, const struct CassetteModulation *modulation, - double *time_displacement); -cassette_image::error cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index, - uint64_t offset, uint64_t length, const struct CassetteModulation *modulation, - double *time_displacement); -cassette_image::error cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index, - uint8_t data, const struct CassetteModulation *modulation, - double *time_displacement); - -/* debug calls */ -void cassette_dump(cassette_image *image, const char *filename); - -/* legacy code support */ -#define CODE_HEADER ((uint8_t*)-1) -#define CODE_TRAILER ((uint8_t*)-2) -cassette_image::error cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts, - const struct CassetteLegacyWaveFiller *legacy_args); -cassette_image::error cassette_legacy_construct(cassette_image *cassette, - const struct CassetteLegacyWaveFiller *legacy_args); - #endif // MAME_FORMATS_CASSIMG_H diff --git a/src/lib/formats/cbm_tap.cpp b/src/lib/formats/cbm_tap.cpp index 7ef8015c6f9..542c0c3ea87 100644 --- a/src/lib/formats/cbm_tap.cpp +++ b/src/lib/formats/cbm_tap.cpp @@ -339,7 +339,7 @@ static int cbm_tap_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) -static const struct CassetteLegacyWaveFiller cbm_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller cbm_legacy_fill_wave = { cbm_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -350,19 +350,19 @@ static const struct CassetteLegacyWaveFiller cbm_legacy_fill_wave = { }; -static cassette_image::error cbm_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) +static cassette_image::error cbm_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { - return cassette_legacy_identify( cassette, opts, &cbm_legacy_fill_wave ); + return cassette->legacy_identify( opts, &cbm_legacy_fill_wave ); } static cassette_image::error cbm_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &cbm_legacy_fill_wave ); + return cassette->legacy_construct( &cbm_legacy_fill_wave ); } -static const struct CassetteFormat cbm_tap_cassette_format = { +static const cassette_image::Format cbm_tap_cassette_format = { "tap", cbm_cassette_identify, cbm_cassette_load, diff --git a/src/lib/formats/cgen_cas.cpp b/src/lib/formats/cgen_cas.cpp index de47a45375d..8a208044960 100644 --- a/src/lib/formats/cgen_cas.cpp +++ b/src/lib/formats/cgen_cas.cpp @@ -18,10 +18,10 @@ NOTE: There exist multiples type of .cas files for Colour Genie We now support these three types below... ********************************************************************/ +#include "formats/cgen_cas.h" #include <cassert> -#include "formats/cgen_cas.h" #define TAPE_HEADER "Colour Genie - Virtual Tape File" @@ -124,7 +124,7 @@ static int cgenie_cas_to_wav_size(const uint8_t *casdata, int caslen) return cgenie_handle_cas(nullptr, casdata); } -static const struct CassetteLegacyWaveFiller cgenie_cas_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller cgenie_cas_legacy_fill_wave = { cgenie_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -136,19 +136,19 @@ static const struct CassetteLegacyWaveFiller cgenie_cas_legacy_fill_wave = }; -static cassette_image::error cgenie_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error cgenie_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &cgenie_cas_legacy_fill_wave); + return cassette->legacy_identify(opts, &cgenie_cas_legacy_fill_wave); } static cassette_image::error cgenie_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &cgenie_cas_legacy_fill_wave); + return cassette->legacy_construct(&cgenie_cas_legacy_fill_wave); } -static const struct CassetteFormat cgenie_cas_format = +static const cassette_image::Format cgenie_cas_format = { "cas", cgenie_cas_identify, diff --git a/src/lib/formats/coco_cas.cpp b/src/lib/formats/coco_cas.cpp index f3df09266b0..75c68aae2a6 100644 --- a/src/lib/formats/coco_cas.cpp +++ b/src/lib/formats/coco_cas.cpp @@ -47,7 +47,7 @@ static int synccount; -const struct CassetteModulation coco_cas_modulation = +const cassette_image::Modulation coco_cas_modulation = { CASSETTE_MODULATION_SINEWAVE, 600.0, 1200.0, 1500.0, @@ -56,9 +56,9 @@ const struct CassetteModulation coco_cas_modulation = -static cassette_image::error coco_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error coco_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_modulation_identify(cassette, &coco_cas_modulation, opts); + return cassette->modulation_identify(&coco_cas_modulation, opts); } @@ -76,12 +76,12 @@ static bool get_cas_block(cassette_image *cassette, uint64_t *offset, uint8_t *b synccount = 0; p.w.l = 0; - image_size = cassette_image_size(cassette); + image_size = cassette->image_size(); current_offset = *offset; while(current_offset < image_size) { - cassette_image_read(cassette, &p.b.h, current_offset, 1); + cassette->image_read(&p.b.h, current_offset, 1); current_offset++; for (i = 0; i < 8; i++) @@ -196,14 +196,14 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) } #endif - err = cassette_put_sample(cassette, 0, time_index, COCO_WAVESAMPLES_HEADER, 0); + err = cassette->put_sample(0, time_index, COCO_WAVESAMPLES_HEADER, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += COCO_WAVESAMPLES_HEADER; offset = 0; last_blocktype = 0; - image_size = cassette_image_size(cassette); + image_size = cassette->image_size(); /* try to find a block that we can untangle */ while(get_cas_block(cassette, &offset, block, &block_length)) @@ -214,13 +214,13 @@ static cassette_image::error cas_load(cassette_image *cassette, uint8_t silence) if ((last_blocktype == 0) || (last_blocktype == 0xFF) || (block[0] == 0)) { /* silence */ - err = cassette_put_sample(cassette, 0, time_index, silence, 0); + err = cassette->put_sample(0, time_index, silence, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += silence; /* sync data */ - err = cassette_put_modulated_filler(cassette, 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(cassette, 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(cassette, 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(cassette, 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(cassette, 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(cassette, 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; @@ -274,7 +274,7 @@ static cassette_image::error alice32_cas_load(cassette_image *cassette) return cas_load(cassette, ALICE32_WAVESAMPLES_HEADER); } -const struct CassetteFormat coco_cas_format = +const cassette_image::Format coco_cas_format = { "cas", coco_cas_identify, @@ -282,7 +282,7 @@ const struct CassetteFormat coco_cas_format = nullptr }; -const struct CassetteFormat alice32_cas_format = +const cassette_image::Format alice32_cas_format = { "cas,c10,k7", coco_cas_identify, diff --git a/src/lib/formats/csw_cas.cpp b/src/lib/formats/csw_cas.cpp index 9edea5c3ff7..916817fee97 100644 --- a/src/lib/formats/csw_cas.cpp +++ b/src/lib/formats/csw_cas.cpp @@ -22,12 +22,13 @@ Offset Value Type Description */ -#include <cstring> +#include "csw_cas.h" +#include "uef_cas.h" #include <zlib.h> + #include <cassert> -#include "uef_cas.h" -#include "csw_cas.h" +#include <cstring> #define CSW_WAV_FREQUENCY 44100 @@ -262,7 +263,7 @@ cleanup: } -static const struct CassetteLegacyWaveFiller csw_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller csw_legacy_fill_wave = { csw_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -272,23 +273,23 @@ static const struct CassetteLegacyWaveFiller csw_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error csw_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) +static cassette_image::error csw_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { uint8_t header[22]; - cassette_image_read(cassette, header, 0, sizeof(header)); + cassette->image_read(header, 0, sizeof(header)); if (memcmp(&header[0], CSW_HEADER, sizeof(CSW_HEADER) - 1)) { return cassette_image::error::INVALID_IMAGE; } - return cassette_legacy_identify( cassette, opts, &csw_legacy_fill_wave ); + return cassette->legacy_identify( opts, &csw_legacy_fill_wave ); } static cassette_image::error csw_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &csw_legacy_fill_wave ); + return cassette->legacy_construct( &csw_legacy_fill_wave ); } -const struct CassetteFormat csw_cassette_format = { +const cassette_image::Format csw_cassette_format = { "csw", csw_cassette_identify, csw_cassette_load, diff --git a/src/lib/formats/csw_cas.h b/src/lib/formats/csw_cas.h index e6e5a62d764..270d85bcd37 100644 --- a/src/lib/formats/csw_cas.h +++ b/src/lib/formats/csw_cas.h @@ -12,7 +12,7 @@ #include "cassimg.h" -extern const struct CassetteFormat csw_cassette_format; +extern const cassette_image::Format csw_cassette_format; CASSETTE_FORMATLIST_EXTERN(csw_cassette_formats); CASSETTE_FORMATLIST_EXTERN(bbc_cassette_formats); diff --git a/src/lib/formats/fc100_cas.cpp b/src/lib/formats/fc100_cas.cpp index 42b99ad3f0e..56c7b8294db 100644 --- a/src/lib/formats/fc100_cas.cpp +++ b/src/lib/formats/fc100_cas.cpp @@ -10,10 +10,10 @@ it's all a guess. ********************************************************************/ -#include <cassert> - #include "fc100_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -21,7 +21,7 @@ it's all a guess. #define FC100_HEADER_BYTES 16 // image size -static int fc100_image_size; +static int fc100_image_size; // FIXME: global variable prevents multiple instances static int fc100_put_samples(int16_t *buffer, int sample_pos, int count, int level) { @@ -122,7 +122,7 @@ static int fc100_cassette_calculate_size_in_samples(const uint8_t *bytes, int le return fc100_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller fc100_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller fc100_legacy_fill_wave = { fc100_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -133,17 +133,17 @@ static const struct CassetteLegacyWaveFiller fc100_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error fc100_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error fc100_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &fc100_legacy_fill_wave); + return cassette->legacy_identify(opts, &fc100_legacy_fill_wave); } static cassette_image::error fc100_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &fc100_legacy_fill_wave); + return cassette->legacy_construct(&fc100_legacy_fill_wave); } -static const struct CassetteFormat fc100_cassette_image_format = +static const cassette_image::Format fc100_cassette_image_format = { "cas", fc100_cassette_identify, diff --git a/src/lib/formats/fm7_cas.cpp b/src/lib/formats/fm7_cas.cpp index f275866d31b..a0c0151be7b 100644 --- a/src/lib/formats/fm7_cas.cpp +++ b/src/lib/formats/fm7_cas.cpp @@ -4,14 +4,14 @@ * Fujitsu FM-7 series cassette handling */ -#include <cassert> - #include "fm7_cas.h" +#include <cassert> + #define WAVE_HIGH 0x5a9e #define WAVE_LOW -0x5a9e -static int cas_size; +static int cas_size; // FIXME: global variable prevents multiple instances static int fm7_fill_wave(int16_t* buffer, uint8_t high, uint8_t low, int sample_pos) { @@ -76,7 +76,7 @@ static int fm7_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *bytes) return fm7_handle_t77(buffer,bytes); } -static const struct CassetteLegacyWaveFiller fm7_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller fm7_legacy_fill_wave = { fm7_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -87,20 +87,20 @@ static const struct CassetteLegacyWaveFiller fm7_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error fm7_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error fm7_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &fm7_legacy_fill_wave); + return cassette->legacy_identify(opts, &fm7_legacy_fill_wave); } static cassette_image::error fm7_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &fm7_legacy_fill_wave); + return cassette->legacy_construct(&fm7_legacy_fill_wave); } -static const struct CassetteFormat fm7_cassette_format = { +static const cassette_image::Format fm7_cassette_format = { "t77", fm7_cas_identify, fm7_cas_load, diff --git a/src/lib/formats/fmsx_cas.cpp b/src/lib/formats/fmsx_cas.cpp index 3b00b81dc92..7bda85782b5 100644 --- a/src/lib/formats/fmsx_cas.cpp +++ b/src/lib/formats/fmsx_cas.cpp @@ -104,7 +104,7 @@ static int fmsx_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *bytes) } -static const struct CassetteLegacyWaveFiller fmsx_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller fmsx_legacy_fill_wave = { fmsx_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -117,21 +117,21 @@ static const struct CassetteLegacyWaveFiller fmsx_legacy_fill_wave = -static cassette_image::error fmsx_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error fmsx_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &fmsx_legacy_fill_wave); + return cassette->legacy_identify(opts, &fmsx_legacy_fill_wave); } static cassette_image::error fmsx_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &fmsx_legacy_fill_wave); + return cassette->legacy_construct(&fmsx_legacy_fill_wave); } -static const struct CassetteFormat fmsx_cas_format = +static const cassette_image::Format fmsx_cas_format = { "tap,cas", fmsx_cas_identify, diff --git a/src/lib/formats/gtp_cas.cpp b/src/lib/formats/gtp_cas.cpp index 0a5c34d140c..f8ac6917d64 100644 --- a/src/lib/formats/gtp_cas.cpp +++ b/src/lib/formats/gtp_cas.cpp @@ -6,10 +6,10 @@ Miodrag Milanovic */ -#include <cassert> - #include "gtp_cas.h" +#include <cassert> + #define GTP_WAV_FREQUENCY 44100 #define WAVE_LOW -0x5a9e @@ -20,7 +20,7 @@ #define GTP_BLOCK_TURBO 0x01 #define GTP_BLOCK_NAME 0x10 -static int16_t wave_data; +static int16_t wave_data; // FIXME: global variable prevent multiple instances static int16_t len; #define PULSE_WIDTH 30 @@ -164,7 +164,7 @@ static int gtp_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) { -static const struct CassetteLegacyWaveFiller gtp_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller gtp_legacy_fill_wave = { gtp_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -176,19 +176,19 @@ static const struct CassetteLegacyWaveFiller gtp_legacy_fill_wave = { -static cassette_image::error gtp_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, >p_legacy_fill_wave ); +static cassette_image::error gtp_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, >p_legacy_fill_wave ); } static cassette_image::error gtp_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, >p_legacy_fill_wave ); + return cassette->legacy_construct( >p_legacy_fill_wave ); } -static const struct CassetteFormat gtp_cassette_format = { +static const cassette_image::Format gtp_cassette_format = { "gtp", gtp_cassette_identify, gtp_cassette_load, diff --git a/src/lib/formats/h8_cas.cpp b/src/lib/formats/h8_cas.cpp index ec92a94b10f..80ad3e07f5a 100644 --- a/src/lib/formats/h8_cas.cpp +++ b/src/lib/formats/h8_cas.cpp @@ -11,17 +11,17 @@ We output a leader, followed by the contents of the H8T file. ********************************************************************/ -#include <cassert> - #include "h8_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 #define H8_WAV_FREQUENCY 9600 // image size -static int h8_image_size; +static int h8_image_size; // FIXME: global variable prevents multiple instances static int h8_put_samples(int16_t *buffer, int sample_pos, int count, int level) { @@ -115,7 +115,7 @@ static int h8_cassette_calculate_size_in_samples(const uint8_t *bytes, int lengt return h8_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller h8_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller h8_legacy_fill_wave = { h8_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -126,17 +126,17 @@ static const struct CassetteLegacyWaveFiller h8_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error h8_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error h8_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &h8_legacy_fill_wave); + return cassette->legacy_identify(opts, &h8_legacy_fill_wave); } static cassette_image::error h8_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &h8_legacy_fill_wave); + return cassette->legacy_construct(&h8_legacy_fill_wave); } -static const struct CassetteFormat h8_cassette_image_format = +static const cassette_image::Format h8_cassette_image_format = { "h8t", h8_cassette_identify, diff --git a/src/lib/formats/hect_tap.cpp b/src/lib/formats/hect_tap.cpp index 78f1bad2e42..a450b9507b4 100644 --- a/src/lib/formats/hect_tap.cpp +++ b/src/lib/formats/hect_tap.cpp @@ -24,7 +24,7 @@ Updated 3/1/10 : use real value for timing. #define SMPHI 32767 -static int cas_size; +static int cas_size; // FIXME: global variable prevents multiple instances enum @@ -240,7 +240,7 @@ static int hector_tap_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller hector_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller hector_legacy_fill_wave = { hector_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -251,7 +251,7 @@ static const struct CassetteLegacyWaveFiller hector_legacy_fill_wave = 0 /* trailer_samples */ }; -static const struct CassetteLegacyWaveFiller hector_forth_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller hector_forth_legacy_fill_wave = { hector_tap_forth_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -263,30 +263,30 @@ static const struct CassetteLegacyWaveFiller hector_forth_legacy_fill_wave = }; -static cassette_image::error hector_k7_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error hector_k7_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &hector_legacy_fill_wave); + return cassette->legacy_identify(opts, &hector_legacy_fill_wave); } static cassette_image::error hector_k7_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &hector_legacy_fill_wave); + return cassette->legacy_construct(&hector_legacy_fill_wave); } -static cassette_image::error hector_k7forth_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error hector_k7forth_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &hector_forth_legacy_fill_wave); + return cassette->legacy_identify(opts, &hector_forth_legacy_fill_wave); } static cassette_image::error hector_k7forth_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &hector_forth_legacy_fill_wave); + return cassette->legacy_construct(&hector_forth_legacy_fill_wave); } -static const struct CassetteFormat hector_k7_format = +static const cassette_image::Format hector_k7_format = { "k7,cin", hector_k7_identify, @@ -294,7 +294,7 @@ static const struct CassetteFormat hector_k7_format = nullptr }; -static const struct CassetteFormat hector_k7Forth_format = +static const cassette_image::Format hector_k7Forth_format = { "for", hector_k7forth_identify, diff --git a/src/lib/formats/ioprocs.h b/src/lib/formats/ioprocs.h index 5b45b4a1450..1244873f14c 100644 --- a/src/lib/formats/ioprocs.h +++ b/src/lib/formats/ioprocs.h @@ -25,20 +25,20 @@ struct io_procs { - void (*closeproc)(void *file); - int (*seekproc)(void *file, int64_t offset, int whence); - size_t (*readproc)(void *file, void *buffer, size_t length); - size_t (*writeproc)(void *file, const void *buffer, size_t length); - uint64_t (*filesizeproc)(void *file); + void (*closeproc)(void *file) = nullptr; + int (*seekproc)(void *file, int64_t offset, int whence) = nullptr; + size_t (*readproc)(void *file, void *buffer, size_t length) = nullptr; + size_t (*writeproc)(void *file, const void *buffer, size_t length) = nullptr; + uint64_t (*filesizeproc)(void *file) = nullptr; }; struct io_generic { - const struct io_procs *procs; - void *file; - uint8_t filler; + const struct io_procs *procs = nullptr; + void *file = nullptr; + uint8_t filler = 0; }; @@ -48,10 +48,10 @@ struct io_generic ***************************************************************************/ -extern const struct io_procs stdio_ioprocs; -extern const struct io_procs stdio_ioprocs_noclose; -extern const struct io_procs corefile_ioprocs; -extern const struct io_procs corefile_ioprocs_noclose; +extern const io_procs stdio_ioprocs; +extern const io_procs stdio_ioprocs_noclose; +extern const io_procs corefile_ioprocs; +extern const io_procs corefile_ioprocs_noclose; diff --git a/src/lib/formats/kc_cas.cpp b/src/lib/formats/kc_cas.cpp index ee3d392e86f..74397e3f89a 100644 --- a/src/lib/formats/kc_cas.cpp +++ b/src/lib/formats/kc_cas.cpp @@ -13,10 +13,10 @@ ********************************************************************/ -#include <cassert> - #include "kc_cas.h" +#include <cassert> + #define SMPLO -32768 #define SMPHI 32767 #define SILENCE 0 @@ -38,7 +38,7 @@ enum }; // image size -static int kc_image_size; +static int kc_image_size; // FIXME: global variable prevents multiple instances /******************************************************************* Generate one high-low cycle of sample data @@ -249,7 +249,7 @@ static int kc_kcc_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller kc_kcc_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller kc_kcc_legacy_fill_wave = { kc_kcc_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -260,19 +260,19 @@ static const struct CassetteLegacyWaveFiller kc_kcc_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error kc_kcc_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error kc_kcc_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &kc_kcc_legacy_fill_wave); + return cassette->legacy_identify(opts, &kc_kcc_legacy_fill_wave); } static cassette_image::error kc_kcc_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &kc_kcc_legacy_fill_wave); + return cassette->legacy_construct(&kc_kcc_legacy_fill_wave); } -static const struct CassetteFormat kc_kcc_format = +static const cassette_image::Format kc_kcc_format = { "kcc,kcb", kc_kcc_identify, @@ -301,7 +301,7 @@ static int kc_tap_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller kc_tap_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller kc_tap_legacy_fill_wave = { kc_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -312,19 +312,19 @@ static const struct CassetteLegacyWaveFiller kc_tap_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error kc_tap_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error kc_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &kc_tap_legacy_fill_wave); + return cassette->legacy_identify(opts, &kc_tap_legacy_fill_wave); } static cassette_image::error kc_tap_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &kc_tap_legacy_fill_wave); + return cassette->legacy_construct(&kc_tap_legacy_fill_wave); } -static const struct CassetteFormat kc_tap_format = +static const cassette_image::Format kc_tap_format = { "tap,853,854,855,tp2,kcm", kc_tap_identify, @@ -353,7 +353,7 @@ static int kc_sss_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller kc_sss_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller kc_sss_legacy_fill_wave = { kc_sss_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -364,18 +364,18 @@ static const struct CassetteLegacyWaveFiller kc_sss_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error kc_sss_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error kc_sss_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &kc_sss_legacy_fill_wave); + return cassette->legacy_identify(opts, &kc_sss_legacy_fill_wave); } static cassette_image::error kc_sss_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &kc_sss_legacy_fill_wave); + return cassette->legacy_construct(&kc_sss_legacy_fill_wave); } -static const struct CassetteFormat kc_sss_format = +static const cassette_image::Format kc_sss_format = { "sss", kc_sss_identify, diff --git a/src/lib/formats/kim1_cas.cpp b/src/lib/formats/kim1_cas.cpp index b7853ee967e..0ae96280ee3 100644 --- a/src/lib/formats/kim1_cas.cpp +++ b/src/lib/formats/kim1_cas.cpp @@ -1,14 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Wilbert Pol -#include <cassert> - #include "kim1_cas.h" +#include <cassert> + #define SMPLO -32768 #define SMPHI 32767 -static int cas_size; +static int cas_size; // FIXME: global variable prevents multiple instances static inline int kim1_output_signal( int16_t *buffer, int sample_pos, int high ) @@ -159,7 +159,7 @@ static int kim1_kim_to_wav_size(const uint8_t *casdata, int caslen) return kim1_handle_kim( nullptr, casdata ); } -static const struct CassetteLegacyWaveFiller kim1_kim_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller kim1_kim_legacy_fill_wave = { kim1_kim_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -171,19 +171,19 @@ static const struct CassetteLegacyWaveFiller kim1_kim_legacy_fill_wave = }; -static cassette_image::error kim1_kim_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error kim1_kim_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &kim1_kim_legacy_fill_wave); + return cassette->legacy_identify(opts, &kim1_kim_legacy_fill_wave); } static cassette_image::error kim1_kim_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &kim1_kim_legacy_fill_wave); + return cassette->legacy_construct(&kim1_kim_legacy_fill_wave); } -static const struct CassetteFormat kim1_kim_format = +static const cassette_image::Format kim1_kim_format = { "kim,kim1", kim1_kim_identify, diff --git a/src/lib/formats/lviv_lvt.cpp b/src/lib/formats/lviv_lvt.cpp index 3a94114d421..3725c181f3c 100644 --- a/src/lib/formats/lviv_lvt.cpp +++ b/src/lib/formats/lviv_lvt.cpp @@ -1,10 +1,10 @@ // license:BSD-3-Clause // copyright-holders:Krzysztof Strzecha /* .LVT tape images */ -#include <cassert> - #include "lviv_lvt.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -19,9 +19,7 @@ static int16_t *lviv_emit_level(int16_t *p, int count, int level) { - int i; - - for (i=0; i<count; i++) + for (int i=0; i<count; i++) { *(p++) = level; } @@ -47,11 +45,9 @@ static int16_t* lviv_output_bit(int16_t *p, uint8_t b) static int16_t* lviv_output_byte(int16_t *p, uint8_t byte) { - int i; - p = lviv_output_bit (p, 0); - for (i=0; i<8; i++) + for (int i=0; i<8; i++) p = lviv_output_bit(p,(byte>>i) & 0x01); p = lviv_output_bit (p, 1); @@ -78,23 +74,22 @@ static int lviv_cassette_calculate_size_in_samples(const uint8_t *bytes, int len static int lviv_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) { - int i; int16_t * p = buffer; int data_size; - for (i=0; i<LVIV_LVT_HEADER_PILOT_LENGTH; i++) + for (int i=0; i<LVIV_LVT_HEADER_PILOT_LENGTH; i++) p = lviv_output_bit (p, 1); - for (i=0; i<10; i++) + for (int i=0; i<10; i++) p = lviv_output_byte (p, bytes[0x09]); - for (i=0; i<6; i++) + for (int i=0; i<6; i++) p = lviv_output_byte (p, bytes[0x0a+i]); p = lviv_emit_level (p, LVIV_LVT_PAUSE_SAMPLES, WAVEENTRY_HIGH); - for (i=0; i<LVIV_LVT_BLOCK_PILOT_LENGTH; i++) + for (int i=0; i<LVIV_LVT_BLOCK_PILOT_LENGTH; i++) p = lviv_output_bit (p, 1); data_size = length - ( LVIV_LVT_HEADER_PILOT_SAMPLES + @@ -103,7 +98,7 @@ static int lviv_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) LVIV_LVT_BLOCK_PILOT_SAMPLES ); data_size/=660; - for (i=0; i<data_size; i++) + for (int i=0; i<data_size; i++) p = lviv_output_byte (p, bytes[0x10+i]); return p - buffer; @@ -111,7 +106,7 @@ static int lviv_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) -static const struct CassetteLegacyWaveFiller lviv_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller lviv_legacy_fill_wave = { lviv_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -124,21 +119,21 @@ static const struct CassetteLegacyWaveFiller lviv_legacy_fill_wave = -static cassette_image::error lviv_lvt_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error lviv_lvt_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &lviv_legacy_fill_wave); + return cassette->legacy_identify(opts, &lviv_legacy_fill_wave); } static cassette_image::error lviv_lvt_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &lviv_legacy_fill_wave); + return cassette->legacy_construct(&lviv_legacy_fill_wave); } -static const struct CassetteFormat lviv_lvt_image_format = +static const cassette_image::Format lviv_lvt_image_format = { "lvt,lvr,lv0,lv1,lv2,lv3", lviv_lvt_identify, diff --git a/src/lib/formats/mbee_cas.cpp b/src/lib/formats/mbee_cas.cpp index 181bca6aac0..855b4757581 100644 --- a/src/lib/formats/mbee_cas.cpp +++ b/src/lib/formats/mbee_cas.cpp @@ -227,7 +227,7 @@ static int mbee_tap_calculate_size_in_samples(const uint8_t *bytes, int length) return mbee_handle_tap(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller mbee_tap_config = +static const cassette_image::LegacyWaveFiller mbee_tap_config = { mbee_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -238,17 +238,17 @@ static const struct CassetteLegacyWaveFiller mbee_tap_config = 0 /* trailer_samples */ }; -static cassette_image::error mbee_tap_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error mbee_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &mbee_tap_config); + return cassette->legacy_identify(opts, &mbee_tap_config); } static cassette_image::error mbee_tap_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &mbee_tap_config); + return cassette->legacy_construct(&mbee_tap_config); } -static const struct CassetteFormat mbee_tap_image_format = +static const cassette_image::Format mbee_tap_image_format = { "tap", mbee_tap_identify, diff --git a/src/lib/formats/mz_cas.cpp b/src/lib/formats/mz_cas.cpp index e7af23aafb4..0ab4cec8e84 100644 --- a/src/lib/formats/mz_cas.cpp +++ b/src/lib/formats/mz_cas.cpp @@ -1,8 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Nathan Woods +#include "mz_cas.h" + #include <cstring> #include <cassert> -#include "mz_cas.h" #ifndef VERBOSE #define VERBOSE 0 @@ -301,7 +302,7 @@ static int fill_wave(int16_t *buffer, int length, uint8_t *code) -static const struct CassetteLegacyWaveFiller mz700_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller mz700_legacy_fill_wave = { fill_wave, /* fill_wave */ 1, /* chunk_size */ @@ -314,21 +315,21 @@ static const struct CassetteLegacyWaveFiller mz700_legacy_fill_wave = -static cassette_image::error mz700_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error mz700_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &mz700_legacy_fill_wave); + return cassette->legacy_identify(opts, &mz700_legacy_fill_wave); } static cassette_image::error mz700_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &mz700_legacy_fill_wave); + return cassette->legacy_construct(&mz700_legacy_fill_wave); } -static const struct CassetteFormat mz700_cas_format = +static const cassette_image::Format mz700_cas_format = { "m12,mzf,mzt", mz700_cas_identify, diff --git a/src/lib/formats/orao_cas.cpp b/src/lib/formats/orao_cas.cpp index 9a2ac05547e..a9c3f7473d4 100644 --- a/src/lib/formats/orao_cas.cpp +++ b/src/lib/formats/orao_cas.cpp @@ -5,10 +5,10 @@ Tape support for Orao TAP format */ -#include <cassert> - #include "orao_cas.h" +#include <cassert> + #define ORAO_WAV_FREQUENCY 44100 #define WAVE_HIGH -32768 @@ -19,7 +19,7 @@ #define ORAO_HEADER_SIZE 360 -static int16_t wave_data; +static int16_t wave_data; // FIXME: global variables prevent multiple instances static int len; static void orao_output_wave( int16_t **buffer, int length ) { @@ -85,7 +85,7 @@ static int orao_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) { -static const struct CassetteLegacyWaveFiller orao_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller orao_legacy_fill_wave = { orao_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -97,19 +97,19 @@ static const struct CassetteLegacyWaveFiller orao_legacy_fill_wave = { -static cassette_image::error orao_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, &orao_legacy_fill_wave ); +static cassette_image::error orao_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, &orao_legacy_fill_wave ); } static cassette_image::error orao_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &orao_legacy_fill_wave ); + return cassette->legacy_construct( &orao_legacy_fill_wave ); } -static const struct CassetteFormat orao_cassette_format = { +static const cassette_image::Format orao_cassette_format = { "tap", orao_cassette_identify, orao_cassette_load, diff --git a/src/lib/formats/oric_tap.cpp b/src/lib/formats/oric_tap.cpp index dcee2f0bd2d..9dc98239fac 100644 --- a/src/lib/formats/oric_tap.cpp +++ b/src/lib/formats/oric_tap.cpp @@ -1,8 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Kevin Thacker +#include "oric_tap.h" + #include <cassert> -#include "oric_tap.h" #define ORIC_WAV_DEBUG 0 #define LOG(x) do { if (ORIC_WAV_DEBUG) printf x; } while (0) @@ -481,7 +482,7 @@ static int oric_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) -static const struct CassetteLegacyWaveFiller oric_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller oric_legacy_fill_wave = { oric_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -494,21 +495,21 @@ static const struct CassetteLegacyWaveFiller oric_legacy_fill_wave = -static cassette_image::error oric_tap_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error oric_tap_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &oric_legacy_fill_wave); + return cassette->legacy_identify(opts, &oric_legacy_fill_wave); } static cassette_image::error oric_tap_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &oric_legacy_fill_wave); + return cassette->legacy_construct(&oric_legacy_fill_wave); } -static const struct CassetteFormat oric_tap_format = +static const cassette_image::Format oric_tap_format = { "tap", oric_tap_identify, diff --git a/src/lib/formats/p2000t_cas.cpp b/src/lib/formats/p2000t_cas.cpp index 6a858e486c4..7bc0c6b21a9 100644 --- a/src/lib/formats/p2000t_cas.cpp +++ b/src/lib/formats/p2000t_cas.cpp @@ -1,12 +1,12 @@ // license:BSD-3-Clause // copyright-holders:Curt Coder -#include <cassert> - -#include "cassimg.h" #include "p2000t_cas.h" + +#include <cassert> #include <ostream> + // This code will reproduce the timing of a P2000 mini cassette tape. constexpr double P2000_CLOCK_PERIOD = 0.000084; constexpr double P2000_BOT_GAP = 1; @@ -156,7 +156,7 @@ std::ostream &operator<<(std::ostream &os, P2000T_Header const &hdr) << std::string(hdr.ext, 3) << " " << hdr.file_length; } -static cassette_image::error p2000t_cas_identify(cassette_image *cass, struct CassetteOptions *opts) +static cassette_image::error p2000t_cas_identify(cassette_image *cass, cassette_image::Options *opts) { opts->bits_per_sample = 32; opts->channels = 1; @@ -215,10 +215,10 @@ cassette_image::error p2000t_put_bit(cassette_image *cass, double *time_index, b { const int channel = 0; cassette_image::error err = cassette_image::error::SUCCESS; - CHR(cassette_put_sample(cass, channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_HIGH : P2000_LOW)); + CHR(cass->put_sample(channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_HIGH : P2000_LOW)); *time_index += P2000_CLOCK_PERIOD; - CHR(cassette_put_sample(cass, channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_LOW : P2000_HIGH)); + CHR(cass->put_sample(channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_LOW : P2000_HIGH)); *time_index += P2000_CLOCK_PERIOD; return err; } @@ -251,7 +251,7 @@ cassette_image::error p2000t_silence(cassette_image *cassette, double *time_index, double time) { - auto err = cassette_put_sample(cassette, 0, *time_index, time, 0); + auto err = cassette->put_sample(0, *time_index, time, 0); *time_index += time; return err; } @@ -259,7 +259,7 @@ double time) static cassette_image::error p2000t_cas_load(cassette_image *cassette) { cassette_image::error err = cassette_image::error::SUCCESS; - uint64_t image_size = cassette_image_size(cassette); + uint64_t image_size = cassette->image_size(); constexpr int CAS_BLOCK = 1280; /* @@ -290,7 +290,7 @@ static cassette_image::error p2000t_cas_load(cassette_image *cassette) for (int i = 0; i < blocks; i++) { uint16_t crc = 0, unused = 0; - cassette_image_read(cassette, &block, CAS_BLOCK * i, CAS_BLOCK); + cassette->image_read(&block, CAS_BLOCK * i, CAS_BLOCK); // Insert sync header.. 0xAA, 0x00, 0x00, 0xAA CHR(p2000t_silence(cassette, &time_idx, P2000_BOB_GAP)); @@ -312,7 +312,7 @@ static cassette_image::error p2000t_cas_load(cassette_image *cassette) return p2000t_silence(cassette, &time_idx, P2000_EOT_GAP); } -static const struct CassetteFormat p2000t_cas = { +static const cassette_image::Format p2000t_cas = { "cas", p2000t_cas_identify, p2000t_cas_load, nullptr /* no save */ }; diff --git a/src/lib/formats/p6001_cas.cpp b/src/lib/formats/p6001_cas.cpp index 3319e377b3d..425a4e8dd2c 100644 --- a/src/lib/formats/p6001_cas.cpp +++ b/src/lib/formats/p6001_cas.cpp @@ -4,22 +4,21 @@ * NEC PC-6001 cassette format handling */ -#include <cassert> - #include "p6001_cas.h" +#include <cassert> + #define WAVE_HIGH 0x5a9e #define WAVE_LOW -0x5a9e -static int cas_size; +static int cas_size; // FIXME: global variable prevents multiple instances static int pc6001_fill_wave(int16_t* buffer, uint8_t data, int sample_pos) { - int x; int sample_count = 0; // one byte = 8 samples - for(x=0;x<8;x++) + for(int x=0;x<8;x++) { if(buffer) buffer[sample_pos+x] = ((data >> (7-x)) & 1) ? WAVE_HIGH : WAVE_LOW; @@ -61,7 +60,7 @@ static int pc6001_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *byte return pc6001_handle_cas(buffer,bytes); } -static const struct CassetteLegacyWaveFiller pc6001_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller pc6001_legacy_fill_wave = { pc6001_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -72,20 +71,20 @@ static const struct CassetteLegacyWaveFiller pc6001_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error pc6001_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error pc6001_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &pc6001_legacy_fill_wave); + return cassette->legacy_identify(opts, &pc6001_legacy_fill_wave); } static cassette_image::error pc6001_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &pc6001_legacy_fill_wave); + return cassette->legacy_construct(&pc6001_legacy_fill_wave); } -static const struct CassetteFormat pc6001_cassette_format = { +static const cassette_image::Format pc6001_cassette_format = { "cas", pc6001_cas_identify, pc6001_cas_load, diff --git a/src/lib/formats/phc25_cas.cpp b/src/lib/formats/phc25_cas.cpp index 197c3db50ae..ee8864adbb5 100644 --- a/src/lib/formats/phc25_cas.cpp +++ b/src/lib/formats/phc25_cas.cpp @@ -29,10 +29,10 @@ enough to make it work. ********************************************************************/ -#include <cassert> - #include "phc25_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -40,7 +40,7 @@ enough to make it work. #define PHC25_HEADER_BYTES 16 // image size -static int phc25_image_size; +static int phc25_image_size; // FIXME: global variable prevents multiple instances static int phc25_put_samples(int16_t *buffer, int sample_pos, int count, int level) { @@ -147,7 +147,7 @@ static int phc25_cassette_calculate_size_in_samples(const uint8_t *bytes, int le return phc25_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller phc25_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller phc25_legacy_fill_wave = { phc25_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -158,17 +158,17 @@ static const struct CassetteLegacyWaveFiller phc25_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error phc25_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error phc25_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &phc25_legacy_fill_wave); + return cassette->legacy_identify(opts, &phc25_legacy_fill_wave); } static cassette_image::error phc25_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &phc25_legacy_fill_wave); + return cassette->legacy_construct(&phc25_legacy_fill_wave); } -static const struct CassetteFormat phc25_cassette_image_format = +static const cassette_image::Format phc25_cassette_image_format = { "phc", phc25_cassette_identify, diff --git a/src/lib/formats/pmd_cas.cpp b/src/lib/formats/pmd_cas.cpp index a046580bc17..20e4a64bbe1 100644 --- a/src/lib/formats/pmd_cas.cpp +++ b/src/lib/formats/pmd_cas.cpp @@ -10,10 +10,10 @@ ********************************************************************/ -#include <cassert> - #include "pmd_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -26,7 +26,7 @@ #define PMD85_BITS_PER_BYTE 11 // image size -static int pmd85_image_size; +static int pmd85_image_size; // FIXME: global variable prevents multiple instances static int pmd85_emit_level(int16_t *buffer, int sample_pos, int count, int level) { @@ -184,7 +184,7 @@ static int pmd85_cassette_calculate_size_in_samples(const uint8_t *bytes, int le return pmd85_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller pmd85_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller pmd85_legacy_fill_wave = { pmd85_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -195,17 +195,17 @@ static const struct CassetteLegacyWaveFiller pmd85_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error pmd85_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error pmd85_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &pmd85_legacy_fill_wave); + return cassette->legacy_identify(opts, &pmd85_legacy_fill_wave); } static cassette_image::error pmd85_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &pmd85_legacy_fill_wave); + return cassette->legacy_construct(&pmd85_legacy_fill_wave); } -static const struct CassetteFormat pmd85_cassette_image_format = +static const cassette_image::Format pmd85_cassette_image_format = { "pmd,tap,ptp", pmd85_cassette_identify, diff --git a/src/lib/formats/primoptp.cpp b/src/lib/formats/primoptp.cpp index 906a08239a6..6e04f01bc62 100644 --- a/src/lib/formats/primoptp.cpp +++ b/src/lib/formats/primoptp.cpp @@ -2,11 +2,10 @@ // copyright-holders:Krzysztof Strzecha /* .PTP Microkey Primo tape images */ +#include "primoptp.h" #include <cassert> -#include "primoptp.h" - #define PRIMO_WAVEENTRY_LOW -32768 #define PRIMO_WAVEENTRY_HIGH 32767 @@ -30,9 +29,7 @@ static uint32_t primo_tape_image_length; static int16_t *primo_emit_level(int16_t *p, int count, int level) { - int i; - - for (i=0; i<count; i++) *(p++) = level; + for (int i=0; i<count; i++) *(p++) = level; return p; } @@ -215,7 +212,7 @@ static int primo_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) return p - buffer; } -static const struct CassetteLegacyWaveFiller primo_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller primo_legacy_fill_wave = { primo_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -226,17 +223,17 @@ static const struct CassetteLegacyWaveFiller primo_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error primo_ptp_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error primo_ptp_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &primo_legacy_fill_wave); + return cassette->legacy_identify(opts, &primo_legacy_fill_wave); } static cassette_image::error primo_ptp_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &primo_legacy_fill_wave); + return cassette->legacy_construct(&primo_legacy_fill_wave); } -static const struct CassetteFormat primo_ptp_image_format = +static const cassette_image::Format primo_ptp_image_format = { "ptp", primo_ptp_identify, diff --git a/src/lib/formats/rk_cas.cpp b/src/lib/formats/rk_cas.cpp index b522fea2f3b..a31c47592db 100644 --- a/src/lib/formats/rk_cas.cpp +++ b/src/lib/formats/rk_cas.cpp @@ -5,10 +5,10 @@ Tape support for RK format */ -#include <cassert> - #include "rk_cas.h" +#include <cassert> + #define RK_WAV_FREQUENCY 44000 #define WAVE_HIGH 32767 @@ -20,13 +20,12 @@ #define RK_SIZE_22 22 #define RK_SIZE_60 60 -static int data_size; +static int data_size; // FIXME: global variable prevents multiple instances static int16_t *rk_emit_level(int16_t *p, int count, int level) { - int i; - for (i=0; i<count; i++) + for (int i=0; i<count; i++) { *(p++) = level; } @@ -141,7 +140,7 @@ static int gam_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) { return p - buffer; } -static const struct CassetteLegacyWaveFiller rk20_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller rk20_legacy_fill_wave = { rk20_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -151,15 +150,15 @@ static const struct CassetteLegacyWaveFiller rk20_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error rk20_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, &rk20_legacy_fill_wave ); +static cassette_image::error rk20_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, &rk20_legacy_fill_wave ); } static cassette_image::error rk20_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &rk20_legacy_fill_wave ); + return cassette->legacy_construct( &rk20_legacy_fill_wave ); } -static const struct CassetteLegacyWaveFiller rk22_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller rk22_legacy_fill_wave = { rk22_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -169,15 +168,15 @@ static const struct CassetteLegacyWaveFiller rk22_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error rk22_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, &rk22_legacy_fill_wave ); +static cassette_image::error rk22_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, &rk22_legacy_fill_wave ); } static cassette_image::error rk22_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &rk22_legacy_fill_wave ); + return cassette->legacy_construct( &rk22_legacy_fill_wave ); } -static const struct CassetteLegacyWaveFiller gam_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller gam_legacy_fill_wave = { gam_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -187,15 +186,15 @@ static const struct CassetteLegacyWaveFiller gam_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error gam_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, &gam_legacy_fill_wave ); +static cassette_image::error gam_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, &gam_legacy_fill_wave ); } static cassette_image::error gam_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &gam_legacy_fill_wave ); + return cassette->legacy_construct( &gam_legacy_fill_wave ); } -static const struct CassetteLegacyWaveFiller rk60_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller rk60_legacy_fill_wave = { rk60_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -205,71 +204,71 @@ static const struct CassetteLegacyWaveFiller rk60_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error rk60_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { - return cassette_legacy_identify( cassette, opts, &rk60_legacy_fill_wave ); +static cassette_image::error rk60_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { + return cassette->legacy_identify( opts, &rk60_legacy_fill_wave ); } static cassette_image::error rk60_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &rk60_legacy_fill_wave ); + return cassette->legacy_construct( &rk60_legacy_fill_wave ); } -static const struct CassetteFormat rku_cassette_format = { +static const cassette_image::Format rku_cassette_format = { "rku", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat rk8_cassette_format = { +static const cassette_image::Format rk8_cassette_format = { "rk8", rk60_cassette_identify, rk60_cassette_load, nullptr }; -static const struct CassetteFormat rks_cassette_format = { +static const cassette_image::Format rks_cassette_format = { "rks", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat rko_cassette_format = { +static const cassette_image::Format rko_cassette_format = { "rko", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat rkr_cassette_format = { +static const cassette_image::Format rkr_cassette_format = { "rk,rkr", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat rka_cassette_format = { +static const cassette_image::Format rka_cassette_format = { "rka", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat rkm_cassette_format = { +static const cassette_image::Format rkm_cassette_format = { "rkm", rk22_cassette_identify, rk22_cassette_load, nullptr }; -static const struct CassetteFormat rkp_cassette_format = { +static const cassette_image::Format rkp_cassette_format = { "rkp", rk20_cassette_identify, rk20_cassette_load, nullptr }; -static const struct CassetteFormat gam_cassette_format = { +static const cassette_image::Format gam_cassette_format = { "gam,g16,pki", gam_cassette_identify, gam_cassette_load, diff --git a/src/lib/formats/sc3000_bit.cpp b/src/lib/formats/sc3000_bit.cpp index 6e3600b7aeb..636d93543c6 100644 --- a/src/lib/formats/sc3000_bit.cpp +++ b/src/lib/formats/sc3000_bit.cpp @@ -7,10 +7,10 @@ Cassette code for Sega SC-3000 *.bit files *********************************************************************/ +#include "sc3000_bit.h" #include <cassert> -#include "sc3000_bit.h" /*************************************************************************** PARAMETERS @@ -26,7 +26,7 @@ CassetteModulation sc3000_bit_modulation -------------------------------------------------*/ -static const struct CassetteModulation sc3000_bit_modulation = +static const cassette_image::Modulation sc3000_bit_modulation = { CASSETTE_MODULATION_SINEWAVE, 1200.0 - 300, 1200.0, 1200.0 + 300, @@ -37,9 +37,9 @@ static const struct CassetteModulation sc3000_bit_modulation = sc3000_bit_identify - identify cassette -------------------------------------------------*/ -static cassette_image::error sc3000_bit_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error sc3000_bit_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_modulation_identify( cassette, &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, struc #define MODULATE(_value) \ for (int i = 0; i < (_value ? 2 : 1); i++) { \ - err = cassette_put_modulated_data_bit(cassette, 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;\ } @@ -56,7 +56,7 @@ static cassette_image::error sc3000_bit_identify(cassette_image *cassette, struc static cassette_image::error sc3000_bit_load(cassette_image *cassette) { cassette_image::error err; - uint64_t image_size = cassette_image_size(cassette); + uint64_t image_size = cassette->image_size(); uint64_t image_pos = 0; double time_index = 0.0; double time_displacement; @@ -64,7 +64,7 @@ static cassette_image::error sc3000_bit_load(cassette_image *cassette) while (image_pos < image_size) { - cassette_image_read(cassette, &data, image_pos, 1); + cassette->image_read(&data, image_pos, 1); switch (data) { @@ -77,7 +77,7 @@ static cassette_image::error sc3000_bit_load(cassette_image *cassette) break; case ' ': - err = cassette_put_sample( cassette, 0, time_index, 1/1200.0, 0); + err = cassette->put_sample(0, time_index, 1/1200.0, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += 1/1200.0; break; @@ -93,7 +93,7 @@ static cassette_image::error sc3000_bit_load(cassette_image *cassette) CassetteFormat sc3000_bit_cassette_format -------------------------------------------------*/ -const struct CassetteFormat sc3000_bit_format = +const cassette_image::Format sc3000_bit_format = { "bit", sc3000_bit_identify, diff --git a/src/lib/formats/sol_cas.cpp b/src/lib/formats/sol_cas.cpp index 4672ff95080..a48a5b918fd 100644 --- a/src/lib/formats/sol_cas.cpp +++ b/src/lib/formats/sol_cas.cpp @@ -33,10 +33,10 @@ SVT - The full explanation may be found on the Solace web site, escaped characters ********************************************************************/ +#include "sol_cas.h" #include <cassert> -#include "sol_cas.h" #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -44,7 +44,7 @@ SVT - The full explanation may be found on the Solace web site, #define SOL20_WAV_FREQUENCY 4800 // image size -static uint32_t sol20_image_size; +static uint32_t sol20_image_size; // FIXME: global variable prevent multiple instances static bool level; static uint8_t sol20_cksm_byte; static uint32_t sol20_byte_num; @@ -356,7 +356,7 @@ static int sol20_cassette_calculate_size_in_samples(const uint8_t *bytes, int le return sol20_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller sol20_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller sol20_legacy_fill_wave = { sol20_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -367,17 +367,17 @@ static const struct CassetteLegacyWaveFiller sol20_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error sol20_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error sol20_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &sol20_legacy_fill_wave); + return cassette->legacy_identify(opts, &sol20_legacy_fill_wave); } static cassette_image::error sol20_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &sol20_legacy_fill_wave); + return cassette->legacy_construct(&sol20_legacy_fill_wave); } -static const struct CassetteFormat sol20_cassette_image_format = +static const cassette_image::Format sol20_cassette_image_format = { "svt", sol20_cassette_identify, diff --git a/src/lib/formats/sorc_cas.cpp b/src/lib/formats/sorc_cas.cpp index 50585d444c7..21b3f8b5c2c 100644 --- a/src/lib/formats/sorc_cas.cpp +++ b/src/lib/formats/sorc_cas.cpp @@ -24,10 +24,10 @@ header and leader bytes. ********************************************************************/ +#include "sorc_cas.h" #include <cassert> -#include "sorc_cas.h" #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -124,7 +124,7 @@ static int sorcerer_cassette_calculate_size_in_samples(const uint8_t *bytes, int return sorcerer_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller sorcerer_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller sorcerer_legacy_fill_wave = { sorcerer_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -135,17 +135,17 @@ static const struct CassetteLegacyWaveFiller sorcerer_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error sorcerer_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error sorcerer_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &sorcerer_legacy_fill_wave); + return cassette->legacy_identify(opts, &sorcerer_legacy_fill_wave); } static cassette_image::error sorcerer_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &sorcerer_legacy_fill_wave); + return cassette->legacy_construct(&sorcerer_legacy_fill_wave); } -static const struct CassetteFormat sorcerer_cassette_image_format = +static const cassette_image::Format sorcerer_cassette_image_format = { "tape", sorcerer_cassette_identify, diff --git a/src/lib/formats/sord_cas.cpp b/src/lib/formats/sord_cas.cpp index 145cd3c3221..ba4ad1faa24 100644 --- a/src/lib/formats/sord_cas.cpp +++ b/src/lib/formats/sord_cas.cpp @@ -7,10 +7,10 @@ Format code for Sord M5 cassette files **************************************************************************/ +#include "sord_cas.h" #include <cstring> #include <cassert> -#include "sord_cas.h" #define SORDM5_WAVESAMPLES_HEADER 1 #define SORDM5_WAVESAMPLES_TRAILER 1 @@ -18,7 +18,7 @@ static const uint8_t SORDM5_CAS_HEADER[6] = { 'S', 'O', 'R', 'D', 'M', '5'}; -static const struct CassetteModulation sordm5_cas_modulation = +static const cassette_image::Modulation sordm5_cas_modulation = { CASSETTE_MODULATION_SINEWAVE, 1575.0 - 300, 1575.0, 1575.0 + 300, @@ -28,13 +28,13 @@ static const struct CassetteModulation sordm5_cas_modulation = static uint8_t cassette_image_read_uint8( cassette_image *cassette, uint64_t offset) { uint8_t data; - cassette_image_read( cassette, &data, offset, 1); + cassette->image_read(&data, offset, 1); return data; } -static cassette_image::error sordm5_tap_identify( cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error sordm5_tap_identify( cassette_image *cassette, cassette_image::Options *opts) { - return cassette_modulation_identify( cassette, &sordm5_cas_modulation, opts); + return cassette->modulation_identify(&sordm5_cas_modulation, opts); } static cassette_image::error sordm5_tap_load( cassette_image *cassette) @@ -49,44 +49,44 @@ static cassette_image::error sordm5_tap_load( cassette_image *cassette) uint32_t block_size, i, j; size_t filler_length; // init - image_size = cassette_image_size(cassette); + image_size = cassette->image_size(); image_pos = 0; // read/check header if (image_size < 16) return cassette_image::error::INVALID_IMAGE; - cassette_image_read( cassette, &header, image_pos, 16); + cassette->image_read(&header, image_pos, 16); image_pos += 16; if (memcmp( header, SORDM5_CAS_HEADER, sizeof(SORDM5_CAS_HEADER)) != 0) return cassette_image::error::INVALID_IMAGE; // add silence (header) - err = cassette_put_sample( cassette, 0, time_index, SORDM5_WAVESAMPLES_HEADER, 0); + err = cassette->put_sample(0, time_index, SORDM5_WAVESAMPLES_HEADER, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += SORDM5_WAVESAMPLES_HEADER; // process blocks while (image_pos < image_size) { // read block type - block_type = cassette_image_read_uint8( cassette, image_pos + 0); + block_type = cassette_image_read_uint8(cassette, image_pos + 0); if ((block_type != 'H') && (block_type != 'D')) return cassette_image::error::INVALID_IMAGE; // read block size - block_size = cassette_image_read_uint8( cassette, image_pos + 1); + block_size = cassette_image_read_uint8(cassette, image_pos + 1); if (block_size == 0) block_size = 0x100; block_size += 3; // add silence (header block) if (block_type == 'H') { - err = cassette_put_sample( cassette, 0, time_index, SORDM5_WAVESAMPLES_BLOCK, 0); + err = cassette->put_sample(0, time_index, SORDM5_WAVESAMPLES_BLOCK, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += SORDM5_WAVESAMPLES_BLOCK; } // add sync if (block_type == 'H') filler_length = 2.4 * (3150 / 8); else filler_length = 0.15 * (3150 / 8); - err = cassette_put_modulated_filler(cassette, 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 for (i=0;i<block_size;i++) { // read byte - byte = cassette_image_read_uint8( cassette, image_pos + i); + byte = cassette_image_read_uint8(cassette, image_pos + i); // calc/check checksum #if 0 if (i == block_size) @@ -108,27 +108,27 @@ static cassette_image::error sordm5_tap_load( cassette_image *cassette) bit = (byte >> (j-2)) & 1; } // add bit - err = cassette_put_modulated_data_bit( cassette, 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( cassette, 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 image_pos += block_size; } // add silence (trailer) - err = cassette_put_sample( cassette, 0, time_index, SORDM5_WAVESAMPLES_TRAILER, 0); + err = cassette->put_sample(0, time_index, SORDM5_WAVESAMPLES_TRAILER, 0); if (err != cassette_image::error::SUCCESS) return err; time_index += SORDM5_WAVESAMPLES_TRAILER; // return cassette_image::error::SUCCESS; } -static const struct CassetteFormat sordm5_cas_format = +static const cassette_image::Format sordm5_cas_format = { "cas", sordm5_tap_identify, diff --git a/src/lib/formats/spc1000_cas.cpp b/src/lib/formats/spc1000_cas.cpp index 2e48980da3d..e5d4bc1d0c3 100644 --- a/src/lib/formats/spc1000_cas.cpp +++ b/src/lib/formats/spc1000_cas.cpp @@ -20,10 +20,10 @@ STA: This format has not been investigated yet, but is assumed to IPL: This seems a quickload format containing RAM dump, not a real tape ********************************************************************/ +#include "spc1000_cas.h" #include <cassert> -#include "spc1000_cas.h" #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -31,7 +31,7 @@ IPL: This seems a quickload format containing RAM dump, not a real tape #define SPC1000_WAV_FREQUENCY 17000 // image size -static int spc1000_image_size; +static int spc1000_image_size; // FIXME: global variable prevents multiple instances static int spc1000_put_samples(int16_t *buffer, int sample_pos, int count, int level) { @@ -125,7 +125,7 @@ static int spc1000_cas_calculate_size_in_samples(const uint8_t *bytes, int lengt // TAP -static const struct CassetteLegacyWaveFiller spc1000_tap_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller spc1000_tap_legacy_fill_wave = { spc1000_tap_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -136,17 +136,17 @@ static const struct CassetteLegacyWaveFiller spc1000_tap_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error spc1000_tap_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error spc1000_tap_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &spc1000_tap_legacy_fill_wave); + return cassette->legacy_identify(opts, &spc1000_tap_legacy_fill_wave); } static cassette_image::error spc1000_tap_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &spc1000_tap_legacy_fill_wave); + return cassette->legacy_construct(&spc1000_tap_legacy_fill_wave); } -static const struct CassetteFormat spc1000_tap_cassette_image_format = +static const cassette_image::Format spc1000_tap_cassette_image_format = { "tap", spc1000_tap_cassette_identify, @@ -156,7 +156,7 @@ static const struct CassetteFormat spc1000_tap_cassette_image_format = // CAS -static const struct CassetteLegacyWaveFiller spc1000_cas_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller spc1000_cas_legacy_fill_wave = { spc1000_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -167,17 +167,17 @@ static const struct CassetteLegacyWaveFiller spc1000_cas_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error spc1000_cas_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error spc1000_cas_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &spc1000_cas_legacy_fill_wave); + return cassette->legacy_identify(opts, &spc1000_cas_legacy_fill_wave); } static cassette_image::error spc1000_cas_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &spc1000_cas_legacy_fill_wave); + return cassette->legacy_construct(&spc1000_cas_legacy_fill_wave); } -static const struct CassetteFormat spc1000_cas_cassette_image_format = +static const cassette_image::Format spc1000_cas_cassette_image_format = { "cas", spc1000_cas_cassette_identify, diff --git a/src/lib/formats/svi_cas.cpp b/src/lib/formats/svi_cas.cpp index fcb2142c4e3..dfd695dd5ec 100644 --- a/src/lib/formats/svi_cas.cpp +++ b/src/lib/formats/svi_cas.cpp @@ -1,9 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Sean Young -#include <cassert> - #include "svi_cas.h" +#include <cassert> + #define CAS_PERIOD_0 (37) #define CAS_PERIOD_1 (18) #define CAS_HEADER_PERIODS (1600) @@ -19,7 +19,7 @@ static const uint8_t CasHeader[17] = #define SMPLO -32768 #define SMPHI 32767 -static int cas_size; +static int cas_size; // FIXME: global variable prevents multiple instances /******************************************************************* Generate samples for the tape image @@ -171,7 +171,7 @@ static int svi_cas_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller svi_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller svi_legacy_fill_wave = { svi_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -184,21 +184,21 @@ static const struct CassetteLegacyWaveFiller svi_legacy_fill_wave = -static cassette_image::error svi_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error svi_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &svi_legacy_fill_wave); + return cassette->legacy_identify(opts, &svi_legacy_fill_wave); } static cassette_image::error svi_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &svi_legacy_fill_wave); + return cassette->legacy_construct(&svi_legacy_fill_wave); } -static const struct CassetteFormat svi_cas_format = +static const cassette_image::Format svi_cas_format = { "cas", svi_cas_identify, diff --git a/src/lib/formats/thom_cas.cpp b/src/lib/formats/thom_cas.cpp index a00c2c3234b..5ca6e6cde95 100644 --- a/src/lib/formats/thom_cas.cpp +++ b/src/lib/formats/thom_cas.cpp @@ -8,12 +8,11 @@ **********************************************************************/ -#include <cmath> -#include <cassert> - -#include "pool.h" -#include "cassimg.h" #include "thom_cas.h" +#include "pool.h" + +#include <cassert> +#include <cmath> /***************************** configuration **************************/ @@ -86,7 +85,7 @@ static uint8_t* to7_k7_bits; -static const struct CassetteModulation to7_k7_modulation = +static const cassette_image::Modulation to7_k7_modulation = { CASSETTE_MODULATION_SQUAREWAVE, 4000.0, 4500.0, 5000.0, @@ -95,9 +94,9 @@ static const struct CassetteModulation to7_k7_modulation = -static cassette_image::error to7_k7_identify ( cassette_image *cass, struct CassetteOptions *opts ) +static cassette_image::error to7_k7_identify ( cassette_image *cass, cassette_image::Options *opts ) { - cassette_image::error e = cassette_modulation_identify( cass, &to7_k7_modulation, opts ); + cassette_image::error e = cass->modulation_identify( &to7_k7_modulation, opts ); return e; } @@ -109,7 +108,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) static const int8_t square_wave[] = { -128, 127 }; double time = 0.; #endif - size_t size = cassette_image_size( cass ), pos = 0; + size_t size = cass->image_size( ), pos = 0; int i, sz, sz2, bitmax = 1024, invalid = 0; uint8_t in, typ, block[264]; @@ -133,7 +132,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) do \ { \ cassette_image::error err; \ - err = cassette_put_samples( cass, 0, time, (PERIOD), 2, 1, \ + err = cass->put_samples( 0, time, (PERIOD), 2, 1, \ square_wave, CASSETTE_WAVEFORM_8BIT ); \ if ( err != cassette_image::error::SUCCESS ) \ return err; \ @@ -202,7 +201,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) } while (0) /* check format */ - cassette_image_read( cass, block, 0, 64 ); + cass->image_read( block, 0, 64 ); for ( i = 3; ; i++ ) { if ( ( i >= size ) || ( i >= 64 ) ) @@ -227,7 +226,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* skip to first 0xff filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); if ( in == 0xff ) break; } @@ -241,7 +240,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* skip 0xff filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); /* actually, we are bit laxist and treat as 0xff bytes with at least 5 bits out of 8 set to 1 */ @@ -257,7 +256,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) pos -= sz; break; } - cassette_image_read( cass, block, pos, 4 ); + cass->image_read( block, pos, 4 ); typ = block[2]; sz2 = block[3]+1; if ( block[0] != 0x01 || block[1] != 0x3c || ( typ != 0x00 && typ != 0x01 && typ != 0xff ) ) @@ -268,7 +267,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) pos += 4; /* get block */ - cassette_image_read( cass, block+4, pos, sz2 ); + cass->image_read( block+4, pos, sz2 ); pos += sz2; /* 1-filler and 0xff-filler */ @@ -323,17 +322,17 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* put block */ for (; pos < size; pos++ ) { - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); for ( sz = 0; pos < size && in == 0xff; sz++ ) { pos++; - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); } if ( invalid < 10 && sz > 4 && in == 0x01 && pos + 4 <= size ) { uint8_t in1,in2; - cassette_image_read( cass, &in1, pos+1, 1 ); - cassette_image_read( cass, &in2, pos+2, 1 ); + cass->image_read( &in1, pos+1, 1 ); + cass->image_read( &in2, pos+2, 1 ); if ( (in1 == 0x3c) && ((in2 == 0x00) || (in2 == 0x01) ) ) { /* seems we have a regular block hidden in raw data => rebounce */ @@ -365,7 +364,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) -static const struct CassetteFormat to7_k7 = +static const cassette_image::Format to7_k7 = { "k7", to7_k7_identify, to7_k7_load, nullptr /* no save */ }; @@ -375,9 +374,9 @@ static const struct CassetteFormat to7_k7 = static cassette_image::error to7_wav_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { - cassette_image::error e = wavfile_format.identify( cass, opts ); + cassette_image::error e = cassette_image::wavfile_format.identify( cass, opts ); return e; } @@ -385,9 +384,7 @@ static cassette_image::error to7_wav_identify ( cassette_image *cass, static cassette_image::error to7_wav_load ( cassette_image *cass ) { - cassette_image::error e = wavfile_format.load( cass ); - struct CassetteInfo info; - double len; + cassette_image::error e = cassette_image::wavfile_format.load( cass ); if ( to7_k7_bits ) { @@ -398,9 +395,9 @@ static cassette_image::error to7_wav_load ( cassette_image *cass ) if ( e != cassette_image::error::SUCCESS ) return e; - cassette_get_info( cass, &info ); + cassette_image::Info info = cass->get_info( ); - len = (double) info.sample_count / info.sample_frequency; + double len = (double) info.sample_count / info.sample_frequency; PRINT (( "to7_wav_load: loading cassette, length %imn %is, %i Hz, %i bps, %i bits\n", (int) len / 60, (int) len % 60, @@ -412,17 +409,17 @@ static cassette_image::error to7_wav_load ( cassette_image *cass ) -static cassette_image::error to7_wav_save ( cassette_image *cass, const struct CassetteInfo *info ) +static cassette_image::error to7_wav_save ( cassette_image *cass, const cassette_image::Info *info ) { int len = info->sample_count / info->sample_frequency; PRINT (( "to7_wav_save: saving cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info->sample_frequency, info->bits_per_sample )); - return wavfile_format.save( cass, info ); + return cassette_image::wavfile_format.save( cass, info ); } /* overloaded wav: dump info */ -static const struct CassetteFormat to7_wav = +static const cassette_image::Format to7_wav = { "wav", to7_wav_identify, to7_wav_load, to7_wav_save }; @@ -432,7 +429,7 @@ static const struct CassetteFormat to7_wav = static cassette_image::error mo5_k5_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { opts -> bits_per_sample = 8; opts -> channels = 1; @@ -464,7 +461,7 @@ static cassette_image::error mo5_k5_identify ( cassette_image *cass, static cassette_image::error mo5_k5_load( cassette_image *cass ) { - size_t size = cassette_image_size( cass ), pos = 0; + size_t size = cass->image_size( ), pos = 0; int i, sz, sz2, hbit = 0; uint8_t in, in2, in3, typ, block[264], sum; int invalid = 0, hbitsize = 0, dcmoto = 0; @@ -476,7 +473,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) #define K5_PUT_HBIT \ do \ { \ - cassette_put_sample ( cass, 0, hbitsize * MO5_HBIT_LENGTH, MO5_HBIT_LENGTH, (hbit ? 1 : -1) << 30 ); \ + cass->put_sample ( 0, hbitsize * MO5_HBIT_LENGTH, MO5_HBIT_LENGTH, (hbit ? 1 : -1) << 30 ); \ hbitsize++; \ } while ( 0 ) @@ -534,7 +531,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) } while (0) /* check format */ - cassette_image_read( cass, block, 0, 64 ); + cass->image_read( block, 0, 64 ); for ( i = 3; ; i++ ) { if ( ( i >= size ) || ( i >= 64 ) ) @@ -556,7 +553,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) } } - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( block, pos, 6 ); if ( ! memcmp( block, "DCMOTO", 6 ) || ! memcmp( block, "DCMO5", 5 ) || ! memcmp( block, "DCMO6", 5 ) ) dcmoto = 1; @@ -567,7 +564,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) /* skip DCMOTO header*/ if ( dcmoto ) { - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( block, pos, 6 ); if ( ! memcmp( block, "DCMOTO", 6 ) ) { LOG (( "mo5_k5_load: DCMOTO signature found at off=$%x\n", (int)pos )); @@ -583,7 +580,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) /* skip 0x01 filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); if ( in != 0x01 ) break; } @@ -594,7 +591,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) pos -= sz; break; } - cassette_image_read( cass, block, pos, 4 ); + cass->image_read( block, pos, 4 ); typ = block[2]; sz2 = (uint8_t) (block[3]-1); if ( block[0] != 0x3c || block[1] != 0x5a || ( typ != 0x00 && typ != 0x01 && typ != 0xff ) || pos+sz2 > size ) @@ -605,7 +602,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) pos += 4; /* get block */ - cassette_image_read( cass, block+4, pos, sz2 ); + cass->image_read( block+4, pos, sz2 ); pos += sz2; /* 0-fillers and 0x01-fillers */ @@ -665,33 +662,33 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) LOG (( "mo5_k5_load: trailing trash off=$%x size=%i hbitstart=%i\n", (int) pos, (int) (size-pos), hbitsize )); for ( ; pos < size; pos++ ) { - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); if ( dcmoto && in=='D' ) { /* skip DCMOTO header*/ - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( block, pos, 6 ); if ( ! memcmp( block, "DCMOTO", 6 ) ) { LOG (( "mo5_k5_load: DCMOTO signature found at off=$%x\n", (int)pos )); pos += 6; - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); } else if ( ! memcmp( block, "DCMO", 4 ) ) { LOG (( "mo5_k5_load: DCMO* signature found at off=$%x\n", (int)pos )); pos += 5; - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); } } for ( sz = 0; pos < size && in == 0x01; sz++ ) { pos++; - cassette_image_read( cass, &in, pos, 1 ); + cass->image_read( &in, pos, 1 ); } if ( sz > 6 ) { - cassette_image_read( cass, &in2, pos+1, 1 ); - cassette_image_read( cass, &in3, pos+2, 1 ); + cass->image_read( &in2, pos+1, 1 ); + cass->image_read( &in3, pos+2, 1 ); if ( invalid < 10 && in == 0x3c && in2 == 0x5a && (in3 == 0x00 || in3 == 0x01 || in3 == 0xff ) ) { /* regular block found */ @@ -729,7 +726,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) -static const struct CassetteFormat mo5_k5 = +static const cassette_image::Format mo5_k5 = { "k5,k7", mo5_k5_identify, mo5_k5_load, nullptr /* no save */ }; @@ -738,9 +735,9 @@ static const struct CassetteFormat mo5_k5 = static cassette_image::error mo5_wav_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { - cassette_image::error e = wavfile_format.identify( cass, opts ); + cassette_image::error e = cassette_image::wavfile_format.identify( cass, opts ); return e; } @@ -748,13 +745,11 @@ static cassette_image::error mo5_wav_identify ( cassette_image *cass, static cassette_image::error mo5_wav_load ( cassette_image *cass ) { - cassette_image::error e = wavfile_format.load( cass ); - struct CassetteInfo info; - int len; + cassette_image::error e = cassette_image::wavfile_format.load( cass ); if ( e == cassette_image::error::SUCCESS ) { - cassette_get_info( cass, &info ); - len = info.sample_count / info.sample_frequency; + cassette_image::Info info = cass->get_info( ); + int len = info.sample_count / info.sample_frequency; PRINT (( "mo5_wav_load: loading cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info.sample_frequency, info.bits_per_sample )); } return e; @@ -762,17 +757,17 @@ static cassette_image::error mo5_wav_load ( cassette_image *cass ) -static cassette_image::error mo5_wav_save ( cassette_image *cass, const struct CassetteInfo *info ) +static cassette_image::error mo5_wav_save ( cassette_image *cass, const cassette_image::Info *info ) { int len = info->sample_count / info->sample_frequency; PRINT (( "mo5_wav_save: saving cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info->sample_frequency, info->bits_per_sample )); - return wavfile_format.save( cass, info ); + return cassette_image::wavfile_format.save( cass, info ); } /* overloaded wav: dump info */ -static const struct CassetteFormat mo5_wav = +static const cassette_image::Format mo5_wav = { "wav", mo5_wav_identify, mo5_wav_load, mo5_wav_save }; @@ -780,9 +775,9 @@ static const struct CassetteFormat mo5_wav = /********************* formats ************************/ -const struct CassetteFormat *const to7_cassette_formats[] = +const cassette_image::Format *const to7_cassette_formats[] = { &to7_wav, &to7_k7, nullptr }; -const struct CassetteFormat *const mo5_cassette_formats[] = +const cassette_image::Format *const mo5_cassette_formats[] = { &mo5_wav, &mo5_k5, nullptr }; diff --git a/src/lib/formats/trs_cas.cpp b/src/lib/formats/trs_cas.cpp index 582abf8869c..7556c392427 100644 --- a/src/lib/formats/trs_cas.cpp +++ b/src/lib/formats/trs_cas.cpp @@ -5,17 +5,17 @@ Support for TRS80 .cas cassette images ********************************************************************/ +#include "formats/trs_cas.h" #include <cassert> -#include "formats/trs_cas.h" #define SILENCE 0 #define SMPLO -32768 #define SMPHI 32767 -static int cas_size; +static int cas_size; // FIXME: global variable prevents mutliple instances /******************************************************************* @@ -99,7 +99,7 @@ static int trs80l2_cas_to_wav_size(const uint8_t *casdata, int caslen) return trs80l2_handle_cas( nullptr, casdata ); } -static const struct CassetteLegacyWaveFiller trs80l2_cas_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller trs80l2_cas_legacy_fill_wave = { trs80l2_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -111,19 +111,19 @@ static const struct CassetteLegacyWaveFiller trs80l2_cas_legacy_fill_wave = }; -static cassette_image::error trs80l2_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error trs80l2_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &trs80l2_cas_legacy_fill_wave); + return cassette->legacy_identify(opts, &trs80l2_cas_legacy_fill_wave); } static cassette_image::error trs80l2_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &trs80l2_cas_legacy_fill_wave); + return cassette->legacy_construct(&trs80l2_cas_legacy_fill_wave); } -static const struct CassetteFormat trs80l2_cas_format = +static const cassette_image::Format trs80l2_cas_format = { "cas", trs80l2_cas_identify, diff --git a/src/lib/formats/tvc_cas.cpp b/src/lib/formats/tvc_cas.cpp index 3cea37cc1bf..e6d05451d9d 100644 --- a/src/lib/formats/tvc_cas.cpp +++ b/src/lib/formats/tvc_cas.cpp @@ -7,10 +7,10 @@ http://tvc.homeserver.hu/html/konvertformatum.html ********************************************************************/ +#include "tvc_cas.h" #include <cassert> -#include "tvc_cas.h" #define TVC64_BIT0_FREQ 1812 #define TVC64_BIT1_FREQ 2577 @@ -24,7 +24,7 @@ static void tvc64_emit_level(cassette_image *cass, double &time, int freq, int level) { double period = 1.0 / freq; - cassette_put_sample(cass, 0, time, period, level * WAVE_AMPLITUDE); + cass->put_sample(0, time, period, level * WAVE_AMPLITUDE); time += period; } @@ -89,7 +89,7 @@ static cassette_image::error tvc64_cassette_load(cassette_image *cassette) double time = 0.0; uint8_t header[TVC64_HEADER_BYTES]; - cassette_image_read(cassette, header, 0, TVC64_HEADER_BYTES); + cassette->image_read(header, 0, TVC64_HEADER_BYTES); uint16_t cas_size = (header[0x83]<<8) | header[0x82]; // tape header @@ -172,7 +172,7 @@ static cassette_image::error tvc64_cassette_load(cassette_image *cassette) // sector data int sector_size = (i == sector_num) ? (cas_size % 256) : 256; for (int z=0; z < sector_size; z++) - cassette_image_read(cassette, &tmp_buff[buff_idx++], TVC64_HEADER_BYTES + i*256 + z, 1); + cassette->image_read(&tmp_buff[buff_idx++], TVC64_HEADER_BYTES + i*256 + z, 1); if (i == sector_num || ((i+1) == sector_num && (cas_size % 256 ) == 0)) tmp_buff[buff_idx++] = 0xff; // last sector @@ -200,10 +200,10 @@ static cassette_image::error tvc64_cassette_load(cassette_image *cassette) return cassette_image::error::SUCCESS; } -static cassette_image::error tvc64_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error tvc64_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { uint8_t byte; - cassette_image_read(cassette, &byte, 0, 1); + cassette->image_read(&byte, 0, 1); if (byte == 0x11) { @@ -216,7 +216,7 @@ static cassette_image::error tvc64_cassette_identify(cassette_image *cassette, s return cassette_image::error::INVALID_IMAGE; } -static const struct CassetteFormat tvc64_cassette_image_format = +static const cassette_image::Format tvc64_cassette_image_format = { "cas", tvc64_cassette_identify, diff --git a/src/lib/formats/tzx_cas.cpp b/src/lib/formats/tzx_cas.cpp index e1ced8175f0..1804e89b1b6 100644 --- a/src/lib/formats/tzx_cas.cpp +++ b/src/lib/formats/tzx_cas.cpp @@ -52,7 +52,7 @@ static const uint8_t TZX_HEADER[8] = { 'Z','X','T','a','p','e','!',0x1a }; Initialized by tzx_cas_get_wave_size, used (and cleaned up) by tzx_cas_fill_wave */ -static int16_t wave_data = 0; +static int16_t wave_data = 0; // FIXME: global variables prevent multiple instances static int block_count = 0; static uint8_t** blocks = nullptr; static float t_scale = 1; /* for scaling T-states to the 4MHz CPC */ @@ -831,7 +831,7 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) return size; } -static const struct CassetteLegacyWaveFiller tzx_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller tzx_legacy_fill_wave = { tzx_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -842,7 +842,7 @@ static const struct CassetteLegacyWaveFiller tzx_legacy_fill_wave = 0 /* trailer_samples */ }; -static const struct CassetteLegacyWaveFiller tap_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller tap_legacy_fill_wave = { tap_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -853,7 +853,7 @@ static const struct CassetteLegacyWaveFiller tap_legacy_fill_wave = 0 /* trailer_samples */ }; -static const struct CassetteLegacyWaveFiller cdt_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller cdt_legacy_fill_wave = { cdt_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -864,24 +864,24 @@ static const struct CassetteLegacyWaveFiller cdt_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error tzx_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) +static cassette_image::error tzx_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { - return cassette_legacy_identify(cassette, opts, &tzx_legacy_fill_wave); + return cassette->legacy_identify(opts, &tzx_legacy_fill_wave); } -static cassette_image::error tap_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) +static cassette_image::error tap_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { - return cassette_legacy_identify(cassette, opts, &tap_legacy_fill_wave); + return cassette->legacy_identify(opts, &tap_legacy_fill_wave); } -static cassette_image::error cdt_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) +static cassette_image::error cdt_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { - return cassette_legacy_identify(cassette, opts, &cdt_legacy_fill_wave); + return cassette->legacy_identify(opts, &cdt_legacy_fill_wave); } static cassette_image::error tzx_cassette_load( cassette_image *cassette ) { - cassette_image::error err = cassette_legacy_construct(cassette, &tzx_legacy_fill_wave); + cassette_image::error err = cassette->legacy_construct(&tzx_legacy_fill_wave); free(blocks); blocks = nullptr; return err; @@ -889,18 +889,18 @@ static cassette_image::error tzx_cassette_load( cassette_image *cassette ) static cassette_image::error tap_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct(cassette, &tap_legacy_fill_wave); + return cassette->legacy_construct(&tap_legacy_fill_wave); } static cassette_image::error cdt_cassette_load( cassette_image *cassette ) { - cassette_image::error err = cassette_legacy_construct(cassette, &cdt_legacy_fill_wave); + cassette_image::error err = cassette->legacy_construct(&cdt_legacy_fill_wave); free(blocks); blocks = nullptr; return err; } -const struct CassetteFormat tzx_cassette_format = +const cassette_image::Format tzx_cassette_format = { "tzx", tzx_cassette_identify, @@ -908,7 +908,7 @@ const struct CassetteFormat tzx_cassette_format = nullptr }; -static const struct CassetteFormat tap_cassette_format = +static const cassette_image::Format tap_cassette_format = { "tap,blk", tap_cassette_identify, @@ -916,7 +916,7 @@ static const struct CassetteFormat tap_cassette_format = nullptr }; -static const struct CassetteFormat cdt_cassette_format = +static const cassette_image::Format cdt_cassette_format = { "cdt", cdt_cassette_identify, diff --git a/src/lib/formats/tzx_cas.h b/src/lib/formats/tzx_cas.h index 2410ea57523..b7e620b1683 100644 --- a/src/lib/formats/tzx_cas.h +++ b/src/lib/formats/tzx_cas.h @@ -13,7 +13,7 @@ #include "cassimg.h" -extern const struct CassetteFormat tzx_cassette_format; +extern const cassette_image::Format tzx_cassette_format; CASSETTE_FORMATLIST_EXTERN(tzx_cassette_formats); CASSETTE_FORMATLIST_EXTERN(cdt_cassette_formats); diff --git a/src/lib/formats/uef_cas.cpp b/src/lib/formats/uef_cas.cpp index d19eb9b2e47..1b4fb1bc271 100644 --- a/src/lib/formats/uef_cas.cpp +++ b/src/lib/formats/uef_cas.cpp @@ -17,13 +17,13 @@ the size of memory to alloc for the decoding. Not nice, but it works... */ - -#include <cstring> -#include <cmath> -#include <cassert> +#include "uef_cas.h" #include <zlib.h> -#include "uef_cas.h" + +#include <cassert> +#include <cmath> +#include <cstring> #define UEF_WAV_FREQUENCY 4800 @@ -334,7 +334,7 @@ static int uef_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes ) return p - buffer; } -static const struct CassetteLegacyWaveFiller uef_legacy_fill_wave = { +static const cassette_image::LegacyWaveFiller uef_legacy_fill_wave = { uef_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ 0, /* chunk_samples */ @@ -344,21 +344,21 @@ static const struct CassetteLegacyWaveFiller uef_legacy_fill_wave = { 0 /* trailer_samples */ }; -static cassette_image::error uef_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts ) { +static cassette_image::error uef_cassette_identify( cassette_image *cassette, cassette_image::Options *opts ) { uint8_t header[10]; - cassette_image_read(cassette, header, 0, sizeof(header)); + cassette->image_read(header, 0, sizeof(header)); if (memcmp(&header[0], GZ_HEADER, sizeof(GZ_HEADER)) && memcmp(&header[0], UEF_HEADER, sizeof(UEF_HEADER))) { return cassette_image::error::INVALID_IMAGE; } - return cassette_legacy_identify( cassette, opts, &uef_legacy_fill_wave ); + return cassette->legacy_identify( opts, &uef_legacy_fill_wave ); } static cassette_image::error uef_cassette_load( cassette_image *cassette ) { - return cassette_legacy_construct( cassette, &uef_legacy_fill_wave ); + return cassette->legacy_construct( &uef_legacy_fill_wave ); } -const struct CassetteFormat uef_cassette_format = { +const cassette_image::Format uef_cassette_format = { "uef", uef_cassette_identify, uef_cassette_load, diff --git a/src/lib/formats/uef_cas.h b/src/lib/formats/uef_cas.h index 73aa2fe8ae2..f6bcff94ca1 100644 --- a/src/lib/formats/uef_cas.h +++ b/src/lib/formats/uef_cas.h @@ -12,7 +12,7 @@ #include "cassimg.h" -extern const struct CassetteFormat uef_cassette_format; +extern const cassette_image::Format uef_cassette_format; CASSETTE_FORMATLIST_EXTERN(uef_cassette_formats); diff --git a/src/lib/formats/vg5k_cas.cpp b/src/lib/formats/vg5k_cas.cpp index 45d3680618c..f73049299b1 100644 --- a/src/lib/formats/vg5k_cas.cpp +++ b/src/lib/formats/vg5k_cas.cpp @@ -5,17 +5,17 @@ Support for VG-5000 .k7 cassette images ********************************************************************/ -#include <cassert> - #include "vg5k_cas.h" +#include <cassert> + #define SMPLO -32768 #define SILENCE 0 #define SMPHI 32767 -static int k7_size; +static int k7_size; // FIXME: global variable prevents multiple instances /******************************************************************* Generate one high-low cycle of sample data @@ -200,7 +200,7 @@ static int vg5k_k7_to_wav_size(const uint8_t *casdata, int caslen) } -static const struct CassetteLegacyWaveFiller vg5k_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller vg5k_legacy_fill_wave = { vg5k_k7_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -211,19 +211,19 @@ static const struct CassetteLegacyWaveFiller vg5k_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error vg5k_k7_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error vg5k_k7_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &vg5k_legacy_fill_wave); + return cassette->legacy_identify(opts, &vg5k_legacy_fill_wave); } static cassette_image::error vg5k_k7_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &vg5k_legacy_fill_wave); + return cassette->legacy_construct(&vg5k_legacy_fill_wave); } -static const struct CassetteFormat vg5k_k7_format = +static const cassette_image::Format vg5k_k7_format = { "k7", vg5k_k7_identify, @@ -234,5 +234,5 @@ static const struct CassetteFormat vg5k_k7_format = CASSETTE_FORMATLIST_START(vg5k_cassette_formats) CASSETTE_FORMAT(vg5k_k7_format) - CASSETTE_FORMAT(wavfile_format) + CASSETTE_FORMAT(cassette_image::wavfile_format) CASSETTE_FORMATLIST_END diff --git a/src/lib/formats/vt_cas.cpp b/src/lib/formats/vt_cas.cpp index a8c30f8d25f..735ec067d7b 100644 --- a/src/lib/formats/vt_cas.cpp +++ b/src/lib/formats/vt_cas.cpp @@ -1,9 +1,9 @@ // license:GPL-2.0+ // copyright-holders:Juergen Buchmueller -#include <cassert> - #include "formats/vt_cas.h" +#include <cassert> + /********************************************************************* vtech 1/2 agnostic *********************************************************************/ @@ -97,28 +97,28 @@ static int vtech1_cassette_fill_wave(int16_t *buffer, int length, uint8_t *code) return generic_fill_wave(buffer, length, code, V1_BITSAMPLES, V1_BYTESAMPLES, V1_LO, vtech1_fill_wave_byte); } -static const struct CassetteLegacyWaveFiller vtech1_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller vtech1_legacy_fill_wave = { - vtech1_cassette_fill_wave, /* fill_wave */ - 1, /* chunk_size */ - V1_BYTESAMPLES, /* chunk_samples */ - nullptr, /* chunk_sample_calc */ - 600*V1_BITSAMPLES, /* sample_frequency */ - 600*V1_BITSAMPLES, /* header_samples */ - 600*V1_BITSAMPLES /* trailer_samples */ + vtech1_cassette_fill_wave, // fill_wave + 1, // chunk_size + V1_BYTESAMPLES, // chunk_samples + nullptr, // chunk_sample_calc + 600*V1_BITSAMPLES, // sample_frequency + 600*V1_BITSAMPLES, // header_samples + 600*V1_BITSAMPLES // trailer_samples }; -static cassette_image::error vtech1_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error vtech1_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &vtech1_legacy_fill_wave); + return cassette->legacy_identify(opts, &vtech1_legacy_fill_wave); } static cassette_image::error vtech1_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &vtech1_legacy_fill_wave); + return cassette->legacy_construct(&vtech1_legacy_fill_wave); } -static const struct CassetteFormat vtech1_cas_format = +static const cassette_image::Format vtech1_cas_format = { "cas", vtech1_cas_identify, @@ -192,7 +192,7 @@ static int vtech2_cassette_fill_wave(int16_t *buffer, int length, uint8_t *code) return generic_fill_wave(buffer, length, code, VT2_BITSAMPLES, VT2_BYTESAMPLES, VT2_LO, vtech2_fill_wave_byte); } -static const struct CassetteLegacyWaveFiller vtech2_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller vtech2_legacy_fill_wave = { vtech2_cassette_fill_wave, /* fill_wave */ 1, /* chunk_size */ @@ -203,17 +203,17 @@ static const struct CassetteLegacyWaveFiller vtech2_legacy_fill_wave = 600*VT2_BITSAMPLES /* trailer_samples */ }; -static cassette_image::error vtech2_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error vtech2_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &vtech2_legacy_fill_wave); + return cassette->legacy_identify(opts, &vtech2_legacy_fill_wave); } static cassette_image::error vtech2_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &vtech2_legacy_fill_wave); + return cassette->legacy_construct(&vtech2_legacy_fill_wave); } -static const struct CassetteFormat vtech2_cas_format = +static const cassette_image::Format vtech2_cas_format = { "cas", vtech2_cas_identify, diff --git a/src/lib/formats/wavfile.cpp b/src/lib/formats/wavfile.cpp index 1408984079c..1ab9598ac9a 100644 --- a/src/lib/formats/wavfile.cpp +++ b/src/lib/formats/wavfile.cpp @@ -8,12 +8,11 @@ *********************************************************************/ +#include "wavfile.h" + #include <cstdio> #include <cassert> -#include "wavfile.h" -#include "cassimg.h" - static const char magic1[4] = { 'R', 'I', 'F', 'F' }; static const char magic2[4] = { 'W', 'A', 'V', 'E' }; static const char format_tag_id[4] = { 'f', 'm', 't', ' ' }; @@ -57,7 +56,7 @@ static void put_leuint16(void *ptr, uint16_t value) -static cassette_image::error wavfile_process(cassette_image *cassette, struct CassetteOptions *opts, +static cassette_image::error wavfile_process(cassette_image *cassette, cassette_image::Options *opts, bool read_waveform) { uint8_t file_header[12]; @@ -76,7 +75,7 @@ static cassette_image::error wavfile_process(cassette_image *cassette, struct Ca int waveform_flags = 0; /* read header */ - cassette_image_read(cassette, file_header, 0, sizeof(file_header)); + cassette->image_read(file_header, 0, sizeof(file_header)); offset = sizeof(file_header); /* check magic numbers */ @@ -87,13 +86,13 @@ static cassette_image::error wavfile_process(cassette_image *cassette, struct Ca /* read and sanity check size */ stated_size = get_leuint32(&file_header[4]) + 8; - file_size = cassette_image_size(cassette); + file_size = cassette->image_size(); if (stated_size > file_size) stated_size = (uint32_t) file_size; while(offset < stated_size) { - cassette_image_read(cassette, tag_header, offset, sizeof(tag_header)); + cassette->image_read(tag_header, offset, sizeof(tag_header)); tag_size = get_leuint32(&tag_header[4]); offset += sizeof(tag_header); @@ -104,7 +103,7 @@ static cassette_image::error wavfile_process(cassette_image *cassette, struct Ca return cassette_image::error::INVALID_IMAGE; format_specified = true; - cassette_image_read(cassette, format_tag, offset, sizeof(format_tag)); + cassette->image_read(format_tag, offset, sizeof(format_tag)); format_type = get_leuint16(&format_tag[0]); opts->channels = get_leuint16(&format_tag[2]); @@ -142,7 +141,7 @@ static cassette_image::error wavfile_process(cassette_image *cassette, struct Ca if (read_waveform) { tag_samples = tag_size / (opts->bits_per_sample / 8) / opts->channels; - cassette_read_samples(cassette, opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency), + cassette->read_samples(opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency), tag_samples, offset, waveform_flags); } } @@ -158,7 +157,7 @@ static cassette_image::error wavfile_process(cassette_image *cassette, struct Ca -static cassette_image::error wavfile_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error wavfile_identify(cassette_image *cassette, cassette_image::Options *opts) { return wavfile_process(cassette, opts, false); } @@ -167,14 +166,14 @@ static cassette_image::error wavfile_identify(cassette_image *cassette, struct C static cassette_image::error wavfile_load(cassette_image *cassette) { - struct CassetteOptions opts; + cassette_image::Options opts; memset(&opts, 0, sizeof(opts)); return wavfile_process(cassette, &opts, true); } -static cassette_image::error wavfile_save(cassette_image *cassette, const struct CassetteInfo *info) +static cassette_image::error wavfile_save(cassette_image *cassette, const cassette_image::Info *info) { cassette_image::error err; uint8_t consolidated_header[12 + 8 + 16 + 8]; @@ -216,10 +215,10 @@ static cassette_image::error wavfile_save(cassette_image *cassette, const struct put_leuint32(&data_tag_header[4], data_size); /* write consolidated header */ - cassette_image_write(cassette, consolidated_header, 0, sizeof(consolidated_header)); + cassette->image_write(consolidated_header, 0, sizeof(consolidated_header)); /* write out the actual data */ - err = cassette_write_samples(cassette, info->channels, 0.0, info->sample_count + err = cassette->write_samples(info->channels, 0.0, info->sample_count / (double) info->sample_frequency, info->sample_count, sizeof(consolidated_header), waveform_flags); if (err != cassette_image::error::SUCCESS) @@ -230,7 +229,7 @@ static cassette_image::error wavfile_save(cassette_image *cassette, const struct -const struct CassetteFormat wavfile_format = +const cassette_image::Format cassette_image::wavfile_format = { "wav", wavfile_identify, diff --git a/src/lib/formats/wavfile.h b/src/lib/formats/wavfile.h index 0f48b8378b0..397d502a0ec 100644 --- a/src/lib/formats/wavfile.h +++ b/src/lib/formats/wavfile.h @@ -14,6 +14,4 @@ #include "cassimg.h" -extern const struct CassetteFormat wavfile_format; - #endif // MAME_FORMATS_WAVFILE_H diff --git a/src/lib/formats/x07_cas.cpp b/src/lib/formats/x07_cas.cpp index 131693f2da1..182a1303cd8 100644 --- a/src/lib/formats/x07_cas.cpp +++ b/src/lib/formats/x07_cas.cpp @@ -6,10 +6,10 @@ ********************************************************************/ -#include <cassert> - #include "x07_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -19,7 +19,7 @@ #define X07_HEADER_BYTES 16 // image size -static int x07_image_size; +static int x07_image_size; // FIXME: global variable prevents multiple instances static int x07_put_samples(int16_t *buffer, int sample_pos, int count, int level) { @@ -140,7 +140,7 @@ static int x07_cassette_calculate_size_in_samples(const uint8_t *bytes, int leng return x07_handle_cassette(nullptr, bytes); } -static const struct CassetteLegacyWaveFiller x07_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller x07_legacy_fill_wave = { x07_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -151,17 +151,17 @@ static const struct CassetteLegacyWaveFiller x07_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error x07_cassette_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error x07_cassette_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &x07_legacy_fill_wave); + return cassette->legacy_identify(opts, &x07_legacy_fill_wave); } static cassette_image::error x07_cassette_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &x07_legacy_fill_wave); + return cassette->legacy_construct(&x07_legacy_fill_wave); } -static const struct CassetteFormat x07_cassette_image_format = +static const cassette_image::Format x07_cassette_image_format = { "k7,lst,cas", x07_cassette_identify, diff --git a/src/lib/formats/x1_tap.cpp b/src/lib/formats/x1_tap.cpp index 88c962bf53b..cbd261f6610 100644 --- a/src/lib/formats/x1_tap.cpp +++ b/src/lib/formats/x1_tap.cpp @@ -20,15 +20,15 @@ * 0x00: Sampling rate (4 bytes) * */ +#include "x1_tap.h" #include <cassert> -#include "x1_tap.h" #define WAVE_HIGH 0x5a9e #define WAVE_LOW -0x5a9e -static int cas_size; +static int cas_size; // FIXME: global variables prevent multiple instances static int samplerate; static int new_format; @@ -103,7 +103,7 @@ static int x1_cas_fill_wave(int16_t *buffer, int sample_count, uint8_t *bytes) return x1_handle_tap(buffer,bytes); } -static const struct CassetteLegacyWaveFiller x1_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller x1_legacy_fill_wave = { x1_cas_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -114,20 +114,20 @@ static const struct CassetteLegacyWaveFiller x1_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error x1_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error x1_cas_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &x1_legacy_fill_wave); + return cassette->legacy_identify(opts, &x1_legacy_fill_wave); } static cassette_image::error x1_cas_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &x1_legacy_fill_wave); + return cassette->legacy_construct(&x1_legacy_fill_wave); } -static const struct CassetteFormat x1_cassette_format = { +static const cassette_image::Format x1_cassette_format = { "tap", x1_cas_identify, x1_cas_load, diff --git a/src/lib/formats/zx81_p.cpp b/src/lib/formats/zx81_p.cpp index 709bdccfc4c..186815507fe 100644 --- a/src/lib/formats/zx81_p.cpp +++ b/src/lib/formats/zx81_p.cpp @@ -31,11 +31,11 @@ medium transfer rate is approx. 307 bps (38 bytes/sec) for files that contain *****************************************************************************/ -#include <cassert> - #include "zx81_p.h" #include "tzx_cas.h" +#include <cassert> + #define WAVEENTRY_LOW -32768 #define WAVEENTRY_HIGH 32767 @@ -56,7 +56,7 @@ medium transfer rate is approx. 307 bps (38 bytes/sec) for files that contain #define ZX81_DATA_LENGTH_OFFSET 0x0b #define ZX80_DATA_LENGTH_OFFSET 0x04 -static uint8_t zx_file_name[128]; +static uint8_t zx_file_name[128]; // FIXME: global variables prevent multiple instances static uint16_t real_data_length = 0; static uint8_t zx_file_name_length = 0; @@ -64,9 +64,7 @@ static uint8_t zx_file_name_length = 0; static int16_t *zx81_emit_level(int16_t *p, int count, int level) { - int i; - - for (i=0; i<count; i++) *(p++) = level; + for (int i=0; i<count; i++) *(p++) = level; return p; } @@ -196,7 +194,7 @@ static int zx81_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) return p - buffer; } -static const struct CassetteLegacyWaveFiller zx81_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller zx81_legacy_fill_wave = { zx81_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -207,9 +205,9 @@ static const struct CassetteLegacyWaveFiller zx81_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error zx81_p_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error zx81_p_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &zx81_legacy_fill_wave); + return cassette->legacy_identify(opts, &zx81_legacy_fill_wave); } static cassette_image::error zx81_p_load(cassette_image *cassette) @@ -219,10 +217,10 @@ static cassette_image::error zx81_p_load(cassette_image *cassette) Hardcoding this to "cassette". */ zx81_fill_file_name ("cassette" /*image_basename_noext(device_list_find_by_tag( Machine->config->m_devicelist, CASSETTE, "cassette" ))*/ ); - return cassette_legacy_construct(cassette, &zx81_legacy_fill_wave); + return cassette->legacy_construct(&zx81_legacy_fill_wave); } -static const struct CassetteFormat zx81_p_image_format = +static const cassette_image::Format zx81_p_image_format = { "p,81", zx81_p_identify, @@ -269,7 +267,7 @@ static int zx80_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes) return p - buffer; } -static const struct CassetteLegacyWaveFiller zx80_legacy_fill_wave = +static const cassette_image::LegacyWaveFiller zx80_legacy_fill_wave = { zx80_cassette_fill_wave, /* fill_wave */ -1, /* chunk_size */ @@ -280,17 +278,17 @@ static const struct CassetteLegacyWaveFiller zx80_legacy_fill_wave = 0 /* trailer_samples */ }; -static cassette_image::error zx80_o_identify(cassette_image *cassette, struct CassetteOptions *opts) +static cassette_image::error zx80_o_identify(cassette_image *cassette, cassette_image::Options *opts) { - return cassette_legacy_identify(cassette, opts, &zx80_legacy_fill_wave); + return cassette->legacy_identify(opts, &zx80_legacy_fill_wave); } static cassette_image::error zx80_o_load(cassette_image *cassette) { - return cassette_legacy_construct(cassette, &zx80_legacy_fill_wave); + return cassette->legacy_construct(&zx80_legacy_fill_wave); } -static const struct CassetteFormat zx80_o_image_format = +static const cassette_image::Format zx80_o_image_format = { "o,80", zx80_o_identify, diff --git a/src/mame/drivers/primo.cpp b/src/mame/drivers/primo.cpp index 65b9e2b44c9..0bdd213fb82 100644 --- a/src/mame/drivers/primo.cpp +++ b/src/mame/drivers/primo.cpp @@ -244,7 +244,7 @@ static INPUT_PORTS_START( primo ) PORT_CONFSETTING( 0x01, DEF_STR( Off ) ) INPUT_PORTS_END -static const struct CassetteOptions primo_cassette_options = { +static const cassette_image::Options primo_cassette_options = { 1, /* channels */ 16, /* bits per sample */ 22050 /* sample frequency */ diff --git a/src/mame/machine/thomson.cpp b/src/mame/machine/thomson.cpp index ee2fd34b6fe..cf8ca0fc56c 100644 --- a/src/mame/machine/thomson.cpp +++ b/src/mame/machine/thomson.cpp @@ -96,7 +96,7 @@ int thomson_state::to7_get_cassette() /* we simply count sign changes... */ int k, chg; int8_t data[40]; - cassette_get_samples( cass, 0, pos, TO7_BIT_LENGTH * 15. / 14., 40, 1, data, 0 ); + cass->get_samples( 0, pos, TO7_BIT_LENGTH * 15. / 14., 40, 1, data, 0 ); for ( k = 1, chg = 0; k < 40; k++ ) { @@ -177,7 +177,7 @@ int thomson_state::mo5_get_cassette() if ( (state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED ) return 1; - cassette_get_sample( cass, 0, pos, 0, &hbit ); + cass->get_sample( 0, pos, 0, &hbit ); hbit = hbit >= 0; VLOG (( "$%04x %f mo5_get_cassette: state=$%X pos=%f hbitpos=%i hbit=%i\n", diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp index 0b2b4230f8b..b67d9b4e303 100644 --- a/src/tools/castool.cpp +++ b/src/tools/castool.cpp @@ -10,15 +10,6 @@ ***************************************************************************/ -#include <cstdio> -#include <cstring> -#include <cctype> -#include <cstdlib> -#include <ctime> -#include <cassert> - -#include "corestr.h" - #include "formats/a26_cas.h" #include "formats/ace_tap.h" #include "formats/adam_cas.h" @@ -61,10 +52,20 @@ #include "formats/x1_tap.h" #include "formats/zx81_p.h" +#include "corestr.h" + +#include <cassert> +#include <cctype> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> + + struct SupportedCassetteFormats { const char *name; - const struct CassetteFormat * const *formats; + const cassette_image::Format * const *formats; const char *desc; }; @@ -159,8 +160,8 @@ int CLIB_DECL main(int argc, char *argv[]) { int i; int found =0; - const struct CassetteFormat * const *selected_formats = nullptr; - cassette_image *cassette; + const cassette_image::Format * const *selected_formats = nullptr; + cassette_image::ptr cassette; FILE *f; if (argc > 1) @@ -193,14 +194,14 @@ int CLIB_DECL main(int argc, char *argv[]) return -1; } - if (cassette_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_FLAG_READONLY, cassette) != cassette_image::error::SUCCESS) { fprintf(stderr, "Invalid format of input file.\n"); fclose(f); return -1; } - cassette_dump(cassette,argv[4]); - cassette_close(cassette); + cassette->dump(argv[4]); + cassette.reset(); fclose(f); goto theend; } |