~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to src/audio_sdl.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2007-02-05 23:18:31 UTC
  • mfrom: (4.1.5 feisty)
  • Revision ID: james.westby@ubuntu.com-20070205231831-d9jsbodape2vfx2i
Tags: 0.61-5
src/httpget.c: Fix potential denial of service attack on premature
end-of-file from HTTP server (CVE-2007-0578). Patch taken from upstream's
0.64 release. Closes: #409296

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        audio_portaudio.c: audio output via PortAudio cross-platform audio API
 
3
 
 
4
        copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
 
5
        see COPYING and AUTHORS files in distribution or http://mpg123.de
 
6
        initially written by Nicholas J. Humfrey
 
7
*/
 
8
 
 
9
#include <stdlib.h>
 
10
#include <stdio.h>
 
11
#include <math.h>
 
12
 
 
13
#include <SDL.h>
 
14
 
 
15
#include "config.h"
 
16
#include "debug.h"
 
17
#include "audio.h"
 
18
#include "sfifo.h"
 
19
#include "mpg123.h"
 
20
 
 
21
 
 
22
#define SAMPLE_SIZE                     (2)
 
23
#define FRAMES_PER_BUFFER       (256)
 
24
#define FIFO_DURATION           (0.5f)
 
25
 
 
26
static int sdl_initialised=0;
 
27
static sfifo_t fifo;
 
28
 
 
29
 
 
30
 
 
31
/* The audio function callback takes the following parameters:
 
32
       stream:  A pointer to the audio buffer to be filled
 
33
       len:     The length (in bytes) of the audio buffer
 
34
*/
 
35
static void
 
36
audio_callback_sdl(void *udata, Uint8 *stream, int len)
 
37
{
 
38
        /* struct audio_info_struct *ai = udata; */
 
39
        int read;
 
40
 
 
41
        /* Only play if we have data left */
 
42
        if ( sfifo_used( &fifo ) < len ) {
 
43
                warning("Didn't have any audio data for SDL (buffer underflow)");
 
44
                SDL_PauseAudio(1);
 
45
                return;
 
46
        }
 
47
 
 
48
        /* Read audio from FIFO to SDL's buffer */
 
49
        read = sfifo_read( &fifo, stream, len );
 
50
        
 
51
        if (len!=read)
 
52
                warning2("Error reading from the FIFO (wanted=%u, read=%u).\n", len, read);
 
53
 
 
54
 
55
 
 
56
 
 
57
int audio_open(struct audio_info_struct *ai)
 
58
{
 
59
        
 
60
        /* Initalise SDL */
 
61
        if (!sdl_initialised)  {
 
62
                if (SDL_Init( SDL_INIT_AUDIO ) ) {
 
63
                        error1("Failed to initialise SDL: %s\n", SDL_GetError());
 
64
                        return -1;
 
65
                }
 
66
                sdl_initialised=1;
 
67
        }
 
68
        
 
69
        
 
70
 
 
71
        /* Open an audio I/O stream. */
 
72
        if (ai->rate > 0 && ai->channels >0 ) {
 
73
                SDL_AudioSpec wanted;
 
74
                size_t ringbuffer_len;
 
75
        
 
76
                /* L16 uncompressed audio data, using 16-bit signed representation in twos 
 
77
                   complement notation - system endian-ness. */
 
78
                wanted.format = AUDIO_S16SYS;
 
79
                wanted.samples = 1024;  /* Good low-latency value for callback */ 
 
80
                wanted.callback = audio_callback_sdl; 
 
81
                wanted.userdata = ai; 
 
82
                wanted.channels = ai->channels; 
 
83
                wanted.freq = ai->rate; 
 
84
        
 
85
                /* Open the audio device, forcing the desired format */
 
86
                if ( SDL_OpenAudio(&wanted, NULL) ) {
 
87
                        error1("Couldn't open SDL audio: %s\n", SDL_GetError());
 
88
                        return -1;
 
89
                }
 
90
        
 
91
                /* Initialise FIFO */
 
92
                ringbuffer_len = ai->rate * FIFO_DURATION * SAMPLE_SIZE *ai->channels;
 
93
                debug2( "Allocating %d byte ring-buffer (%f seconds)", ringbuffer_len, (float)FIFO_DURATION);
 
94
                sfifo_init( &fifo, ringbuffer_len );
 
95
                                                                           
 
96
        }
 
97
        
 
98
        return(0);
 
99
}
 
100
 
 
101
 
 
102
int audio_get_formats(struct audio_info_struct *ai)
 
103
{
 
104
        /* Only implemented Signed 16-bit audio for now */
 
105
        return AUDIO_FORMAT_SIGNED_16;
 
106
}
 
107
 
 
108
 
 
109
int audio_play_samples(struct audio_info_struct *ai, unsigned char *buf, int len)
 
110
{
 
111
 
 
112
        /* Sleep for half the length of the FIFO */
 
113
        while (sfifo_space( &fifo ) < len ) {
 
114
                usleep( (FIFO_DURATION/2) * 1000000 );
 
115
        }
 
116
        
 
117
        /* Bung decoded audio into the FIFO 
 
118
                 SDL Audio locking probably isn't actually needed
 
119
                 as SFIFO claims to be thread safe...
 
120
        */
 
121
        SDL_LockAudio();
 
122
        sfifo_write( &fifo, buf, len);
 
123
        SDL_UnlockAudio();
 
124
        
 
125
        
 
126
        /* Unpause once the buffer is 50% full */
 
127
        if (sfifo_used(&fifo) > (sfifo_size(&fifo)*0.5) ) SDL_PauseAudio(0);
 
128
 
 
129
        return len;
 
130
}
 
131
 
 
132
int audio_close(struct audio_info_struct *ai)
 
133
{
 
134
        SDL_CloseAudio();
 
135
        
 
136
        sfifo_close( &fifo );
 
137
        
 
138
        return 0;
 
139
}
 
140
 
 
141
void audio_queueflush(struct audio_info_struct *ai)
 
142
{
 
143
        SDL_PauseAudio(1);
 
144
        
 
145
        sfifo_flush( &fifo );   
 
146
}
 
147