1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 #include "ppport.h"
5 #include "helper.h"
6 #include "defines.h"
7 
8 #ifndef aTHX_
9 #define aTHX_
10 #endif
11 
12 #ifdef USE_THREADS
13 #define HAVE_TLS_CONTEXT
14 #endif
15 
16 #include <SDL.h>
17 #include <SDL_audio.h>
18 
19 
20 void
audio_callback(void * data,Uint8 * stream,int len)21 audio_callback ( void* data, Uint8 *stream, int len )
22 {
23 	ENTER_TLS_CONTEXT;
24 	dSP;
25 
26         char* string = (char*)stream;
27 
28 	SV* sv = newSVpv("a",1);
29         SvCUR_set(sv,len * sizeof(Uint8));
30 	SvLEN_set(sv,len * sizeof(Uint8));
31         void* old = SvPVX(sv);
32         SvPV_set(sv,string);
33 
34 	ENTER;
35 	SAVETMPS;
36 	PUSHMARK(SP);
37 
38 	XPUSHs(sv_2mortal(newSViv(sizeof(Uint8))));
39 	XPUSHs(sv_2mortal(newSViv(len)));
40 	XPUSHs(sv_2mortal(newRV_inc(sv)));
41 
42 	PUTBACK;
43  	call_pv(data,G_VOID|G_DISCARD);
44 
45         SvPV_set(sv,old);
46         SvCUR_set(sv,1);
47 	SvLEN_set(sv,1);
48         sv_2mortal(sv);
49 
50 	FREETMPS;
51 	LEAVE;
52 	LEAVE_TLS_CONTEXT;
53 }
54 
55 MODULE = SDL::AudioSpec 	PACKAGE = SDL::AudioSpec    PREFIX = audiospec_
56 
57 =for documentation
58 
59 SDL_AudioSpec -- Audio specification
60 
61   /* The calculated values in this structure are calculated by SDL_OpenAudio() */
62   typedef struct SDL_AudioSpec {
63           int freq;               /* DSP frequency -- samples per second */
64           Uint16 format;          /* Audio data format */
65           Uint8  channels;        /* Number of channels: 1 mono, 2 stereo */
66           Uint8  silence;         /* Audio buffer silence value (calculated) */
67           Uint16 samples;         /* Audio buffer size in samples (power of 2) */
68           Uint16 padding;         /* Necessary for some compile environments */
69           Uint32 size;            /* Audio buffer size in bytes (calculated) */
70           /* This function is called when the audio device needs more data.
71              'stream' is a pointer to the audio data buffer
72              'len' is the length of that buffer in bytes.
73              Once the callback returns, the buffer will no longer be valid.
74              Stereo samples are stored in a LRLRLR ordering.
75           */
76           void (SDLCALL *callback)(void *userdata, Uint8 *stream, int len);
77           void  *userdata;
78   } SDL_AudioSpec;
79 
80 =cut
81 
82 SDL_AudioSpec *
83 audiospec_new (CLASS)
84 	char* CLASS
85 	CODE:
86 		RETVAL = safemalloc(sizeof(SDL_AudioSpec));
87 
88 	OUTPUT:
89 		RETVAL
90 
91 int
92 audiospec_freq ( audiospec, ... )
93 	SDL_AudioSpec *audiospec
94 	CODE:
95 		if (items > 1 ) audiospec->freq = SvIV(ST(1));
96 		RETVAL = audiospec->freq;
97 	OUTPUT:
98 		RETVAL
99 
100 Uint16
101 audiospec_format ( audiospec, ... )
102 	SDL_AudioSpec *audiospec
103 	CODE:
104 		if (items > 1 ) audiospec->format = SvIV(ST(1));
105 		RETVAL = audiospec->format;
106 	OUTPUT:
107 		RETVAL
108 
109 Uint8
110 audiospec_channels ( audiospec, ... )
111 	SDL_AudioSpec *audiospec
112 	CODE:
113 		if (items > 1 ) audiospec->channels = SvIV(ST(1));
114 		RETVAL = audiospec->channels;
115 	OUTPUT:
116 		RETVAL
117 
118 Uint16
119 audiospec_samples ( audiospec, ... )
120 	SDL_AudioSpec *audiospec
121 	CODE:
122 		if (items > 1 ) audiospec->samples = SvIV(ST(1));
123 		RETVAL = audiospec->samples;
124 	OUTPUT:
125 		RETVAL
126 
127 #ifdef USE_THREADS
128 
129 void
130 audiospec_callback( audiospec, cb )
131 	SDL_AudioSpec *audiospec
132 	char* cb
133 	CODE:
134 		/* the audio callback will happen in a different thread. */
135 		GET_TLS_CONTEXT;
136 		audiospec->userdata = cb;
137 		audiospec->callback = audio_callback;
138 
139 #else
140 
141 void
142 audiospec_callback( audiospec, cb )
143 	SDL_AudioSpec *audiospec
144 	char* cb
145 	CODE:
146 		warn("Perl need to be compiled with 'useithreads' for SDL::AudioSpec::callback( cb )");
147 
148 #endif
149 
150 void
151 audiospec_DESTROY(bag)
152 	SV *bag
153 	CODE:
154 		objDESTROY(bag, safefree);
155