2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
31 #include "alDatabuffer.h"
35 DECL_VERIFIER(Databuffer
, ALdatabuffer
, databuffer
)
38 * alGenDatabuffersEXT(ALsizei n, ALuint *puiBuffers)
40 * Generates n AL Databuffers, and stores the Databuffers Names in the array pointed to by puiBuffers
42 ALvoid AL_APIENTRY
alGenDatabuffersEXT(ALsizei n
,ALuint
*puiBuffers
)
47 Context
= GetContextSuspended();
50 /* Check that we are actually generation some Databuffers */
53 ALCdevice
*device
= Context
->Device
;
55 /* Check the pointer is valid (and points to enough memory to store
56 * Databuffer Names) */
57 if(!IsBadWritePtr((void*)puiBuffers
, n
* sizeof(ALuint
)))
60 ALdatabuffer
**list
= &device
->DatabufferList
;
62 list
= &(*list
)->next
;
64 /* Create all the new Databuffers */
68 *list
= calloc(1, sizeof(ALdatabuffer
));
73 ALdatabuffer
*temp
= end
->next
;
74 end
->next
= temp
->next
;
76 ALTHUNK_REMOVEENTRY(temp
->databuffer
);
77 device
->DatabufferCount
--;
80 alSetError(Context
, AL_OUT_OF_MEMORY
);
84 puiBuffers
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
85 (*list
)->databuffer
= puiBuffers
[i
];
86 (*list
)->state
= UNMAPPED
;
87 device
->DatabufferCount
++;
90 list
= &(*list
)->next
;
94 alSetError(Context
, AL_INVALID_VALUE
);
97 ProcessContext(Context
);
101 * alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
103 * Deletes the n AL Databuffers pointed to by puiBuffers
105 ALvoid AL_APIENTRY
alDeleteDatabuffersEXT(ALsizei n
, const ALuint
*puiBuffers
)
110 ALboolean bFailed
= AL_FALSE
;
112 Context
= GetContextSuspended();
115 /* Check we are actually Deleting some Databuffers */
118 ALCdevice
*device
= Context
->Device
;
120 /* Check that all the databuffers are valid and can actually be
127 /* Check for valid Buffer ID */
128 if((ALBuf
=VerifyDatabuffer(device
->DatabufferList
, puiBuffers
[i
])) != NULL
)
130 if(ALBuf
->state
!= UNMAPPED
)
132 /* Databuffer still in use, cannot be deleted */
133 alSetError(Context
, AL_INVALID_OPERATION
);
140 /* Invalid Databuffer */
141 alSetError(Context
, AL_INVALID_NAME
);
147 /* If all the Databuffers were valid (and unmapped), then we can
153 if((ALBuf
=VerifyDatabuffer(device
->DatabufferList
, puiBuffers
[i
])) != NULL
)
155 ALdatabuffer
**list
= &device
->DatabufferList
;
157 while(*list
&& *list
!= ALBuf
)
158 list
= &(*list
)->next
;
161 *list
= (*list
)->next
;
163 if(ALBuf
== Context
->SampleSource
)
164 Context
->SampleSource
= NULL
;
165 if(ALBuf
== Context
->SampleSink
)
166 Context
->SampleSink
= NULL
;
168 // Release the memory used to store audio data
171 // Release buffer structure
172 ALTHUNK_REMOVEENTRY(puiBuffers
[i
]);
173 memset(ALBuf
, 0, sizeof(ALdatabuffer
));
174 device
->DatabufferCount
--;
181 alSetError(Context
, AL_INVALID_VALUE
);
183 ProcessContext(Context
);
187 * alIsDatabufferEXT(ALuint uiBuffer)
189 * Checks if ulBuffer is a valid Databuffer Name
191 ALboolean AL_APIENTRY
alIsDatabufferEXT(ALuint uiBuffer
)
194 ALboolean result
= AL_TRUE
;
197 Context
= GetContextSuspended();
198 if(!Context
) return AL_FALSE
;
200 device
= Context
->Device
;
202 result
= (VerifyDatabuffer(device
->DatabufferList
, uiBuffer
) ?
205 ProcessContext(Context
);
211 * alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
213 * Fill databuffer with data
215 ALvoid AL_APIENTRY
alDatabufferDataEXT(ALuint buffer
,const ALvoid
*data
,ALsizeiptrEXT size
,ALenum usage
)
222 Context
= GetContextSuspended();
225 Device
= Context
->Device
;
226 if((ALBuf
=VerifyDatabuffer(Device
->DatabufferList
, buffer
)) != NULL
)
228 if(ALBuf
->state
== UNMAPPED
)
230 if(usage
== AL_STREAM_WRITE_EXT
|| usage
== AL_STREAM_READ_EXT
||
231 usage
== AL_STREAM_COPY_EXT
|| usage
== AL_STATIC_WRITE_EXT
||
232 usage
== AL_STATIC_READ_EXT
|| usage
== AL_STATIC_COPY_EXT
||
233 usage
== AL_DYNAMIC_WRITE_EXT
|| usage
== AL_DYNAMIC_READ_EXT
||
234 usage
== AL_DYNAMIC_COPY_EXT
)
238 /* (Re)allocate data */
239 temp
= realloc(ALBuf
->data
, size
);
244 ALBuf
->usage
= usage
;
246 memcpy(ALBuf
->data
, data
, size
);
249 alSetError(Context
, AL_OUT_OF_MEMORY
);
252 alSetError(Context
, AL_INVALID_VALUE
);
255 alSetError(Context
, AL_INVALID_ENUM
);
258 alSetError(Context
, AL_INVALID_OPERATION
);
261 alSetError(Context
, AL_INVALID_NAME
);
263 ProcessContext(Context
);
266 ALvoid AL_APIENTRY
alDatabufferSubDataEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, const ALvoid
*data
)
268 ALCcontext
*pContext
;
269 ALdatabuffer
*pBuffer
;
272 pContext
= GetContextSuspended();
273 if(!pContext
) return;
275 Device
= pContext
->Device
;
276 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
278 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
280 if(pBuffer
->state
== UNMAPPED
)
281 memcpy(pBuffer
->data
+start
, data
, length
);
283 alSetError(pContext
, AL_INVALID_OPERATION
);
286 alSetError(pContext
, AL_INVALID_VALUE
);
289 alSetError(pContext
, AL_INVALID_NAME
);
291 ProcessContext(pContext
);
294 ALvoid AL_APIENTRY
alGetDatabufferSubDataEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, ALvoid
*data
)
296 ALCcontext
*pContext
;
297 ALdatabuffer
*pBuffer
;
300 pContext
= GetContextSuspended();
301 if(!pContext
) return;
303 Device
= pContext
->Device
;
304 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
306 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
308 if(pBuffer
->state
== UNMAPPED
)
309 memcpy(data
, pBuffer
->data
+start
, length
);
311 alSetError(pContext
, AL_INVALID_OPERATION
);
314 alSetError(pContext
, AL_INVALID_VALUE
);
317 alSetError(pContext
, AL_INVALID_NAME
);
319 ProcessContext(pContext
);
323 ALvoid AL_APIENTRY
alDatabufferfEXT(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
325 ALCcontext
*pContext
;
330 pContext
= GetContextSuspended();
331 if(!pContext
) return;
333 Device
= pContext
->Device
;
334 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
339 alSetError(pContext
, AL_INVALID_ENUM
);
344 alSetError(pContext
, AL_INVALID_NAME
);
346 ProcessContext(pContext
);
349 ALvoid AL_APIENTRY
alDatabufferfvEXT(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
351 ALCcontext
*pContext
;
356 pContext
= GetContextSuspended();
357 if(!pContext
) return;
359 Device
= pContext
->Device
;
360 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
365 alSetError(pContext
, AL_INVALID_ENUM
);
370 alSetError(pContext
, AL_INVALID_NAME
);
372 ProcessContext(pContext
);
376 ALvoid AL_APIENTRY
alDatabufferiEXT(ALuint buffer
, ALenum eParam
, ALint lValue
)
378 ALCcontext
*pContext
;
383 pContext
= GetContextSuspended();
384 if(!pContext
) return;
386 Device
= pContext
->Device
;
387 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
392 alSetError(pContext
, AL_INVALID_ENUM
);
397 alSetError(pContext
, AL_INVALID_NAME
);
399 ProcessContext(pContext
);
402 ALvoid AL_APIENTRY
alDatabufferivEXT(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
404 ALCcontext
*pContext
;
409 pContext
= GetContextSuspended();
410 if(!pContext
) return;
412 Device
= pContext
->Device
;
413 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
418 alSetError(pContext
, AL_INVALID_ENUM
);
423 alSetError(pContext
, AL_INVALID_NAME
);
425 ProcessContext(pContext
);
429 ALvoid AL_APIENTRY
alGetDatabufferfEXT(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
431 ALCcontext
*pContext
;
434 pContext
= GetContextSuspended();
435 if(!pContext
) return;
439 Device
= pContext
->Device
;
440 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
445 alSetError(pContext
, AL_INVALID_ENUM
);
450 alSetError(pContext
, AL_INVALID_NAME
);
453 alSetError(pContext
, AL_INVALID_VALUE
);
455 ProcessContext(pContext
);
458 ALvoid AL_APIENTRY
alGetDatabufferfvEXT(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
460 ALCcontext
*pContext
;
463 pContext
= GetContextSuspended();
464 if(!pContext
) return;
468 Device
= pContext
->Device
;
469 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
474 alSetError(pContext
, AL_INVALID_ENUM
);
479 alSetError(pContext
, AL_INVALID_NAME
);
482 alSetError(pContext
, AL_INVALID_VALUE
);
484 ProcessContext(pContext
);
487 ALvoid AL_APIENTRY
alGetDatabufferiEXT(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
489 ALCcontext
*pContext
;
490 ALdatabuffer
*pBuffer
;
493 pContext
= GetContextSuspended();
494 if(!pContext
) return;
498 Device
= pContext
->Device
;
499 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, buffer
)) != NULL
)
504 *plValue
= (ALint
)pBuffer
->size
;
508 alSetError(pContext
, AL_INVALID_ENUM
);
513 alSetError(pContext
, AL_INVALID_NAME
);
516 alSetError(pContext
, AL_INVALID_VALUE
);
518 ProcessContext(pContext
);
521 ALvoid AL_APIENTRY
alGetDatabufferivEXT(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
523 ALCcontext
*pContext
;
526 pContext
= GetContextSuspended();
527 if(!pContext
) return;
531 Device
= pContext
->Device
;
532 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
537 alGetDatabufferiEXT(buffer
, eParam
, plValues
);
541 alSetError(pContext
, AL_INVALID_ENUM
);
546 alSetError(pContext
, AL_INVALID_NAME
);
549 alSetError(pContext
, AL_INVALID_VALUE
);
551 ProcessContext(pContext
);
555 ALvoid AL_APIENTRY
alSelectDatabufferEXT(ALenum target
, ALuint uiBuffer
)
557 ALCcontext
*pContext
;
558 ALdatabuffer
*pBuffer
= NULL
;
561 pContext
= GetContextSuspended();
562 if(!pContext
) return;
564 Device
= pContext
->Device
;
566 (pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
568 if(target
== AL_SAMPLE_SOURCE_EXT
)
569 pContext
->SampleSource
= pBuffer
;
570 else if(target
== AL_SAMPLE_SINK_EXT
)
571 pContext
->SampleSink
= pBuffer
;
573 alSetError(pContext
, AL_INVALID_VALUE
);
576 alSetError(pContext
, AL_INVALID_NAME
);
578 ProcessContext(pContext
);
582 ALvoid
* AL_APIENTRY
alMapDatabufferEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, ALenum access
)
584 ALCcontext
*pContext
;
585 ALdatabuffer
*pBuffer
;
589 pContext
= GetContextSuspended();
590 if(!pContext
) return NULL
;
592 Device
= pContext
->Device
;
593 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
595 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
597 if(access
== AL_READ_ONLY_EXT
|| access
== AL_WRITE_ONLY_EXT
||
598 access
== AL_READ_WRITE_EXT
)
600 if(pBuffer
->state
== UNMAPPED
)
602 ret
= pBuffer
->data
+ start
;
603 pBuffer
->state
= MAPPED
;
606 alSetError(pContext
, AL_INVALID_OPERATION
);
609 alSetError(pContext
, AL_INVALID_ENUM
);
612 alSetError(pContext
, AL_INVALID_VALUE
);
615 alSetError(pContext
, AL_INVALID_NAME
);
617 ProcessContext(pContext
);
622 ALvoid AL_APIENTRY
alUnmapDatabufferEXT(ALuint uiBuffer
)
624 ALCcontext
*pContext
;
625 ALdatabuffer
*pBuffer
;
628 pContext
= GetContextSuspended();
629 if(!pContext
) return;
631 Device
= pContext
->Device
;
632 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
634 if(pBuffer
->state
== MAPPED
)
635 pBuffer
->state
= UNMAPPED
;
637 alSetError(pContext
, AL_INVALID_OPERATION
);
640 alSetError(pContext
, AL_INVALID_NAME
);
642 ProcessContext(pContext
);
647 * ReleaseALDatabuffers()
649 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
651 ALvoid
ReleaseALDatabuffers(ALCdevice
*device
)
653 ALdatabuffer
*ALBuffer
;
654 ALdatabuffer
*ALBufferTemp
;
656 ALBuffer
= device
->DatabufferList
;
659 // Release sample data
660 free(ALBuffer
->data
);
662 // Release Buffer structure
663 ALBufferTemp
= ALBuffer
;
664 ALBuffer
= ALBuffer
->next
;
665 memset(ALBufferTemp
, 0, sizeof(ALdatabuffer
));
668 device
->DatabufferList
= NULL
;
669 device
->DatabufferCount
= 0;