diff options
author | 987123879113 <63495610+987123879113@users.noreply.github.com> | 2022-04-13 23:36:52 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-13 16:36:52 +0200 |
commit | 232c10aef1d65140fa383930d70463ee9203ca53 (patch) | |
tree | 1e2f635d10bbc48a6115b02c26e5afce62212ae4 /src/devices/sound | |
parent | c8ab7240564794057997f285cf38b93fa6f55d7e (diff) |
k573dio/k573fpga: Improve counters and status flags (#9554)
Diffstat (limited to 'src/devices/sound')
-rw-r--r-- | src/devices/sound/mas3507d.cpp | 88 | ||||
-rw-r--r-- | src/devices/sound/mas3507d.h | 24 |
2 files changed, 64 insertions, 48 deletions
diff --git a/src/devices/sound/mas3507d.cpp b/src/devices/sound/mas3507d.cpp index bc4131739cd..23693bfa641 100644 --- a/src/devices/sound/mas3507d.cpp +++ b/src/devices/sound/mas3507d.cpp @@ -17,7 +17,7 @@ #define MINIMP3_ONLY_MP3 #define MINIMP3_NO_STDIO #define MINIMP3_IMPLEMENTATION -#define MAX_FRAME_SYNC_MATCHES 1 +#define MAX_FRAME_SYNC_MATCHES 3 #include "minimp3/minimp3.h" #include "minimp3/minimp3_ex.h" @@ -49,7 +49,7 @@ DEFINE_DEVICE_TYPE(MAS3507D, mas3507d_device, "mas3507d", "Micronas MAS 3507D MP mas3507d_device::mas3507d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MAS3507D, tag, owner, clock) , device_sound_interface(mconfig, *this) - , cb_sample(*this) + , cb_mpeg_frame_sync(*this), cb_demand(*this) , i2c_bus_state(IDLE), i2c_bus_address(UNKNOWN), i2c_subdest(UNDEFINED), i2c_command(CMD_BAD) , i2c_scli(false), i2c_sclo(false), i2c_sdai(false), i2c_sdao(false) , i2c_bus_curbit(0), i2c_bus_curval(0), i2c_bytecount(0), i2c_io_bank(0), i2c_io_adr(0), i2c_io_count(0), i2c_io_val(0) @@ -58,9 +58,10 @@ mas3507d_device::mas3507d_device(const machine_config &mconfig, const char *tag, void mas3507d_device::device_start() { - current_rate = 44100; // TODO: related to clock/divider - stream = stream_alloc(0, 2, current_rate); - cb_sample.resolve(); + stream = stream_alloc(0, 2, 44100); + + cb_mpeg_frame_sync.resolve(); + cb_demand.resolve(); save_item(NAME(mp3data)); save_item(NAME(samples)); @@ -74,8 +75,8 @@ void mas3507d_device::device_start() save_item(NAME(i2c_sdao)); save_item(NAME(i2c_bus_curbit)); save_item(NAME(i2c_bus_curval)); + save_item(NAME(mp3data_count)); - save_item(NAME(current_rate)); save_item(NAME(decoded_frame_count)); save_item(NAME(decoded_samples)); save_item(NAME(sample_count)); @@ -90,6 +91,7 @@ void mas3507d_device::device_start() save_item(NAME(i2c_io_val)); save_item(NAME(i2c_sdao_data)); save_item(NAME(playback_status)); + save_item(NAME(mp3_is_buffered)); // This should be removed in the future if/when native MP3 decoding is implemented in MAME save_item(NAME(mp3_dec.mdct_overlap)); @@ -119,6 +121,8 @@ void mas3507d_device::device_reset() is_muted = false; gain_ll = gain_rr = 0; + stream->set_sample_rate(44100); + reset_playback(); } @@ -355,11 +359,11 @@ void mas3507d_device::i2c_device_got_stop() LOGOTHER("MAS I2C: got stop\n"); } -int gain_to_db(double val) { +int mas3507d_device::gain_to_db(double val) { return round(20 * log10((0x100000 - val) / 0x80000)); } -float gain_to_percentage(int val) { +float mas3507d_device::gain_to_percentage(int val) { if(val == 0) return 0; // Special case for muting it seems @@ -425,30 +429,53 @@ void mas3507d_device::run_program(uint32_t adr) } } +void mas3507d_device::sid_w(uint8_t byte) +{ + if (mp3data_count >= mp3data.size()) { + std::copy(mp3data.begin() + 1, mp3data.end(), mp3data.begin()); + mp3data_count--; + } + + mp3data[mp3data_count++] = byte; + + if (!mp3_is_buffered) { + // Only start the decoder when a full MP3 frame is found + int free_format_bytes = 0, frame_size = 0; + int frame_offset = mp3d_find_frame(static_cast<const uint8_t *>(&mp3data[0]), mp3data_count, &free_format_bytes, &frame_size); + mp3_is_buffered = frame_size && frame_offset + frame_size < mp3data_count; + } + + cb_demand(!mp3_is_buffered || mp3data_count < mp3data.size()); +} + void mas3507d_device::fill_buffer() { - while(mp3data_count + 2 < mp3data.size()) { - uint16_t v = cb_sample(); - mp3data[mp3data_count++] = v >> 8; - mp3data[mp3data_count++] = v; + cb_mpeg_frame_sync(0); + + if (!mp3_is_buffered) { + cb_demand(!mp3_is_buffered || mp3data_count < mp3data.size()); + return; } + memset(&mp3_info, 0, sizeof(mp3dec_frame_info_t)); sample_count = mp3dec_decode_frame(&mp3_dec, static_cast<const uint8_t *>(&mp3data[0]), mp3data_count, static_cast<mp3d_sample_t *>(&samples[0]), &mp3_info); samples_idx = 0; - playback_status = PLAYBACK_STATE_BUFFER_FULL; - if(sample_count == 0) + if (sample_count == 0) { + // Frame decode failed + reset_playback(); return; + } std::copy(mp3data.begin() + mp3_info.frame_bytes, mp3data.end(), mp3data.begin()); mp3data_count -= mp3_info.frame_bytes; - if(mp3_info.hz != current_rate) { - current_rate = mp3_info.hz; - stream->set_sample_rate(current_rate); - } + stream->set_sample_rate(mp3_info.hz); decoded_frame_count++; + cb_mpeg_frame_sync(1); + + cb_demand(!mp3_is_buffered || mp3data_count < mp3data.size()); } void mas3507d_device::append_buffer(std::vector<write_stream_view> &outputs, int &pos, int scount) @@ -459,8 +486,6 @@ void mas3507d_device::append_buffer(std::vector<write_stream_view> &outputs, int if(s1 > sample_count) s1 = sample_count; - playback_status = PLAYBACK_STATE_DEMAND_BUFFER; - for(int i = 0; i < s1; i++) { outputs[0].put_int(pos, samples[samples_idx * bytes_per_sample], 32768); outputs[1].put_int(pos, samples[samples_idx * bytes_per_sample + (bytes_per_sample >> 1)], 32768); @@ -478,22 +503,20 @@ void mas3507d_device::append_buffer(std::vector<write_stream_view> &outputs, int void mas3507d_device::reset_playback() { + if (mp3data_count != 0) + std::fill(mp3data.begin(), mp3data.end(), 0); + + if (sample_count != 0 || decoded_samples != 0) + std::fill(samples.begin(), samples.end(), 0); + mp3dec_init(&mp3_dec); mp3data_count = 0; sample_count = 0; decoded_frame_count = 0; decoded_samples = 0; - playback_status = PLAYBACK_STATE_IDLE; - is_started = false; samples_idx = 0; - std::fill(mp3data.begin(), mp3data.end(), 0); - std::fill(samples.begin(), samples.end(), 0); -} -void mas3507d_device::start_playback() -{ - reset_playback(); - is_started = true; + mp3_is_buffered = false; } void mas3507d_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) @@ -502,13 +525,10 @@ void mas3507d_device::sound_stream_update(sound_stream &stream, std::vector<read int pos = 0; while(pos < csamples) { - if(is_started && sample_count == 0) + if(sample_count == 0) fill_buffer(); - if(!is_started || sample_count <= 0) { - playback_status = PLAYBACK_STATE_IDLE; - decoded_frame_count = 0; - decoded_samples = 0; + if(sample_count <= 0) { outputs[0].fill(0, pos); outputs[1].fill(0, pos); return; diff --git a/src/devices/sound/mas3507d.h b/src/devices/sound/mas3507d.h index 36f95de72db..52c2e924109 100644 --- a/src/devices/sound/mas3507d.h +++ b/src/devices/sound/mas3507d.h @@ -12,31 +12,22 @@ class mas3507d_device : public device_t, public device_sound_interface { public: - enum { - PLAYBACK_STATE_IDLE, - PLAYBACK_STATE_BUFFER_FULL, - PLAYBACK_STATE_DEMAND_BUFFER - }; - // construction/destruction mas3507d_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - auto sample_cb() { return cb_sample.bind(); } + auto mpeg_frame_sync_cb() { return cb_mpeg_frame_sync.bind(); } + auto demand_cb() { return cb_demand.bind(); } int i2c_scl_r(); int i2c_sda_r(); void i2c_scl_w(bool line); void i2c_sda_w(bool line); - uint32_t get_samples() const { return decoded_samples; } - uint32_t get_status() const { return playback_status; } + void sid_w(uint8_t byte); void update_stream() { stream->update(); } void reset_playback(); - void start_playback(); - - bool is_started; protected: virtual void device_start() override; @@ -56,7 +47,11 @@ private: void fill_buffer(); void append_buffer(std::vector<write_stream_view> &outputs, int &pos, int scount); - devcb_read16 cb_sample; + int gain_to_db(double val); + float gain_to_percentage(int val); + + devcb_write_line cb_mpeg_frame_sync; + devcb_write_line cb_demand; enum { CMD_DEV_WRITE = 0x3a, @@ -92,7 +87,8 @@ private: uint32_t i2c_io_bank, i2c_io_adr, i2c_io_count, i2c_io_val; uint32_t i2c_sdao_data; - uint32_t mp3data_count, current_rate; + bool mp3_is_buffered; + uint32_t mp3data_count; uint32_t decoded_frame_count, decoded_samples; int32_t sample_count, samples_idx; |