From ad19b6504be279ba0c777e2e1601e317a9096ddb Mon Sep 17 00:00:00 2001 From: tudnai Date: Sat, 27 Jun 2020 20:29:53 -0700 Subject: [PATCH] - Speaker quality improvements - Initial steps for WOZ2 format --- src/dev/audio/speaker.c | 42 +++++++++++++++++++++++------------------ src/dev/audio/speaker.h | 8 ++++++-- src/dev/disk/woz.c | 16 ++++++++-------- src/dev/disk/woz.h | 32 ++++++++++++++++++++++++++----- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/dev/audio/speaker.c b/src/dev/audio/speaker.c index 58227c4..e4dc202 100644 --- a/src/dev/audio/speaker.c +++ b/src/dev/audio/speaker.c @@ -244,13 +244,15 @@ void spkr_init() { int spkr_unqueue( ALuint src ) { ALint processed = 0; - alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed ); - al_check_error(); - printf("%s alGetSourcei(%d)\n", __FUNCTION__, src); - - if ( processed ) { - alSourceUnqueueBuffers( src, processed, &spkr_buffers[freeBuffers]); + if ( src ) { + alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed ); al_check_error(); + // printf("%s alGetSourcei(%d)\n", __FUNCTION__, src); + + if ( processed ) { + alSourceUnqueueBuffers( src, processed, &spkr_buffers[freeBuffers]); + al_check_error(); + } } return processed; @@ -322,20 +324,23 @@ void spkr_toggle() { // (we will play the entire buffer at the end of the frame) spkr_sample_idx = ( (spkr_clk + clkfrm) / ( MHZ(default_MHz_6502) / spkr_sample_rate)) * SPKR_CHANNELS; + spkr_level = spkr_samples[ spkr_sample_idx ]; + if ( spkr_state ) { // down edge spkr_state = 0; - float fadeLevel = spkr_level - SPKR_LEVEL_MIN; - - while ( fadeLevel > +1 ) { - spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel; - spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel; // stereo + float dumping = spkr_level - SPKR_LEVEL_MIN; + dumping *= SPKR_INITIAL_DUMPING; + + while ( dumping > 1 ) { + spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + dumping; + spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + dumping; // stereo // how smooth we want the speeker to decay, so we will hear no pops and crackles // 0.9 gives you a kind of saw wave at 1KHz (beep) // 0.7 is better, but Xonix gives you a bit distorted speech and Donkey Kong does not sound the same - fadeLevel *= 0.16; + dumping *= SPKR_FADE_TRAILING_EDGE; } spkr_level = SPKR_LEVEL_MIN; } @@ -343,16 +348,17 @@ void spkr_toggle() { // up edge spkr_state = 1; - float fadeLevel = spkr_level - SPKR_LEVEL_MAX; - - while ( fadeLevel < -1 ) { - spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel; - spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel; // stereo + float dumping = spkr_level - SPKR_LEVEL_MAX; + dumping *= SPKR_INITIAL_DUMPING; + + while ( dumping < -1 ) { + spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + dumping; + spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + dumping; // stereo // how smooth we want the speeker to decay, so we will hear no pops and crackles // 0.9 gives you a kind of saw wave at 1KHz (beep) // 0.7 is better, but Xonix gives you a bit distorted speech and Donkey Kong does not sound the same - fadeLevel *= 0.32; + dumping *= SPKR_FADE_LEADING_EDGE; } spkr_level = SPKR_LEVEL_MAX; } diff --git a/src/dev/audio/speaker.h b/src/dev/audio/speaker.h index b7f3024..af7f81f 100644 --- a/src/dev/audio/speaker.h +++ b/src/dev/audio/speaker.h @@ -22,8 +22,12 @@ //#define SPKR_LEVEL_MAX (+5000) // medium -#define SPKR_LEVEL_MIN (-3000) -#define SPKR_LEVEL_MAX (+3000) +#define SPKR_LEVEL_MIN (-3072) +#define SPKR_LEVEL_MAX (+3072) + +#define SPKR_FADE_LEADING_EDGE 0.32 +#define SPKR_FADE_TRAILING_EDGE 0.16 +#define SPKR_INITIAL_DUMPING 0.86 // quiet //#define SPKR_LEVEL_MIN (-1000) diff --git a/src/dev/disk/woz.c b/src/dev/disk/woz.c index 4f206af..ac221d7 100644 --- a/src/dev/disk/woz.c +++ b/src/dev/disk/woz.c @@ -32,7 +32,7 @@ uint8_t * woz_file_buffer = NULL; woz_header_t * woz_header; woz_chunk_header_t * woz_chunk_header; woz_tmap_t * woz_tmap; -woz_trks_t * woz_trks; +woz1_trks_t * woz_trks; int track_loaded = -1; @@ -49,7 +49,7 @@ typedef union trackEntry_u { #pragma pack(pop) -trackEntry_t prepared_track[WOZ_TRACK_BYTE_COUNT]; +trackEntry_t prepared_track[WOZ1_TRACK_BYTE_COUNT]; typedef enum readState_e { readNormal = 0, @@ -67,7 +67,7 @@ void woz_loadTrack_old( int track ) { reg.data = (*woz_trks)[track].data[1]; prepared_track[0] = reg; - for ( int offs = 1; offs < WOZ_TRACK_BYTE_COUNT; offs++ ) { + for ( int offs = 1; offs < WOZ1_TRACK_BYTE_COUNT; offs++ ) { for ( int i = 0; i < 8; i++ ) { if (reg.shift & 0x80) { @@ -77,7 +77,7 @@ void woz_loadTrack_old( int track ) { reg.shift16 <<= 1; } - reg.data = (*woz_trks)[track].data[ (offs + 1) % WOZ_TRACK_BYTE_COUNT ]; + reg.data = (*woz_trks)[track].data[ (offs + 1) % WOZ1_TRACK_BYTE_COUNT ]; prepared_track[offs] = reg; } } @@ -199,7 +199,7 @@ void woz_loadTrack( int track ) { int bitOffs = 0; - for ( int byteOffs = 0; byteOffs < WOZ_TRACK_BYTE_COUNT; byteOffs++ ) { + for ( int byteOffs = 0; byteOffs < WOZ1_TRACK_BYTE_COUNT; byteOffs++ ) { reg.data = (*woz_trks)[track].data[ byteOffs ]; @@ -236,7 +236,7 @@ uint8_t woz_read() { const int clkBeforeAdjusting = 512; const int magicShiftOffset = 45; - uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ_TRACK_BYTE_COUNT; + uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ1_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ1_TRACK_BYTE_COUNT; if ( usedBytes ) { int shiftOffset = magicShiftOffset; @@ -375,7 +375,7 @@ void woz_write( uint8_t data ) { clkelpased = m6502.clktime + clkfrm - m6502.clklast; m6502.clklast = m6502.clktime + clkfrm; - uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ_TRACK_BYTE_COUNT; + uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ1_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ1_TRACK_BYTE_COUNT; if ( usedBytes ) { @@ -555,7 +555,7 @@ int woz_loadFile( const char * filename ) { break; case WOZ_TRKS_CHUNK_ID: - woz_trks = (woz_trks_t*) &woz_file_buffer[bufOffs]; + woz_trks = (woz1_trks_t*) &woz_file_buffer[bufOffs]; break; case WOZ_META_CHUNK_ID: diff --git a/src/dev/disk/woz.h b/src/dev/disk/woz.h index a1e69a1..db5fdc1 100644 --- a/src/dev/disk/woz.h +++ b/src/dev/disk/woz.h @@ -95,22 +95,44 @@ typedef struct woz_tmap_s { uint8_t phase [DISKII_MAXTRACKS * DISKII_PHASES]; } woz_tmap_t; -#define WOZ_TRACK_BYTE_COUNT 6646 +#define WOZ1_TRACK_BYTE_COUNT 6646 +#define WOZ2_TRACK_BYTE_COUNT 6680 + // chunk data only -typedef struct woz_track_s { - uint8_t data [WOZ_TRACK_BYTE_COUNT]; +typedef struct woz1_track_s { + uint8_t data [WOZ1_TRACK_BYTE_COUNT]; uint16_t bytes_used; uint16_t bit_count; uint16_t splice_point; uint8_t splice_nibble; uint8_t splice_bit_count; uint16_t reserved; -} woz_track_t; +} woz1_track_t; +typedef struct woz2_trk_s { + uint16_t starting_block; // First block of BITS data. This value is relative to the start of the file, + // so the first possible starting block is 3. Multiply this value by 512 (x << 9) + // to get the starting byte of the BITS data + uint16_t block_count; // Number of blocks for this BITS data + uint32_t bit_count; // The number of bits in the bitstream +} woz2_trk_t; + +#define WOZ_MAX_TRK 160 + +typedef struct woz2_track_s { + uint8_t trks [WOZ_MAX_TRK]; + uint16_t bytes_used; + uint16_t bit_count; + uint16_t splice_point; + uint8_t splice_nibble; + uint8_t splice_bit_count; + uint16_t reserved; +} woz2_track_t; + // chunk data only -typedef woz_track_t woz_trks_t[DISKII_MAXTRACKS]; +typedef woz1_track_t woz1_trks_t[DISKII_MAXTRACKS]; #pragma pack(pop)