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 1021:848db285a184
prev994:a92d433f1be8
next1024:c67f2d61ab97
author nkeynes
date Wed Jun 03 11:37:10 2009 +0000 (13 years ago)
permissions -rw-r--r--
last change Add missing svn:keywords property
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/SDL.h>
    21 #include <SDL/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 char *audio_buffer;
    32 int buffer_pos;
    34 void mix_audio(void *userdata, Uint8 *stream, int len);
    35 void audio_sdl_start();
    37 gboolean audio_sdl_init( )
    38 {
    39     int rate = DEFAULT_SAMPLE_RATE;
    40     int format = DEFAULT_SAMPLE_FORMAT;
    42     SDL_AudioSpec fmt;
    43     fmt.freq = rate;
    44     if (format & AUDIO_FMT_16BIT) 
    45         fmt.format = AUDIO_S16;
    46     else
    47         fmt.format = AUDIO_U8;
    48     if (format & AUDIO_FMT_STEREO)
    49         fmt.channels = 2;
    50     else
    51         fmt.channels = 1;
    53     fmt.samples = SDL_SAMPLES;
    54     fmt.callback = mix_audio;
    55     fmt.userdata = NULL;
    57     if (SDL_OpenAudio(&fmt, NULL) < 0)
    58     {
    59         ERROR("Unable to open audio output (SDL)");
    60         return FALSE;
    61     }
    62     buffer_pos = 0;
    63     audio_buffer = (char*)malloc(BUFFER_MAX_SIZE * sizeof(char));
    64     if (audio_buffer == NULL)
    65     {
    66         ERROR("Could not allocate audio buffer (SDL)");
    67         return FALSE;
    68     }
    70     //hmm, this doesn't seem to get called externally...
    71     audio_sdl_start();
    73     return TRUE;
    74 }
    76 gboolean audio_sdl_process_buffer( audio_buffer_t buffer )
    77 {
    78     SDL_LockAudio();
    79     if (buffer_pos + buffer->length >= BUFFER_MAX_SIZE)
    80     {
    81         printf("Audio buffer full, dropping a chunk\n");
    82     }
    83     else
    84     {
    85         memcpy(audio_buffer, buffer->data, buffer->length);
    86         buffer_pos += buffer->length;
    87     }
    88     SDL_UnlockAudio();
    90     return TRUE;    
    91 }
    93 void mix_audio(void *userdata, Uint8 *stream, int len)
    94 {
    95     if (len < buffer_pos)
    96     {
    97         memcpy(stream, audio_buffer, len);
    98     }
    99     if (buffer_pos > BUFFER_MIN_SIZE)
   100     {
   101         memcpy(audio_buffer, &audio_buffer[len], buffer_pos - len);
   102         buffer_pos -= len;
   103     }
   104     else
   105     {
   106         //printf("Audio buffer low, repeating a chunk\n");
   107     }
   108 }
   110 gboolean audio_sdl_shutdown()
   111 {
   112     SDL_CloseAudio();
   113     free(audio_buffer);
   114     return TRUE;
   115 }
   117 void audio_sdl_start()
   118 {
   119     SDL_PauseAudio(0);
   120 }
   122 void audio_sdl_stop()
   123 {
   124     SDL_PauseAudio(1);
   125 }
   127 struct audio_driver audio_sdl_driver = { 
   128     "sdl",
   129     N_("SDL sound driver"),
   130     DEFAULT_SAMPLE_RATE,
   131     DEFAULT_SAMPLE_FORMAT,
   132     audio_sdl_init,
   133     audio_sdl_start,
   134     audio_sdl_process_buffer,
   135     audio_sdl_stop,
   136     audio_sdl_shutdown
   137 };
.