summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/sound.cpp')
-rw-r--r--src/emu/sound.cpp72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index dade6ed3479..696742a87e2 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -637,7 +637,7 @@ void sound_stream::reprime_sync_timer()
u64 next_sample = m_output_buffer.write_sample() + 1;
attotime next_time = sample_to_time(next_sample);
- next_time.m_attoseconds += 1'000'000'000; // Go to the next nanosecond
+ next_time.m_attoseconds += 1'000'000'000; // Go to the next nanosecond '
m_sync_timer->adjust(next_time - m_device.machine().time());
}
@@ -844,13 +844,8 @@ void sound_manager::after_devices_init()
m_record_buffer.resize(m_outputs_count * machine().sample_rate(), 0);
m_record_samples = 0;
- // Have all streams create their initial resamplers
- for(auto &stream : m_stream_list)
- stream->create_resamplers();
-
- // Then get the initial history sizes
- for(auto &stream : m_stream_list)
- stream->lookup_history_sizes();
+ // Create resamplers and setup history
+ rebuild_all_resamplers();
m_effects_done = false;
@@ -917,6 +912,7 @@ void sound_manager::output_push(int id, sound_stream &stream)
*outb1 = std::clamp(int(*inb++ * 32768), -32768, 32767);
outb1 += m_outputs_count;
}
+ outb++;
}
}
@@ -1122,11 +1118,24 @@ void sound_manager::config_load(config_type cfg_type, config_level cfg_level, ut
// In the global config, get the default effect chain configuration
util::xml::data_node const *efl_node = parentnode->get_child("default_audio_effects");
- for(util::xml::data_node const *ef_node = efl_node->get_child("effect"); ef_node != nullptr; ef_node = ef_node->get_next_sibling("effect")) {
- unsigned int id = ef_node->get_attribute_int("step", 0);
- std::string type = ef_node->get_attribute_string("type", "");
- if(id >= 1 && id <= m_default_effects.size() && audio_effect::effect_names[m_default_effects[id-1]->type()] == type)
- m_default_effects[id-1]->config_load(ef_node);
+ if(efl_node) {
+ for(util::xml::data_node const *ef_node = efl_node->get_child("effect"); ef_node != nullptr; ef_node = ef_node->get_next_sibling("effect")) {
+ unsigned int id = ef_node->get_attribute_int("step", 0);
+ std::string type = ef_node->get_attribute_string("type", "");
+ if(id >= 1 && id <= m_default_effects.size() && audio_effect::effect_names[m_default_effects[id-1]->type()] == type)
+ m_default_effects[id-1]->config_load(ef_node);
+ }
+ }
+
+ // and the resampler configuration
+ util::xml::data_node const *rs_node = parentnode->get_child("resampler");
+ if(rs_node) {
+ m_resampler_hq_latency = rs_node->get_attribute_float("hq_latency", 0.0050);
+ m_resampler_hq_length = rs_node->get_attribute_int("hq_length", 400);
+ m_resampler_hq_phases = rs_node->get_attribute_int("hq_phases", 200);
+
+ // this also applies the hq settings if resampler is hq
+ set_resampler_type(rs_node->get_attribute_int("type", RESAMPLER_LOFI));
}
break;
}
@@ -1217,6 +1226,12 @@ void sound_manager::config_save(config_type cfg_type, util::xml::data_node *pare
ef_node->set_attribute("type", audio_effect::effect_names[e->type()]);
e->config_save(ef_node);
}
+
+ util::xml::data_node *const rs_node = parentnode->add_child("resampler", nullptr);
+ rs_node->set_attribute_int("type", m_resampler_type);
+ rs_node->set_attribute_float("hq_latency", m_resampler_hq_latency);
+ rs_node->set_attribute_int("hq_length", m_resampler_hq_length);
+ rs_node->set_attribute_int("hq_phases", m_resampler_hq_phases);
break;
}
@@ -2396,7 +2411,7 @@ void sound_manager::mapping_update()
u64 sound_manager::rate_and_time_to_index(attotime time, u32 sample_rate) const
{
- return time.m_seconds * sample_rate + ((time.m_attoseconds / 100'000'000) * sample_rate) / 10'000'000'000LL;
+ return time.m_seconds * sample_rate + ((time.m_attoseconds / 100'000'000) * sample_rate) / 10'000'000'000LL; //'
}
void sound_manager::update(s32)
@@ -2462,7 +2477,7 @@ void sound_manager::streams_update()
machine().osd().add_audio_to_recording(m_record_buffer.data(), m_record_samples);
machine().video().add_sound_to_recording(m_record_buffer.data(), m_record_samples);
if(m_wavfile)
- util::wav_add_data_16(*m_wavfile, m_record_buffer.data(), m_record_samples);
+ util::wav_add_data_16(*m_wavfile, m_record_buffer.data(), m_record_samples * m_outputs_count);
m_effects_condition.notify_all();
}
@@ -2474,6 +2489,7 @@ const audio_resampler *sound_manager::get_resampler(u32 fs, u32 ft)
auto i = m_resamplers.find(key);
if(i != m_resamplers.end())
return i->second.get();
+
audio_resampler *res;
if(m_resampler_type == RESAMPLER_HQ)
res = new audio_resampler_hq(fs, ft, m_resampler_hq_latency, m_resampler_hq_length, m_resampler_hq_phases);
@@ -2491,31 +2507,39 @@ void sound_manager::rebuild_all_resamplers()
stream->create_resamplers();
for(auto &stream : m_stream_list)
- stream->lookup_history_sizes();
+ stream->lookup_history_sizes();
}
void sound_manager::set_resampler_type(u32 type)
{
- m_resampler_type = type;
- rebuild_all_resamplers();
+ if(type != m_resampler_type) {
+ m_resampler_type = type;
+ rebuild_all_resamplers();
+ }
}
void sound_manager::set_resampler_hq_latency(double latency)
{
- m_resampler_hq_latency = latency;
- rebuild_all_resamplers();
+ if(latency != m_resampler_hq_latency) {
+ m_resampler_hq_latency = latency;
+ rebuild_all_resamplers();
+ }
}
void sound_manager::set_resampler_hq_length(u32 length)
{
- m_resampler_hq_length = length;
- rebuild_all_resamplers();
+ if(length != m_resampler_hq_length) {
+ m_resampler_hq_length = length;
+ rebuild_all_resamplers();
+ }
}
void sound_manager::set_resampler_hq_phases(u32 phases)
{
- m_resampler_hq_phases = phases;
- rebuild_all_resamplers();
+ if(phases != m_resampler_hq_phases) {
+ m_resampler_hq_phases = phases;
+ rebuild_all_resamplers();
+ }
}
const char *sound_manager::resampler_type_names(u32 type) const