formats/flacfile.cpp: Added support for compact cassette images in FLAC format. (#11841)

This commit is contained in:
wilbertpol 2023-12-17 04:22:40 +00:00 committed by GitHub
parent 3706aabe3d
commit b9fbc6e7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 1 deletions

View File

@ -25,6 +25,7 @@ project "formats"
MAME_DIR .. "src/lib/util",
MAME_DIR .. "3rdparty",
GEN_DIR,
ext_includedir("flac"),
ext_includedir("zlib"),
}
@ -37,6 +38,8 @@ project "formats"
MAME_DIR .. "src/lib/formats/cassimg.cpp",
MAME_DIR .. "src/lib/formats/cassimg.h",
MAME_DIR .. "src/lib/formats/flacfile.cpp",
MAME_DIR .. "src/lib/formats/flacfile.h",
MAME_DIR .. "src/lib/formats/wavfile.cpp",
MAME_DIR .. "src/lib/formats/wavfile.h",

View File

@ -136,6 +136,7 @@ public:
uint8_t image_read_byte(uint64_t offset);
void image_write(const void *buffer, uint64_t offset, size_t length);
uint64_t image_size();
util::random_read_write::ptr &get_raw_cassette_image() { return m_io; }
// waveform accesses
error get_samples(int channel,
@ -191,6 +192,7 @@ public:
// builtin formats
static const Format wavfile_format;
static const Format flacfile_format;
private:
struct manipulation_ranges;
@ -224,7 +226,8 @@ private:
#define CASSETTE_FORMATLIST_START(name) \
const cassette_image::Format *const name[] = \
{ \
&cassette_image::wavfile_format,
&cassette_image::wavfile_format, \
&cassette_image::flacfile_format,
#define CASSETTE_FORMAT(name) \
&(name),
#define CASSETTE_FORMATLIST_END \

View File

@ -0,0 +1,86 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
/*********************************************************************
flacfile.cpp
Format code for flac files.
*********************************************************************/
#include "flacfile.h"
#include "flac.h"
#include <memory>
#include <new>
static constexpr int MAX_CHANNELS = 8;
static cassette_image::error flacfile_identify(cassette_image *cassette, cassette_image::Options *opts)
{
cassette->get_raw_cassette_image()->seek(0, SEEK_SET);
flac_decoder decoder(*cassette->get_raw_cassette_image());
if (!decoder.reset())
return cassette_image::error::INVALID_IMAGE;
const int channels = decoder.channels();
const int sample_rate = decoder.sample_rate();
const int bits_per_sample = decoder.bits_per_sample();
const int total_samples = decoder.total_samples();
decoder.finish();
opts->channels = channels;
opts->sample_frequency = sample_rate;
opts->bits_per_sample = bits_per_sample;
if (channels > MAX_CHANNELS)
return cassette_image::error::INVALID_IMAGE;
else if (channels > 0 && sample_rate > 0 && total_samples > 0)
return cassette_image::error::SUCCESS;
else
return cassette_image::error::INVALID_IMAGE;
}
static cassette_image::error flacfile_load(cassette_image *cassette)
{
cassette->get_raw_cassette_image()->seek(0, SEEK_SET);
flac_decoder decoder(*cassette->get_raw_cassette_image());
if (!decoder.reset())
return cassette_image::error::INVALID_IMAGE;
const int channels = decoder.channels();
const int total_samples = decoder.total_samples();
std::unique_ptr<int16_t []> samples[MAX_CHANNELS];
int16_t *channel_samples[MAX_CHANNELS];
for (int channel = 0; channel < channels; channel++)
{
samples[channel].reset(new (std::nothrow) int16_t [total_samples]);
if (!samples[channel])
return cassette_image::error::OUT_OF_MEMORY;
channel_samples[channel] = samples[channel].get();
}
if (!decoder.decode(channel_samples, decoder.total_samples(), false))
return cassette_image::error::INVALID_IMAGE;
for (int channel = 0; channel < channels; channel++)
{
const cassette_image::error err = cassette->put_samples(
channel, 0.0, (double)total_samples/decoder.sample_rate(), total_samples,
2, channel_samples[channel], cassette_image::WAVEFORM_16BIT);
if (err != cassette_image::error::SUCCESS)
return err;
}
return cassette_image::error::SUCCESS;
}
const cassette_image::Format cassette_image::flacfile_format =
{
"flac",
flacfile_identify,
flacfile_load,
nullptr
};

View File

@ -0,0 +1,10 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
#ifndef MAME_FORMATS_FLACFILE_H
#define MAME_FORMATS_FLACFILE_H
#pragma once
#include "cassimg.h"
#endif // MAME_FORMATS_FLACFILE_H

View File

@ -316,6 +316,9 @@ flac_decoder::flac_decoder()
flac_decoder::flac_decoder(const void *buffer, uint32_t length, const void *buffer2, uint32_t length2)
: m_decoder(FLAC__stream_decoder_new()),
m_file(nullptr),
m_sample_rate(0),
m_channels(0),
m_bits_per_sample(0),
m_compressed_offset(0),
m_compressed_start(reinterpret_cast<const FLAC__byte *>(buffer)),
m_compressed_length(length),
@ -333,6 +336,9 @@ flac_decoder::flac_decoder(const void *buffer, uint32_t length, const void *buff
flac_decoder::flac_decoder(util::read_stream &file)
: m_decoder(FLAC__stream_decoder_new()),
m_file(&file),
m_sample_rate(0),
m_channels(0),
m_bits_per_sample(0),
m_compressed_offset(0),
m_compressed_start(nullptr),
m_compressed_length(0),