- 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,14 +244,16 @@ void spkr_init() {
int spkr_unqueue( ALuint src ) {
ALint processed = 0;
if ( src ) {
alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed );
al_check_error();
printf("%s alGetSourcei(%d)\n", __FUNCTION__, src);
// 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;
float dumping = spkr_level - SPKR_LEVEL_MIN;
dumping *= SPKR_INITIAL_DUMPING;
while ( fadeLevel > +1 ) {
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel;
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MIN + fadeLevel; // stereo
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;
float dumping = spkr_level - SPKR_LEVEL_MAX;
dumping *= SPKR_INITIAL_DUMPING;
while ( fadeLevel < -1 ) {
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel;
spkr_samples[ spkr_sample_idx++ ] = SPKR_LEVEL_MAX + fadeLevel; // stereo
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;
}

View File

@ -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)

View File

@ -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:

View File

@ -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)