2
pygame - Python Game Library
3
Copyright (C) 2000-2001 Pete Shinners
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with this library; if not, write to the Free
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include<Numeric/arrayobject.h>
26
#include<SDL_byteorder.h>
31
/*DOC*/ static char doc_samples[] =
32
/*DOC*/ "pygame.sndarray.samples(Surface) -> Array\n"
33
/*DOC*/ "get a reference to the sound samples\n"
35
/*DOC*/ "This will return an array that directly references the samples\n"
36
/*DOC*/ "in the array.\n"
39
static PyObject* sndarray_samples(PyObject* self, PyObject* arg)
41
int dim[2], numdims, type, formatbytes;
42
PyObject *array, *chunkobj;
47
if(!PyArg_ParseTuple(arg, "O!", &PySound_Type, &chunkobj))
49
chunk = PySound_AsChunk(chunkobj);
51
if(!Mix_QuerySpec(NULL, &format, &numchannels))
52
return RAISE(PyExc_SDLError, "Mixer not initialized");
54
formatbytes = (abs(format)&0xff)/8;
55
if(format == AUDIO_S8)
57
else if(format == AUDIO_U8)
59
else if(formatbytes == 2)
62
return RAISE(PyExc_TypeError, "Unpresentable audio format");
64
numdims = (numchannels>1)?2:1;
65
dim[0] = chunk->alen / (formatbytes*numchannels);
68
array = PyArray_FromDimsAndData(numdims, dim, type, chunk->abuf);
72
((PyArrayObject*)array)->base = chunkobj;
73
((PyArrayObject*)array)->flags |= SAVESPACE;
78
/*DOC*/ static char doc_array[] =
79
/*DOC*/ "pygame.sndarray.array(Sound) -> Array\n"
80
/*DOC*/ "get an array copied from a sound\n"
82
/*DOC*/ "Creates an array with a copy of the sound data.\n"
85
PyObject* sndarray_array(PyObject* self, PyObject* arg)
87
PyObject *array, *arraycopy=NULL;
89
/*we'll let numeric do the copying for us*/
90
array = sndarray_samples(self, arg);
93
arraycopy = PyArray_Copy((PyArrayObject*)array);
100
/*DOC*/ static char doc_make_sound[] =
101
/*DOC*/ "pygame.sndarray.make_sound(array) -> Sound\n"
102
/*DOC*/ "create a new Sound object from array data\n"
104
/*DOC*/ "Create a new playable Sound object from array data\n"
105
/*DOC*/ "the Sound will be a copy of the array samples.\n"
107
/*DOC*/ "The array must be 1-dimensional for mono sound, and.\n"
108
/*DOC*/ "2-dimensional for stereo.\n"
111
PyObject* sndarray_make_sound(PyObject* self, PyObject* arg)
114
PyArrayObject *array;
117
int numchannels, mixerbytes;
118
int loop1, loop2, step1, step2, length, length2=0;
121
if(!PyArg_ParseTuple(arg, "O!", &PyArray_Type, &arrayobj))
123
array = (PyArrayObject*)arrayobj;
125
if(!Mix_QuerySpec(NULL, &format, &numchannels))
126
return RAISE(PyExc_SDLError, "Mixer not initialized");
127
if(array->descr->type_num > PyArray_LONG)
128
return RAISE(PyExc_ValueError, "Invalid array datatype for sound");
130
if(format==AUDIO_S8 || format==AUDIO_U8)
135
/*test array dimensions*/
139
return RAISE(PyExc_ValueError, "Array must be 1-dimensional for mono mixer");
144
return RAISE(PyExc_ValueError, "Array must be 2-dimensional for stereo mixer");
145
if(array->dimensions[1] != numchannels)
146
return RAISE(PyExc_ValueError, "Array depth must match number of mixer channels");
148
length = array->dimensions[0];
150
length2 = array->dimensions[1];
152
/*create chunk, we are screwed if SDL_mixer ever does more than malloc/free*/
153
chunk = (Mix_Chunk *)malloc(sizeof(Mix_Chunk));
155
return RAISE(PyExc_MemoryError, "Cannot allocate chunk\n");
156
/*let's hope Mix_Chunk never changes also*/
157
chunk->alen = mixerbytes * length * numchannels;
158
chunk->abuf = (Uint8*)malloc(chunk->alen);
159
chunk->allocated = 1;
164
step1 = array->strides[0];
165
src = (Uint8*)array->data;
166
dst = (Uint8*)chunk->abuf;
169
switch(array->descr->elsize)
172
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
173
*(Uint8*)dst = (Uint8)*((Uint8*)src);
176
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
177
*(Uint8*)dst = (Uint8)*((Uint16*)src);
180
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
181
*(Uint8*)dst = (Uint8)*((Uint32*)src);
187
switch(array->descr->elsize)
190
for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
191
*(Uint16*)dst = (Uint16)((*((Uint8*)src))<<8);
194
for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
195
*(Uint16*)dst = (Uint16)*((Uint16*)src);
198
for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
199
*(Uint16*)dst = (Uint16)*((Uint32*)src);
206
step1 = array->strides[0];
207
step2 = array->strides[1];
208
dst = (Uint8*)chunk->abuf;
211
for(loop1=0; loop1<length; loop1++)
213
src = (Uint8*)array->data + loop1*step1;
214
switch(array->descr->elsize)
217
for(loop2=0; loop2<length2; loop1++, dst+=1, src+=step2)
218
*(Uint8*)dst = (Uint8)*((Uint8*)src);
221
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
222
*(Uint8*)dst = (Uint8)*((Uint16*)src);
225
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
226
*(Uint8*)dst = (Uint8)*((Uint32*)src);
233
for(loop1 = 0; loop1 < length; loop1++)
235
src = (Uint8*)array->data + loop1*step1;
236
switch(array->descr->elsize)
239
for(loop2=0; loop2<length2; loop1++, dst+=1, src+=step2)
240
*(Uint16*)dst = (Uint16)(*((Uint8*)src)<<8);
243
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
244
*(Uint16*)dst = (Uint16)*((Uint16*)src);
247
for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
248
*(Uint16*)dst = (Uint16)*((Uint32*)src);
255
return PySound_New(chunk);
260
static PyMethodDef sndarray_builtins[] =
262
{ "samples", sndarray_samples, 1, doc_samples },
263
{ "array", sndarray_array, 1, doc_array },
264
{ "make_sound", sndarray_make_sound, 1, doc_make_sound },
273
/*DOC*/ static char doc_pygame_sndarray_MODULE[] =
274
/*DOC*/ "Contains routines for mixing numeric arrays with\n"
279
void initsndarray(void)
281
PyObject *module, *dict;
283
/* create the module */
284
module = Py_InitModule3("sndarray", sndarray_builtins, doc_pygame_sndarray_MODULE);
285
dict = PyModule_GetDict(module);
287
/*imported needed apis*/
288
import_pygame_base();
289
import_pygame_mixer();
291
/*needed for Numeric in python2.3*/
292
PyImport_ImportModule("Numeric");