Make audio buffer stereo
authorAndreas Eversberg <jolly@eversberg.eu>
Sun, 25 Mar 2018 12:15:08 +0000 (14:15 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Sun, 25 Mar 2018 12:15:08 +0000 (14:15 +0200)
src/libsdl/sdl.c
src/libsound/sound.c
src/libsound/sound.h
src/mercenary/main.c

index 50af2a8..e6a34e6 100644 (file)
@@ -39,7 +39,7 @@ static void audio_cb(void __attribute__((unused)) *userdata, Uint8 *stream, int
        float audio_data[len / sizeof(float)];
 
        SDL_memset(stream, 0, len);
-       audio_sdl(audio_data, len / sizeof(float));
+       audio_sdl(audio_data, len / sizeof(float) / 2);
        SDL_MixAudio(stream, (Uint8 *)audio_data, len, SDL_MIX_MAXVOLUME);
 }
 
@@ -120,7 +120,7 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
        SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
        want.freq = sound_samplerate;
        want.format = AUDIO_F32; /* we always use float in this project */
-       want.channels = 1;
+       want.channels = 2;
        want.samples = sound_chunk; /* must be a power of two */
        want.callback = audio_cb;
        rc = SDL_OpenAudio(&want, &have);
@@ -137,6 +137,11 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
                SDL_CloseAudio();
                rc = -EIO;
                goto error;
+       } else if (have.channels != want.channels) {
+               print_error("Failed to open audio with desired channels (got %d)\n", have.channels);
+               SDL_CloseAudio();
+               rc = -EIO;
+               goto error;
        } else {
                SDL_PauseAudio(0);
                audio_initialized = 1;
index 5b6243a..081a16e 100644 (file)
@@ -161,7 +161,7 @@ void emulate_sound_write(uint32_t address, uint16_t value, int samplerate)
 }
 
 /* render sound from memory and add each channel to ring buffer array */
-void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_pos, int length, int filter)
+void render_sound(uint8_t *memory, stereo_t *sample, int buffer_size, int buffer_pos, int length, int filter)
 {
        int c, s, pos;
        struct audio_channel *chan;
@@ -171,7 +171,7 @@ void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_po
        /* clear buffer first */
        pos = buffer_pos;
        for (s = 0; s < length; s++) {
-               sample[pos] = 0.0;
+               sample[pos].left = 0.0;
                pos = (pos + 1) % buffer_size;
        }
 
@@ -190,7 +190,7 @@ void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_po
                        new_offset = chan->offset + chan->step;
                        if (new_offset < 1.0)
                                /* no interpolation: use last input sample, because there is no change */
-                               sample[pos] += chan->sample * chan->volume;
+                               sample[pos].left += chan->sample * chan->volume;
                        else {
                                /* there is a change of input sample, so read new sample */
                                new_offset -= 1.0;
@@ -200,7 +200,7 @@ void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_po
                                                break;
                                }
                                /* linear interpolation: add portion of last sample to portion of new sample */
-                               sample[pos] += (chan->sample * (1.0 - chan->offset) + new_sample * new_offset) / chan->step * chan->volume;
+                               sample[pos].left += (chan->sample * (1.0 - chan->offset) + new_sample * new_offset) / chan->step * chan->volume;
                                chan->sample = new_sample;
                        }
                        chan->offset = new_offset;
@@ -213,10 +213,17 @@ void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_po
                pos = buffer_pos;
                for (s = 0; s < length; s++) {
                        /* y[i] := y[i-1] + alpha * (x[i] - y[i-1]) */
-                       filter_last = sample[pos] = filter_last + filter_alpha * (sample[pos] - filter_last);
+                       filter_last = sample[pos].left = filter_last + filter_alpha * (sample[pos].left - filter_last);
                        pos = (pos + 1) % buffer_size;
                }
        }
+
+       /* copy left to right */
+       pos = buffer_pos;
+       for (s = 0; s < length; s++) {
+               sample[pos].right = sample[pos].left;
+               pos = (pos + 1) % buffer_size;
+       }
 }
 
 void sound_init_filter(int samplerate)
index 524f6d4..b7f8278 100644 (file)
@@ -1,5 +1,9 @@
 
+typedef struct stereo {
+       float left, right;
+} stereo_t;
+
 void emulate_sound_write(uint32_t address, uint16_t value, int samplerate);
-void render_sound(uint8_t *memory, float *sample, int buffer_size, int buffer_pos, int length, int filter);
+void render_sound(uint8_t *memory, stereo_t *sample, int buffer_size, int buffer_pos, int length, int filter);
 void sound_init_filter(int samplerate);
 
index c15f23e..c3ca13a 100644 (file)
@@ -68,7 +68,7 @@ static uint8_t *image = NULL;
 #define BENSON_AT_LINE 136
 #define IMAGE_DIWSTART 0x2c
 static uint16_t *chipreg = NULL;
-static float *sound_buffer = NULL; /* sound buffer memory */
+static stereo_t *sound_buffer = NULL; /* sound buffer memory */
 static int sound_buffer_size; /* buffer sample size */
 static int sound_buffer_writep; /* write pointer at buffer */
 static int sound_buffer_readp; /* read pointer at buffer */
@@ -228,7 +228,8 @@ static void main_loop(void)
                        static int cnt = 0;
                        int s;
                        for (s = 0; s < length; s++) {
-                               sound_buffer[(sound_buffer_writep + s) % sound_buffer_size]
+                               sound_buffer[(sound_buffer_writep + s) % sound_buffer_size].left =
+                               sound_buffer[(sound_buffer_writep + s) % sound_buffer_size].right
                                        = sin(2 * M_PI * 999 * cnt / SOUND_SAMPLERATE)
                                        * sin(2 * M_PI * 21 * cnt / SOUND_SAMPLERATE)
                                        * sin(2 * M_PI * 0.5 * cnt / SOUND_SAMPLERATE);
@@ -548,10 +549,12 @@ void audio_sdl(float *data, int length)
                /* correct read pointer as if the buffer would have 'length' of samples stored inside */
                sound_buffer_readp = (sound_buffer_readp + fill - length + sound_buffer_size) % sound_buffer_size;
        }
-       for (s = 0; s < length; s++)
-               *data++ = sound_buffer[(sound_buffer_readp + s) % sound_buffer_size];
+       for (s = 0; s < length; s++) {
+               *data++ = sound_buffer[(sound_buffer_readp + s) % sound_buffer_size].left;
+               *data++ = sound_buffer[(sound_buffer_readp + s) % sound_buffer_size].right;
+       }
 #ifdef DEBUG_SOUND_BUFFERING
-       printf("fill %d = %.4f\n", length, sound_buffer[sound_buffer_readp]);
+       printf("fill %d = %.4f\n", length, sound_buffer[sound_buffer_readp][0]);
 #endif
        sound_buffer_readp =(sound_buffer_readp + length) % sound_buffer_size;
 }