From ebc3f6947fd2014d941deb88ce9ac10d5ad9215b Mon Sep 17 00:00:00 2001 From: Frank Palazzolo Date: Sun, 8 Jul 2018 15:28:18 -0400 Subject: Bug fix for multi-channel reads in cassette_get_samples(). (#3725) * Bug fix for multi-channel reads in cassette_get_samples(). Use the unused "sample_bytes" arg the same way as cassette_put_samples() Can be used with multi-channel files now! * Rename sample_bytes to more descriptive sample_spacing Add some comments about sample functions and sample_spacing variable --- src/lib/formats/cassimg.cpp | 39 ++++++++++++++++++++++----------------- src/lib/formats/cassimg.h | 6 +++--- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp index 87636b81349..df8322ff8be 100644 --- a/src/lib/formats/cassimg.cpp +++ b/src/lib/formats/cassimg.cpp @@ -414,8 +414,11 @@ static cassette_image::error lookup_sample(cassette_image *cassette, int channel waveform accesses *********************************************************************/ +// 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, - double time_index, double sample_period, size_t sample_count, size_t sample_bytes, + double time_index, double sample_period, size_t sample_count, size_t sample_spacing, void *samples, int waveform_flags) { cassette_image::error err; @@ -456,7 +459,7 @@ cassette_image::error cassette_get_samples(cassette_image *cassette, int channel /* and write out the result */ dest_ptr = (uint8_t*)samples; - dest_ptr += waveform_bytes_per_sample(waveform_flags) * sample_index * cassette->channels; + dest_ptr += sample_index * sample_spacing; switch(waveform_bytes_per_sample(waveform_flags)) { case 1: @@ -480,9 +483,11 @@ cassette_image::error cassette_get_samples(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 read from samples +// (see cassette_read_samples) cassette_image::error cassette_put_samples(cassette_image *cassette, int channel, - double time_index, double sample_period, size_t sample_count, size_t sample_bytes, + double time_index, double sample_period, size_t sample_count, size_t sample_spacing, const void *samples, int waveform_flags) { cassette_image::error err; @@ -521,7 +526,7 @@ cassette_image::error cassette_put_samples(cassette_image *cassette, int channel /* 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; - source_ptr += ((size_t) d) * sample_bytes; + source_ptr += ((size_t) d) * sample_spacing; /* compute the value that we are writing */ switch(waveform_bytes_per_sample(waveform_flags)) { @@ -589,7 +594,7 @@ cassette_image::error cassette_read_samples(cassette_image *cassette, int channe cassette_image::error err; size_t chunk_sample_count; size_t bytes_per_sample; - size_t sample_bytes; + size_t sample_spacing; size_t samples_loaded = 0; double chunk_time_index; double chunk_sample_period; @@ -597,25 +602,25 @@ cassette_image::error cassette_read_samples(cassette_image *cassette, int channe uint8_t buffer[8192]; bytes_per_sample = waveform_bytes_per_sample(waveform_flags); - sample_bytes = bytes_per_sample * channels; + sample_spacing = bytes_per_sample * channels; while(samples_loaded < sample_count) { - chunk_sample_count = std::min(sizeof(buffer) / sample_bytes, (sample_count - samples_loaded)); + 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); - cassette_image_read(cassette, buffer, offset, chunk_sample_count * sample_bytes); + cassette_image_read(cassette, buffer, offset, chunk_sample_count * sample_spacing); for (channel = 0; channel < channels; channel++) { err = cassette_put_samples(cassette, channel, chunk_time_index, chunk_sample_period, - chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags); + chunk_sample_count, sample_spacing, &buffer[channel * bytes_per_sample], waveform_flags); if (err != cassette_image::error::SUCCESS) return err; } - offset += chunk_sample_count * sample_bytes; + offset += chunk_sample_count * sample_spacing; samples_loaded += chunk_sample_count; } return cassette_image::error::SUCCESS; @@ -629,7 +634,7 @@ cassette_image::error cassette_write_samples(cassette_image *cassette, int chann cassette_image::error err; size_t chunk_sample_count; size_t bytes_per_sample; - size_t sample_bytes; + size_t sample_spacing; size_t samples_saved = 0; double chunk_time_index; double chunk_sample_period; @@ -637,25 +642,25 @@ cassette_image::error cassette_write_samples(cassette_image *cassette, int chann uint8_t buffer[8192]; bytes_per_sample = waveform_bytes_per_sample(waveform_flags); - sample_bytes = bytes_per_sample * channels; + sample_spacing = bytes_per_sample * channels; while(samples_saved < sample_count) { - chunk_sample_count = std::min(sizeof(buffer) / sample_bytes, (sample_count - samples_saved)); + 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); for (channel = 0; channel < channels; channel++) { err = cassette_get_samples(cassette, channel, chunk_time_index, chunk_sample_period, - chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags); + chunk_sample_count, sample_spacing, &buffer[channel * bytes_per_sample], waveform_flags); if (err != cassette_image::error::SUCCESS) return err; } - cassette_image_write(cassette, buffer, offset, chunk_sample_count * sample_bytes); + cassette_image_write(cassette, buffer, offset, chunk_sample_count * sample_spacing); - offset += chunk_sample_count * sample_bytes; + offset += chunk_sample_count * sample_spacing; samples_saved += chunk_sample_count; } return cassette_image::error::SUCCESS; diff --git a/src/lib/formats/cassimg.h b/src/lib/formats/cassimg.h index 2f9ff01f1cb..88c2080114f 100644 --- a/src/lib/formats/cassimg.h +++ b/src/lib/formats/cassimg.h @@ -181,17 +181,17 @@ 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_bytes, + 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_bytes, + 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 */ +/* 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, -- cgit v1.2.3