]> Shamusworld >> Repos - apple2/commitdiff
More work on sound.cpp, especially definition of time constants
authorShamus Hammons <jlhamm@acm.org>
Mon, 19 Jan 2009 20:00:34 +0000 (20:00 +0000)
committerShamus Hammons <jlhamm@acm.org>
Mon, 19 Jan 2009 20:00:34 +0000 (20:00 +0000)
apple2.cfg
src/apple2.cpp
src/sound.cpp

index 5ee931d0347e38a04436c63e8e4527a4641bbd2d..ee5cc6b00570dee40e3b267c4b8f6bbb8dbbd951 100755 (executable)
@@ -21,9 +21,9 @@ autoSaveState = 1
 #floppyImage1 = ./disks/temp.nib
 #floppyImage1 = ./disks/temp.dsk
 # Yes
-floppyImage1 = ./disks/bt1_boot.dsk
+#floppyImage1 = ./disks/bt1_boot.dsk
 # Yes
-#floppyImage1 = ./disks/bt2_boot.dsk
+floppyImage1 = ./disks/bt2_boot.dsk
 # No (gets stuck on 1st track)
 #floppyImage1 = ./disks/bt3_boot.dsk
 # Yes
index 729dc23cc80206dbeee31fad906e592e3b5bcd70..f50454d35678757cf8495c3b84bb2bd60ccb21d2 100755 (executable)
@@ -163,6 +163,23 @@ if (addr >= 0xC080 && addr <= 0xC08F)
        }
        else if ((addr & 0xFFF0) == 0xC030)
        {
+/*
+This is problematic, mainly because the v65C02 removes actual cycles run after each call.
+Therefore, we don't really have a reliable method of sending a timestamp to the sound routine.
+How to fix?
+
+What we need to send is a delta T value but related to the IRQ buffer routine. E.g., if the buffer
+hasn't had any changes in it then we just fill it with the last sample value and are done. Then
+we need to adjust our delta T accordingly. What we could do is keep a running total of time since the
+last change and adjust it accordingly, i.e., whenever a sound IRQ happens.
+How to keep track?
+
+Have deltaT somewhere. Then, whenever there's a toggle, backfill buffer with last spkr state and reset
+deltaT to zero. In the sound IRQ, if deltaT > buffer size, then subtract buffer size from deltaT. (?)
+
+
+
+*/
                ToggleSpeaker(GetCurrentV65C02Clock());
 //should it return something else here???
                return 0x00;
@@ -797,6 +814,8 @@ else if (event.key.keysym.sym == SDLK_F10)
        SetCallbackTime(FrameCallback, 16666.66666667);
 
 //Instead of this, we should yield remaining time to other processes... !!! FIX !!!
+//lessee...
+//nope. SDL_Delay(10);
        while (SDL_GetTicks() - startTicks < 16);       // Wait for next frame...
        startTicks = SDL_GetTicks();
 }
index 9158db6d3d97f22bd188395cb85441620a23e002..d8a8771bc3c225889506adc9772b30dbb27ea0a0 100755 (executable)
 #include "log.h"
 
 
+#define SAMPLE_RATE                    (44100.0)
+#define SAMPLES_PER_FRAME      (SAMPLE_RATE / 60.0)
+#define CYCLES_PER_SAMPLE      ((1024000.0 / 60.0) / (SAMPLES_PER_FRAME))
+#define SOUND_BUFFER_SIZE      8192
 #define AMPLITUDE      (32)                                            // -32 - +32 seems to be plenty loud!
 
 // Global variables
@@ -36,7 +40,7 @@
 static SDL_AudioSpec desired;
 static bool soundInitialized = false;
 static bool speakerState;
-static uint8 soundBuffer[4096];
+static uint8 soundBuffer[SOUND_BUFFER_SIZE];
 static uint32 soundBufferPos;
 static uint32 sampleBase;
 static SDL_cond * conditional = NULL;
@@ -56,7 +60,7 @@ void SoundInit(void)
 return;
 #endif
 
-       desired.freq = 44100;                                           // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
+       desired.freq = SAMPLE_RATE;                                     // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
        desired.format = AUDIO_S8;                                      // This uses the native endian (for portability)...
 //     desired.format = AUDIO_S16SYS;                          // This uses the native endian (for portability)...
        desired.channels = 1;
@@ -173,9 +177,9 @@ if (time > 95085)//(time & 0x80000000)
        // (or do we?)
 
        SDL_LockAudio();
-       uint32 currentPos = sampleBase + (uint32)((double)time / 23.2199);
+       uint32 currentPos = sampleBase + (uint32)((double)time / CYCLES_PER_SAMPLE);
 
-       if (currentPos > 4095)
+       if (currentPos > SOUND_BUFFER_SIZE - 1)
        {
 #if 0
 WriteLog("ToggleSpeaker() about to go into spinlock at time: %08X (%u) (sampleBase=%u)!\n", time, time, sampleBase);
@@ -216,6 +220,25 @@ void HandleSoundAtFrameEdge(void)
                return;
 
        SDL_LockAudio();
-       sampleBase += 735;
+       sampleBase += SAMPLES_PER_FRAME;
        SDL_UnlockAudio();
 }
+
+/*
+A better way might be as follows:
+
+Keep timestamp array of speaker toggle times. In the sound routine, unpack as many as will fit
+into the given buffer and keep going. Have the toggle function check to see if the buffer is full,
+and if it is, way for a signal from the interrupt that there's room for more. Can keep a circular
+buffer. Also, would need a timestamp buffer on the order of 2096 samples *in theory* could toggle
+each sample
+
+Instead of a timestamp, just keep a delta. That way, don't need to deal with wrapping and all that
+(though the timestamp could wrap--need to check into that)
+
+Need to consider corner cases where a sound IRQ happens but no speaker toggle happened.
+
+*/
+
+
+