Almost glitch free speaker

This commit is contained in:
tudnai 2022-06-25 19:11:33 -07:00
parent 6ea84d85e1
commit 985c5840ac
2 changed files with 130 additions and 81 deletions

View File

@ -45,7 +45,7 @@
contextName = "spkr_toggle:speaker.c">
<PersistentStrings>
<PersistentString
value = "spkr_samples[spkr_sample_last_idx]">
value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2">
</PersistentString>
<PersistentString
value = "(int16_t)28000 + (int16_t)-32768">
@ -63,7 +63,7 @@
value = "( (spkr_clk + m6502.clkfrm) / ( default_MHz_6502 * 1000 * 1000 / spkr_sample_rate)) * 2">
</PersistentString>
<PersistentString
value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2">
value = "spkr_samples[spkr_sample_last_idx]">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -152,7 +152,7 @@
contextName = "closure #1 in ViewController.Update():ViewController.swift">
<PersistentStrings>
<PersistentString
value = "MEMcfg.is_80STORE">
value = "txtArr">
</PersistentString>
<PersistentString
value = "self.shadowTxt">
@ -161,10 +161,10 @@
value = "txt">
</PersistentString>
<PersistentString
value = "MEMcfg.txt_page_2">
value = "MEMcfg.is_80STORE">
</PersistentString>
<PersistentString
value = "txtArr">
value = "MEMcfg.txt_page_2">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -270,7 +270,7 @@
contextName = "LoRes.Update():LoRes.swift">
<PersistentStrings>
<PersistentString
value = "UInt8( (block &gt;&gt; 4) &amp; 0x0F )">
value = "blockChanged[ screenIdx ]">
</PersistentString>
<PersistentString
value = "UInt8(block)">
@ -279,7 +279,7 @@
value = "UInt8(block &amp; 4)">
</PersistentString>
<PersistentString
value = "blockChanged[ screenIdx ]">
value = "UInt8( (block &gt;&gt; 4) &amp; 0x0F )">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -304,13 +304,13 @@
contextName = "auxMemorySelect:mmio.c">
<PersistentStrings>
<PersistentString
value = "newReadMEM == Apple2_64K_MEM + 0x200">
value = "newReadMEM == Apple2_64K_RAM + 0x200">
</PersistentString>
<PersistentString
value = "newReadMEM == currentLowRDMEM">
</PersistentString>
<PersistentString
value = "newReadMEM == Apple2_64K_RAM + 0x200">
value = "newReadMEM == Apple2_64K_MEM + 0x200">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -394,13 +394,10 @@
</PersistentStrings>
</ContextState>
<ContextState
contextName = "CPY:6502_instr_compare_test.h">
contextName = "ViewController.extraBuf(_:):ViewController.swift">
<PersistentStrings>
<PersistentString
value = "m6502.Y">
</PersistentString>
<PersistentString
value = "(int)m6502.Y - imm">
value = "soundGapLabel">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -422,10 +419,13 @@
</PersistentStrings>
</ContextState>
<ContextState
contextName = "ViewController.extraBuf(_:):ViewController.swift">
contextName = "CPY:6502_instr_compare_test.h">
<PersistentStrings>
<PersistentString
value = "soundGapLabel">
value = "m6502.Y">
</PersistentString>
<PersistentString
value = "(int)m6502.Y - imm">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -460,6 +460,14 @@
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "ViewController.Pause(_:):ViewController.swift">
<PersistentStrings>
<PersistentString
value = "upd">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "spkr_playUpd:speaker.c">
</ContextState>
@ -528,13 +536,13 @@
contextName = "HiRes.compute():HiRes.swift">
<PersistentStrings>
<PersistentString
value = "UnsafeRawBufferPointer(result)">
value = "computePipelineState.maxTotalThreadsPerThreadgroup">
</PersistentString>
<PersistentString
value = "result[2]">
</PersistentString>
<PersistentString
value = "computePipelineState.maxTotalThreadsPerThreadgroup">
value = "UnsafeRawBufferPointer(result)">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -593,7 +601,7 @@
value = "new">
</PersistentString>
<PersistentString
value = "WOZtmp.shift16">
value = "WOZwrite.shift16">
</PersistentString>
<PersistentString
value = "WOZwrite.shift">
@ -605,7 +613,7 @@
value = "(1 &lt;&lt; i) - 1">
</PersistentString>
<PersistentString
value = "WOZwrite.shift16">
value = "WOZtmp.shift16">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -754,10 +762,10 @@
contextName = "set_flags_NZC:common.h">
<PersistentStrings>
<PersistentString
value = "(unsigned)0xFF">
value = "(unsigned)test ">
</PersistentString>
<PersistentString
value = "(unsigned)test ">
value = "(unsigned)0xFF">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -765,10 +773,10 @@
contextName = "HiRes.draw(_:):HiRes.swift">
<PersistentStrings>
<PersistentString
value = "ctx?.bitsPerComponent">
value = "linAddr">
</PersistentString>
<PersistentString
value = "ctx?.data">
value = "ctx?.height">
</PersistentString>
<PersistentString
value = "ctx?.width">
@ -791,14 +799,14 @@
<PersistentString
value = "(blockH7 | ( block &amp; bitMask ))">
</PersistentString>
<PersistentString
value = "ctx?.bitsPerComponent">
</PersistentString>
<PersistentString
value = "HiRes.blockCols">
</PersistentString>
<PersistentString
value = "linAddr">
</PersistentString>
<PersistentString
value = "ctx?.height">
value = "ctx?.data">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -823,7 +831,7 @@
value = "textDisplay_height_diff">
</PersistentString>
<PersistentString
value = "textDisplay_width_diff">
value = "textDisplay.frame">
</PersistentString>
<PersistentString
value = "textDisplay.bounds">
@ -832,10 +840,10 @@
value = "MonitorView.textViewBounds">
</PersistentString>
<PersistentString
value = "frame.size">
value = "textDisplay_width_diff">
</PersistentString>
<PersistentString
value = "textDisplay.frame">
value = "frame.size">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -845,6 +853,9 @@
<PersistentString
value = "m6502">
</PersistentString>
<PersistentString
value = "(void*)Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "Apple2_64K_AUX + 0x3600">
</PersistentString>
@ -854,9 +865,6 @@
<PersistentString
value = "Apple2_64K_RAM + 0x3600">
</PersistentString>
<PersistentString
value = "(void*)Apple2_64K_RAM">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
@ -969,7 +977,7 @@
value = "pdl_value[pdl]">
</PersistentString>
<PersistentString
value = "normalized_time">
value = "normalized_time &gt;= pdl_value[pdl] ? 255 : 0">
</PersistentString>
<PersistentString
value = "(3300 * 255/3300)">
@ -981,7 +989,7 @@
value = "1 * 512 * (1 - ( 3300 / 3300.0 ))">
</PersistentString>
<PersistentString
value = "normalized_time &gt;= pdl_value[pdl] ? 255 : 0">
value = "normalized_time">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1052,10 +1060,10 @@
value = "Apple2_64K_AUX + 0xC600">
</PersistentString>
<PersistentString
value = "Apple2_64K_RAM + 0xC600">
value = "(void*)rom">
</PersistentString>
<PersistentString
value = "(void*)rom">
value = "Apple2_64K_RAM + 0xC600">
</PersistentString>
<PersistentString
value = "strlen(fullPath)">

View File

@ -457,28 +457,30 @@ void spkr_exit() {
char spkr_state = 0;
// Exponential Moving Average
INLINE int ema( int val, int prev, float ema_len ) {
static const float ema_sensitivity = 2;
// static const float ema_len = 42;
float m = ema_sensitivity / ema_len;
float n = 1 - m;
return m * val + n * prev;
#define _NO_SPKR_EARLY_ZERO_LEVEL 500
INLINE void spkr_finish_square(const unsigned new_idx) {
// only fill small enough gaps and larger ones will go back to 0
#ifdef SPKR_EARLY_ZERO_LEVEL
if ( (new_idx - spkr_sample_last_idx) < SPKR_EARLY_ZERO_LEVEL ) {
#endif
// finish the aquare wave
while ( spkr_sample_last_idx < new_idx ) {
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level;
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level; // stereo
}
#ifdef SPKR_EARLY_ZERO_LEVEL
}
else {
spkr_sample_last_idx = new_idx;
spkr_level = 0;
}
#endif
}
void spkr_toggle_square ( int level_max, const unsigned idx_diff ) {
// finish the aquare wave
while ( spkr_sample_last_idx < spkr_sample_idx ) {
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level;
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level; // stereo
}
// start a new speaker level -- it might not be necessary, but...
// spkr_samples[ spkr_sample_idx++ ] = level_max;
// spkr_samples[ spkr_sample_idx++ ] = level_max; // stereo
INLINE void spkr_toggle_square ( const int level_max ) {
spkr_finish_square(spkr_sample_idx);
spkr_level = level_max;
}
@ -549,14 +551,14 @@ void spkr_toggle() {
spkr_state = 0;
// spkr_toggle_tick(SPKR_LEVEL_MIN, spkr_sample_idx_diff);
spkr_toggle_square(SPKR_LEVEL_MIN, spkr_sample_idx_diff);
spkr_toggle_square(SPKR_LEVEL_MIN);
}
else {
// up edge
spkr_state = 1;
// spkr_toggle_tick(SPKR_LEVEL_MAX, spkr_sample_idx_diff);
spkr_toggle_square(SPKR_LEVEL_MAX, spkr_sample_idx_diff);
spkr_toggle_square(SPKR_LEVEL_MAX);
}
//spkr_samples[sample_idx] = spkr_level;
@ -579,25 +581,33 @@ INLINE static void spkr_filter_reset() {
}
INLINE static void spkr_filter(int buf_len) {
// Exponential Moving Average
INLINE int ema( int val, int prev, float ema_len ) {
static const float ema_sensitivity = 2;
// static const float ema_len = 42;
float m = ema_sensitivity / ema_len;
float n = 1 - m;
return m * val + n * prev;
}
// Debug SPKR Buffer Before EMA
spkr_debug(spkr_debug_raw_file);
INLINE static void spkr_filter_ema(int buf_len) {
// to use with EMA
// static const int ema_len_sharper = 30;
// static const int ema_len_soft = 70;
// static const int ema_len_supersoft = 200;
// static const int ema_len_sharper = 30;
// static const int ema_len_soft = 70;
// static const int ema_len_supersoft = 200;
// to use with TEMA
// static const int ema_len_sharper = 7;
// static const int ema_len_sharp = 14;
// static const int ema_len_normal = 18;
// static const int ema_len_soft = 20;
// static const int ema_len_supersoft = 40;
//
// static const int ema_len = ema_len_soft;
// static const int ema_len_sharper = 7;
// static const int ema_len_sharp = 14;
// static const int ema_len_normal = 18;
// static const int ema_len_soft = 20;
// static const int ema_len_supersoft = 40;
//
// static const int ema_len = ema_len_soft;
for ( int i = 0; i < spkr_buf_size; ) {
spkr_level_ema = ema(spkr_samples[i], spkr_level_ema, spkr_ema_len);
spkr_level_dema = ema(spkr_level_ema, spkr_level_dema, spkr_ema_len);
@ -607,9 +617,42 @@ INLINE static void spkr_filter(int buf_len) {
spkr_samples[i++] = spkr_level_tema;
spkr_samples[i++] = spkr_level_tema;
}
// Debug SPKR Buffer After EMA
spkr_debug(spkr_debug_ema_file);
// spkr_level = spkr_level_tema;
}
INLINE static void spkr_filter_sma(int buf_len) {
static const unsigned sma_len = 35;
static spkr_sample_t sma_buf [ sma_len ] = {0};
static int64_t sum = 0;
for ( int i = 0; i < spkr_buf_size; ) {
// before we feed the value, remove the one that comes out
sum -= sma_buf[0];
// move array down
memcpy(sma_buf, sma_buf + sizeof(spkr_sample_t), (sma_len - 1) * sizeof(spkr_sample_t));
// add new value
sma_buf[sma_len - 1] = spkr_samples[i];
sum += spkr_samples[i];
// calculate average
spkr_sample_t spkr_level = (int)(sum / sma_len);
spkr_samples[i++] = spkr_level;
spkr_samples[i++] = spkr_level;
}
}
INLINE static void spkr_filter(int buf_len) {
// Debug SPKR Buffer Before filters
spkr_debug(spkr_debug_raw_file);
spkr_filter_ema(buf_len);
// spkr_filter_sma(buf_len);
}
@ -795,15 +838,16 @@ void spkr_update() {
// Need to Cool Down Speaker -- Soft Fade to Zero
else {
spkr_fade(spkr_level);
spkr_fade(spkr_level_tema);
spkr_filter(SPKR_SLOT_SIZE(1));
#ifdef SPKR_DEBUG
spkr_debug(spkr_debug_raw_file);
spkr_debug(spkr_debug_ema_file);
#endif
spkr_buffer_with_pause(SPKR_SLOT_SIZE(1));
}
@ -833,10 +877,7 @@ void spkr_update() {
// Normal Sound Buffer Feed
else {
// finish the aquare wave
while ( spkr_sample_last_idx < spkr_buf_size ) {
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level;
spkr_samples[ spkr_sample_last_idx++ ] = spkr_level; // stereo
}
spkr_finish_square(spkr_buf_size);
const int buf_len = round((double)spkr_buf_size + spkr_extra_buf) * sizeof(spkr_sample_t);