~ubuntu-branches/ubuntu/warty/pygame/warty

« back to all changes in this revision

Viewing changes to src/sndarray.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-09-17 17:09:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040917170953-caomeukd8awvvpwv
Tags: 1.6-0.2ubuntu1
Add missing build-depends: python

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    pygame - Python Game Library
 
3
    Copyright (C) 2000-2001  Pete Shinners
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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
 
18
 
 
19
    Pete Shinners
 
20
    pete@shinners.org
 
21
*/
 
22
 
 
23
#include"pygame.h"
 
24
#include"mixer.h"
 
25
#include<Numeric/arrayobject.h>
 
26
#include<SDL_byteorder.h>
 
27
 
 
28
 
 
29
 
 
30
 
 
31
    /*DOC*/ static char doc_samples[] =
 
32
    /*DOC*/    "pygame.sndarray.samples(Surface) -> Array\n"
 
33
    /*DOC*/    "get a reference to the sound samples\n"
 
34
    /*DOC*/    "\n"
 
35
    /*DOC*/    "This will return an array that directly references the samples\n"
 
36
    /*DOC*/    "in the array.\n"
 
37
    /*DOC*/ ;
 
38
 
 
39
static PyObject* sndarray_samples(PyObject* self, PyObject* arg)
 
40
{
 
41
        int dim[2], numdims, type, formatbytes;
 
42
        PyObject *array, *chunkobj;
 
43
        Mix_Chunk* chunk;
 
44
        Uint16 format;
 
45
        int numchannels;
 
46
 
 
47
        if(!PyArg_ParseTuple(arg, "O!", &PySound_Type, &chunkobj))
 
48
                return NULL;
 
49
        chunk = PySound_AsChunk(chunkobj);
 
50
 
 
51
        if(!Mix_QuerySpec(NULL, &format, &numchannels))
 
52
            return RAISE(PyExc_SDLError, "Mixer not initialized");
 
53
 
 
54
        formatbytes = (abs(format)&0xff)/8;
 
55
        if(format == AUDIO_S8)
 
56
            type = PyArray_CHAR;
 
57
        else if(format == AUDIO_U8)
 
58
            type = PyArray_UBYTE;
 
59
        else if(formatbytes == 2)
 
60
            type = PyArray_SHORT;
 
61
        else
 
62
            return RAISE(PyExc_TypeError, "Unpresentable audio format");
 
63
 
 
64
        numdims = (numchannels>1)?2:1;
 
65
        dim[0] = chunk->alen / (formatbytes*numchannels);
 
66
        dim[1] = numchannels;
 
67
 
 
68
        array = PyArray_FromDimsAndData(numdims, dim, type, chunk->abuf);
 
69
        if(array)
 
70
        {
 
71
            Py_INCREF(chunkobj);
 
72
            ((PyArrayObject*)array)->base = chunkobj;
 
73
            ((PyArrayObject*)array)->flags |= SAVESPACE;
 
74
        }
 
75
        return array;
 
76
}
 
77
 
 
78
    /*DOC*/ static char doc_array[] =
 
79
    /*DOC*/    "pygame.sndarray.array(Sound) -> Array\n"
 
80
    /*DOC*/    "get an array copied from a sound\n"
 
81
    /*DOC*/    "\n"
 
82
    /*DOC*/    "Creates an array with a copy of the sound data.\n"
 
83
    /*DOC*/ ;
 
84
 
 
85
PyObject* sndarray_array(PyObject* self, PyObject* arg)
 
86
{
 
87
        PyObject *array, *arraycopy=NULL;
 
88
 
 
89
/*we'll let numeric do the copying for us*/
 
90
        array = sndarray_samples(self, arg);
 
91
        if(array)
 
92
        {
 
93
            arraycopy = PyArray_Copy((PyArrayObject*)array);
 
94
            Py_DECREF(array);
 
95
        }
 
96
        return arraycopy;
 
97
}
 
98
 
 
99
 
 
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"
 
103
    /*DOC*/    "\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"
 
106
    /*DOC*/    "\n"
 
107
    /*DOC*/    "The array must be 1-dimensional for mono sound, and.\n"
 
108
    /*DOC*/    "2-dimensional for stereo.\n"
 
109
    /*DOC*/ ;
 
110
 
 
111
PyObject* sndarray_make_sound(PyObject* self, PyObject* arg)
 
112
{
 
113
    PyObject *arrayobj;
 
114
    PyArrayObject *array;
 
115
    Mix_Chunk *chunk;
 
116
    Uint16 format;
 
117
    int numchannels, mixerbytes;
 
118
    int loop1, loop2, step1, step2, length, length2=0;
 
119
    Uint8 *src, *dst;
 
120
 
 
121
    if(!PyArg_ParseTuple(arg, "O!", &PyArray_Type, &arrayobj))
 
122
        return NULL;
 
123
    array = (PyArrayObject*)arrayobj;
 
124
 
 
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");
 
129
 
 
130
    if(format==AUDIO_S8 || format==AUDIO_U8)
 
131
        mixerbytes = 1;
 
132
    else
 
133
        mixerbytes = 2;
 
134
 
 
135
    /*test array dimensions*/
 
136
    if(numchannels==1)
 
137
    {
 
138
        if(array->nd != 1)
 
139
            return RAISE(PyExc_ValueError, "Array must be 1-dimensional for mono mixer");
 
140
    }
 
141
    else
 
142
    {
 
143
        if(array->nd != 2)
 
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");
 
147
    }
 
148
    length = array->dimensions[0];
 
149
    if(array->nd == 2)
 
150
        length2 = array->dimensions[1];
 
151
 
 
152
    /*create chunk, we are screwed if SDL_mixer ever does more than malloc/free*/
 
153
    chunk = (Mix_Chunk *)malloc(sizeof(Mix_Chunk));
 
154
    if ( chunk == NULL )
 
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;
 
160
    chunk->volume = 128;
 
161
 
 
162
    if(array->nd == 1)
 
163
    {
 
164
        step1 = array->strides[0];
 
165
        src = (Uint8*)array->data;
 
166
        dst = (Uint8*)chunk->abuf;
 
167
        if(mixerbytes == 1)
 
168
        {
 
169
            switch(array->descr->elsize)
 
170
            {
 
171
            case 1:
 
172
                for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
 
173
                    *(Uint8*)dst = (Uint8)*((Uint8*)src);
 
174
                break;
 
175
            case 2:
 
176
                for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
 
177
                    *(Uint8*)dst = (Uint8)*((Uint16*)src);
 
178
                break;
 
179
            case 4:
 
180
                for(loop1=0; loop1<length; loop1++, dst+=1, src+=step1)
 
181
                    *(Uint8*)dst = (Uint8)*((Uint32*)src);
 
182
                break;
 
183
            }
 
184
        }
 
185
        else
 
186
        {
 
187
            switch(array->descr->elsize)
 
188
            {
 
189
            case 1:
 
190
                for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
 
191
                    *(Uint16*)dst = (Uint16)((*((Uint8*)src))<<8);
 
192
                break;
 
193
            case 2:
 
194
                for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
 
195
                    *(Uint16*)dst = (Uint16)*((Uint16*)src);
 
196
                break;
 
197
            case 4:
 
198
                for(loop1=0; loop1<length; loop1++, dst+=2, src+=step1)
 
199
                    *(Uint16*)dst = (Uint16)*((Uint32*)src);
 
200
                break;
 
201
            }
 
202
        }
 
203
    }
 
204
    else
 
205
    {
 
206
        step1 = array->strides[0];
 
207
        step2 = array->strides[1];
 
208
        dst = (Uint8*)chunk->abuf;
 
209
        if(mixerbytes == 1)
 
210
        {
 
211
            for(loop1=0; loop1<length; loop1++)
 
212
            {
 
213
                src = (Uint8*)array->data + loop1*step1;
 
214
                switch(array->descr->elsize)
 
215
                {
 
216
                case 1:
 
217
                    for(loop2=0; loop2<length2; loop1++, dst+=1, src+=step2)
 
218
                        *(Uint8*)dst = (Uint8)*((Uint8*)src);
 
219
                    break;
 
220
                case 2:
 
221
                    for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
 
222
                        *(Uint8*)dst = (Uint8)*((Uint16*)src);
 
223
                    break;
 
224
                case 4:
 
225
                    for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
 
226
                        *(Uint8*)dst = (Uint8)*((Uint32*)src);
 
227
                    break;
 
228
                }
 
229
            }
 
230
        }
 
231
        else
 
232
        {
 
233
            for(loop1 = 0; loop1 < length; loop1++)
 
234
            {
 
235
                src = (Uint8*)array->data + loop1*step1;
 
236
               switch(array->descr->elsize)
 
237
                {
 
238
                case 1:
 
239
                    for(loop2=0; loop2<length2; loop1++, dst+=1, src+=step2)
 
240
                        *(Uint16*)dst = (Uint16)(*((Uint8*)src)<<8);
 
241
                    break;
 
242
                case 2:
 
243
                    for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
 
244
                        *(Uint16*)dst = (Uint16)*((Uint16*)src);
 
245
                    break;
 
246
                case 4:
 
247
                    for(loop1=0; loop1<length; loop1++, dst+=1, src+=step2)
 
248
                        *(Uint16*)dst = (Uint16)*((Uint32*)src);
 
249
                    break;
 
250
                }
 
251
            }
 
252
        }
 
253
    }
 
254
 
 
255
    return PySound_New(chunk);
 
256
}
 
257
 
 
258
 
 
259
 
 
260
static PyMethodDef sndarray_builtins[] =
 
261
{
 
262
        { "samples", sndarray_samples, 1, doc_samples },
 
263
        { "array", sndarray_array, 1, doc_array },
 
264
        { "make_sound", sndarray_make_sound, 1, doc_make_sound },
 
265
 
 
266
        { NULL, NULL }
 
267
};
 
268
 
 
269
 
 
270
 
 
271
 
 
272
 
 
273
    /*DOC*/ static char doc_pygame_sndarray_MODULE[] =
 
274
    /*DOC*/    "Contains routines for mixing numeric arrays with\n"
 
275
    /*DOC*/    "sounds\n"
 
276
    /*DOC*/ ;
 
277
 
 
278
PYGAME_EXPORT
 
279
void initsndarray(void)
 
280
{
 
281
        PyObject *module, *dict;
 
282
 
 
283
    /* create the module */
 
284
        module = Py_InitModule3("sndarray", sndarray_builtins, doc_pygame_sndarray_MODULE);
 
285
        dict = PyModule_GetDict(module);
 
286
 
 
287
        /*imported needed apis*/
 
288
        import_pygame_base();
 
289
        import_pygame_mixer();
 
290
        import_array();
 
291
    /*needed for Numeric in python2.3*/
 
292
        PyImport_ImportModule("Numeric");
 
293
}
 
294
 
 
295
 
 
296