- Speaker quality improvements

- Initial steps for WOZ2 format
This commit is contained in:
tudnai 2020-06-27 20:29:53 -07:00
parent cb498c415c
commit ad19b6504b
4 changed files with 65 additions and 33 deletions

View File

@ -244,13 +244,15 @@ void spkr_init() {
int spkr_unqueue( ALuint src ) { int spkr_unqueue( ALuint src ) {
ALint processed = 0; ALint processed = 0;
alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed ); if ( src ) {
al_check_error(); alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed );
printf("%s alGetSourcei(%d)\n", __FUNCTION__, src);
if ( processed ) {
alSourceUnqueueBuffers( src, processed, &spkr_buffers[freeBuffers]);
al_check_error(); al_check_error();
// printf("%s alGetSourcei(%d)\n", __FUNCTION__, src);
if ( processed ) {
alSourceUnqueueBuffers( src, processed, &spkr_buffers[freeBuffers]);
al_check_error();
}
} }
return processed; return processed;
@ -322,20 +324,23 @@ void spkr_toggle() {
// (we will play the entire buffer at the end of the frame) // (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_sample_idx = ( (spkr_clk + clkfrm) / ( MHZ(default_MHz_6502) / spkr_sample_rate)) * SPKR_CHANNELS;
spkr_level = spkr_samples[ spkr_sample_idx ];
if ( spkr_state ) { if ( spkr_state ) {
// down edge // down edge
spkr_state = 0; spkr_state = 0;
float fadeLevel = spkr_level - SPKR_LEVEL_MIN; float dumping = spkr_level - SPKR_LEVEL_MIN;
dumping *= SPKR_INITIAL_DUMPING;
while ( fadeLevel > +1 ) { while ( dumping > 1 ) {
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel; spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + dumping;
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel; // stereo 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 // 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.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 // 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; spkr_level = SPKR_LEVEL_MIN;
} }
@ -343,16 +348,17 @@ void spkr_toggle() {
// up edge // up edge
spkr_state = 1; spkr_state = 1;
float fadeLevel = spkr_level - SPKR_LEVEL_MAX; float dumping = spkr_level - SPKR_LEVEL_MAX;
dumping *= SPKR_INITIAL_DUMPING;
while ( fadeLevel < -1 ) { while ( dumping < -1 ) {
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel; spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + dumping;
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel; // stereo 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 // 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.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 // 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; spkr_level = SPKR_LEVEL_MAX;
} }

View File

@ -22,8 +22,12 @@
//#define SPKR_LEVEL_MAX (+5000) //#define SPKR_LEVEL_MAX (+5000)
// medium // medium
#define SPKR_LEVEL_MIN (-3000) #define SPKR_LEVEL_MIN (-3072)
#define SPKR_LEVEL_MAX (+3000) #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 // quiet
//#define SPKR_LEVEL_MIN (-1000) //#define SPKR_LEVEL_MIN (-1000)

View File

@ -32,7 +32,7 @@ uint8_t * woz_file_buffer = NULL;
woz_header_t * woz_header; woz_header_t * woz_header;
woz_chunk_header_t * woz_chunk_header; woz_chunk_header_t * woz_chunk_header;
woz_tmap_t * woz_tmap; woz_tmap_t * woz_tmap;
woz_trks_t * woz_trks; woz1_trks_t * woz_trks;
int track_loaded = -1; int track_loaded = -1;
@ -49,7 +49,7 @@ typedef union trackEntry_u {
#pragma pack(pop) #pragma pack(pop)
trackEntry_t prepared_track[WOZ_TRACK_BYTE_COUNT]; trackEntry_t prepared_track[WOZ1_TRACK_BYTE_COUNT];
typedef enum readState_e { typedef enum readState_e {
readNormal = 0, readNormal = 0,
@ -67,7 +67,7 @@ void woz_loadTrack_old( int track ) {
reg.data = (*woz_trks)[track].data[1]; reg.data = (*woz_trks)[track].data[1];
prepared_track[0] = reg; 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++ ) { for ( int i = 0; i < 8; i++ ) {
if (reg.shift & 0x80) { if (reg.shift & 0x80) {
@ -77,7 +77,7 @@ void woz_loadTrack_old( int track ) {
reg.shift16 <<= 1; 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; prepared_track[offs] = reg;
} }
} }
@ -199,7 +199,7 @@ void woz_loadTrack( int track ) {
int bitOffs = 0; 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 ]; reg.data = (*woz_trks)[track].data[ byteOffs ];
@ -236,7 +236,7 @@ uint8_t woz_read() {
const int clkBeforeAdjusting = 512; const int clkBeforeAdjusting = 512;
const int magicShiftOffset = 45; 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 ) { if ( usedBytes ) {
int shiftOffset = magicShiftOffset; int shiftOffset = magicShiftOffset;
@ -375,7 +375,7 @@ void woz_write( uint8_t data ) {
clkelpased = m6502.clktime + clkfrm - m6502.clklast; clkelpased = m6502.clktime + clkfrm - m6502.clklast;
m6502.clklast = m6502.clktime + clkfrm; 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 ) { if ( usedBytes ) {
@ -555,7 +555,7 @@ int woz_loadFile( const char * filename ) {
break; break;
case WOZ_TRKS_CHUNK_ID: case WOZ_TRKS_CHUNK_ID:
woz_trks = (woz_trks_t*) &woz_file_buffer[bufOffs]; woz_trks = (woz1_trks_t*) &woz_file_buffer[bufOffs];
break; break;
case WOZ_META_CHUNK_ID: case WOZ_META_CHUNK_ID:

View File

@ -95,22 +95,44 @@ typedef struct woz_tmap_s {
uint8_t phase [DISKII_MAXTRACKS * DISKII_PHASES]; uint8_t phase [DISKII_MAXTRACKS * DISKII_PHASES];
} woz_tmap_t; } woz_tmap_t;
#define WOZ_TRACK_BYTE_COUNT 6646 #define WOZ1_TRACK_BYTE_COUNT 6646
#define WOZ2_TRACK_BYTE_COUNT 6680
// chunk data only // chunk data only
typedef struct woz_track_s { typedef struct woz1_track_s {
uint8_t data [WOZ_TRACK_BYTE_COUNT]; uint8_t data [WOZ1_TRACK_BYTE_COUNT];
uint16_t bytes_used; uint16_t bytes_used;
uint16_t bit_count; uint16_t bit_count;
uint16_t splice_point; uint16_t splice_point;
uint8_t splice_nibble; uint8_t splice_nibble;
uint8_t splice_bit_count; uint8_t splice_bit_count;
uint16_t reserved; 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 // chunk data only
typedef woz_track_t woz_trks_t[DISKII_MAXTRACKS]; typedef woz1_track_t woz1_trks_t[DISKII_MAXTRACKS];
#pragma pack(pop) #pragma pack(pop)