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