Search
lxdream.org :: lxdream/src/drivers/audio_sdl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/audio_sdl.c
changeset 1161:d3511e94c29f
prev1049:e723f379ec88
author nkeynes
date Fri May 29 18:47:05 2015 +1000 (8 years ago)
permissions -rw-r--r--
last change Fix test case
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * The SDL sound driver
     5  *
     6  * Copyright (c) 2009 wahrhaft
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    18 #include <stdio.h>
    19 #include <unistd.h>
    20 #include <SDL.h>
    21 #include <SDL_audio.h>
    22 #include "aica/audio.h"
    23 #include "lxdream.h"
    25 #define SDL_SAMPLES 512        //tweaking this value may help with audio dropouts
    26 #define BYTES_PER_SAMPLE 4     //should be changed if samples are not S16 stereo
    28 #define BUFFER_MIN_SIZE SDL_SAMPLES * BYTES_PER_SAMPLE * 4
    29 #define BUFFER_MAX_SIZE SDL_SAMPLES * BYTES_PER_SAMPLE * 16
    31 static char *audio_buffer;
    32 static int buffer_pos;
    34 static void mix_audio(void *userdata, Uint8 *stream, int len);
    36 static gboolean audio_sdl_init( )
    37 {
    38     int rate = DEFAULT_SAMPLE_RATE;
    39     int format = DEFAULT_SAMPLE_FORMAT;
    41     SDL_AudioSpec fmt;
    42     fmt.freq = rate;
    43     if (format & AUDIO_FMT_16BIT)
    44         fmt.format = AUDIO_S16;
    45     else
    46         fmt.format = AUDIO_U8;
    47     if (format & AUDIO_FMT_STEREO)
    48         fmt.channels = 2;
    49     else
    50         fmt.channels = 1;
    52     fmt.samples = SDL_SAMPLES;
    53     fmt.callback = mix_audio;
    54     fmt.userdata = NULL;
    56     if (SDL_OpenAudio(&fmt, NULL) < 0)
    57     {
    58         ERROR("Unable to open audio output (SDL)");
    59         return FALSE;
    60     }
    61     buffer_pos = 0;
    62     audio_buffer = (char*)malloc(BUFFER_MAX_SIZE * sizeof(char));
    63     if (audio_buffer == NULL)
    64     {
    65         ERROR("Could not allocate audio buffer (SDL)");
    66         return FALSE;
    67     }
    69     return TRUE;
    70 }
    72 gboolean audio_sdl_process_buffer( audio_buffer_t buffer )
    73 {
    74     SDL_LockAudio();
    75     if (buffer_pos + buffer->length >= BUFFER_MAX_SIZE)
    76     {
    77         DEBUG("Audio buffer full, dropping a chunk\n");
    78     }
    79     else
    80     {
    81         memcpy(audio_buffer, buffer->data, buffer->length);
    82         buffer_pos += buffer->length;
    83     }
    84     SDL_UnlockAudio();
    86     return TRUE;
    87 }
    89 static void mix_audio(void *userdata, Uint8 *stream, int len)
    90 {
    91     if (len < buffer_pos)
    92     {
    93         memcpy(stream, audio_buffer, len);
    94     }
    95     if (buffer_pos > BUFFER_MIN_SIZE)
    96     {
    97         memcpy(audio_buffer, &audio_buffer[len], buffer_pos - len);
    98         buffer_pos -= len;
    99     }
   100     else
   101     {
   102         DEBUG("Audio buffer low, repeating a chunk\n");
   103     }
   104 }
   106 static gboolean audio_sdl_shutdown()
   107 {
   108     SDL_CloseAudio();
   109     free(audio_buffer);
   110     return TRUE;
   111 }
   113 static void audio_sdl_start()
   114 {
   115     SDL_PauseAudio(0);
   116 }
   118 static void audio_sdl_stop()
   119 {
   120     SDL_PauseAudio(1);
   121 }
   123 static struct audio_driver audio_sdl_driver = {
   124     "sdl",
   125     N_("SDL sound driver"),
   126     20,
   127     DEFAULT_SAMPLE_RATE,
   128     DEFAULT_SAMPLE_FORMAT,
   129     audio_sdl_init,
   130     audio_sdl_start,
   131     audio_sdl_process_buffer,
   132     audio_sdl_stop,
   133     audio_sdl_shutdown
   134 };
   136 AUDIO_DRIVER( "sdl", audio_sdl_driver );
.