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 ALAPIENTRY
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
)))
59 ALdatabuffer
**list
= &device
->DatabufferList
;
61 list
= &(*list
)->next
;
63 /* Create all the new Databuffers */
66 *list
= calloc(1, sizeof(ALdatabuffer
));
69 alDeleteDatabuffersEXT(i
, puiBuffers
);
70 alSetError(Context
, AL_OUT_OF_MEMORY
);
74 puiBuffers
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
75 (*list
)->databuffer
= puiBuffers
[i
];
76 (*list
)->state
= UNMAPPED
;
77 device
->DatabufferCount
++;
80 list
= &(*list
)->next
;
84 alSetError(Context
, AL_INVALID_VALUE
);
87 ProcessContext(Context
);
91 * alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
93 * Deletes the n AL Databuffers pointed to by puiBuffers
95 ALvoid ALAPIENTRY
alDeleteDatabuffersEXT(ALsizei n
, const ALuint
*puiBuffers
)
100 ALboolean bFailed
= AL_FALSE
;
102 Context
= GetContextSuspended();
105 /* Check we are actually Deleting some Databuffers */
108 ALCdevice
*device
= Context
->Device
;
110 /* Check that all the databuffers are valid and can actually be
117 /* Check for valid Buffer ID */
118 if((ALBuf
=VerifyDatabuffer(device
->DatabufferList
, puiBuffers
[i
])) != NULL
)
120 if(ALBuf
->state
!= UNMAPPED
)
122 /* Databuffer still in use, cannot be deleted */
123 alSetError(Context
, AL_INVALID_OPERATION
);
130 /* Invalid Databuffer */
131 alSetError(Context
, AL_INVALID_NAME
);
137 /* If all the Databuffers were valid (and unmapped), then we can
143 if((ALBuf
=VerifyDatabuffer(device
->DatabufferList
, puiBuffers
[i
])) != NULL
)
145 ALdatabuffer
**list
= &device
->DatabufferList
;
147 while(*list
&& *list
!= ALBuf
)
148 list
= &(*list
)->next
;
151 *list
= (*list
)->next
;
153 if(ALBuf
== Context
->SampleSource
)
154 Context
->SampleSource
= NULL
;
155 if(ALBuf
== Context
->SampleSink
)
156 Context
->SampleSink
= NULL
;
158 // Release the memory used to store audio data
161 // Release buffer structure
162 ALTHUNK_REMOVEENTRY(puiBuffers
[i
]);
163 memset(ALBuf
, 0, sizeof(ALdatabuffer
));
164 device
->DatabufferCount
--;
171 alSetError(Context
, AL_INVALID_VALUE
);
173 ProcessContext(Context
);
177 * alIsDatabufferEXT(ALuint uiBuffer)
179 * Checks if ulBuffer is a valid Databuffer Name
181 ALboolean ALAPIENTRY
alIsDatabufferEXT(ALuint uiBuffer
)
184 ALboolean result
= AL_TRUE
;
187 Context
= GetContextSuspended();
188 if(!Context
) return AL_FALSE
;
190 device
= Context
->Device
;
192 result
= (VerifyDatabuffer(device
->DatabufferList
, uiBuffer
) ?
195 ProcessContext(Context
);
201 * alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
203 * Fill databuffer with data
205 ALvoid ALAPIENTRY
alDatabufferDataEXT(ALuint buffer
,const ALvoid
*data
,ALsizeiptrEXT size
,ALenum usage
)
212 Context
= GetContextSuspended();
215 Device
= Context
->Device
;
216 if((ALBuf
=VerifyDatabuffer(Device
->DatabufferList
, buffer
)) != NULL
)
218 if(ALBuf
->state
== UNMAPPED
)
220 if(usage
== AL_STREAM_WRITE_EXT
|| usage
== AL_STREAM_READ_EXT
||
221 usage
== AL_STREAM_COPY_EXT
|| usage
== AL_STATIC_WRITE_EXT
||
222 usage
== AL_STATIC_READ_EXT
|| usage
== AL_STATIC_COPY_EXT
||
223 usage
== AL_DYNAMIC_WRITE_EXT
|| usage
== AL_DYNAMIC_READ_EXT
||
224 usage
== AL_DYNAMIC_COPY_EXT
)
228 /* (Re)allocate data */
229 temp
= realloc(ALBuf
->data
, size
);
234 ALBuf
->usage
= usage
;
236 memcpy(ALBuf
->data
, data
, size
);
239 alSetError(Context
, AL_OUT_OF_MEMORY
);
242 alSetError(Context
, AL_INVALID_VALUE
);
245 alSetError(Context
, AL_INVALID_ENUM
);
248 alSetError(Context
, AL_INVALID_OPERATION
);
251 alSetError(Context
, AL_INVALID_NAME
);
253 ProcessContext(Context
);
256 ALvoid ALAPIENTRY
alDatabufferSubDataEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, const ALvoid
*data
)
258 ALCcontext
*pContext
;
259 ALdatabuffer
*pBuffer
;
262 pContext
= GetContextSuspended();
263 if(!pContext
) return;
265 Device
= pContext
->Device
;
266 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
268 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
270 if(pBuffer
->state
== UNMAPPED
)
271 memcpy(pBuffer
->data
+start
, data
, length
);
273 alSetError(pContext
, AL_INVALID_OPERATION
);
276 alSetError(pContext
, AL_INVALID_VALUE
);
279 alSetError(pContext
, AL_INVALID_NAME
);
281 ProcessContext(pContext
);
284 ALvoid ALAPIENTRY
alGetDatabufferSubDataEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, ALvoid
*data
)
286 ALCcontext
*pContext
;
287 ALdatabuffer
*pBuffer
;
290 pContext
= GetContextSuspended();
291 if(!pContext
) return;
293 Device
= pContext
->Device
;
294 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
296 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
298 if(pBuffer
->state
== UNMAPPED
)
299 memcpy(data
, pBuffer
->data
+start
, length
);
301 alSetError(pContext
, AL_INVALID_OPERATION
);
304 alSetError(pContext
, AL_INVALID_VALUE
);
307 alSetError(pContext
, AL_INVALID_NAME
);
309 ProcessContext(pContext
);
313 ALvoid ALAPIENTRY
alDatabufferfEXT(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
315 ALCcontext
*pContext
;
320 pContext
= GetContextSuspended();
321 if(!pContext
) return;
323 Device
= pContext
->Device
;
324 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
329 alSetError(pContext
, AL_INVALID_ENUM
);
334 alSetError(pContext
, AL_INVALID_NAME
);
336 ProcessContext(pContext
);
339 ALvoid ALAPIENTRY
alDatabufferfvEXT(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
341 ALCcontext
*pContext
;
346 pContext
= GetContextSuspended();
347 if(!pContext
) return;
349 Device
= pContext
->Device
;
350 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
355 alSetError(pContext
, AL_INVALID_ENUM
);
360 alSetError(pContext
, AL_INVALID_NAME
);
362 ProcessContext(pContext
);
366 ALvoid ALAPIENTRY
alDatabufferiEXT(ALuint buffer
, ALenum eParam
, ALint lValue
)
368 ALCcontext
*pContext
;
373 pContext
= GetContextSuspended();
374 if(!pContext
) return;
376 Device
= pContext
->Device
;
377 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
382 alSetError(pContext
, AL_INVALID_ENUM
);
387 alSetError(pContext
, AL_INVALID_NAME
);
389 ProcessContext(pContext
);
392 ALvoid ALAPIENTRY
alDatabufferivEXT(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
394 ALCcontext
*pContext
;
399 pContext
= GetContextSuspended();
400 if(!pContext
) return;
402 Device
= pContext
->Device
;
403 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
408 alSetError(pContext
, AL_INVALID_ENUM
);
413 alSetError(pContext
, AL_INVALID_NAME
);
415 ProcessContext(pContext
);
419 ALvoid ALAPIENTRY
alGetDatabufferfEXT(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
421 ALCcontext
*pContext
;
424 pContext
= GetContextSuspended();
425 if(!pContext
) return;
429 Device
= pContext
->Device
;
430 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
435 alSetError(pContext
, AL_INVALID_ENUM
);
440 alSetError(pContext
, AL_INVALID_NAME
);
443 alSetError(pContext
, AL_INVALID_VALUE
);
445 ProcessContext(pContext
);
448 ALvoid ALAPIENTRY
alGetDatabufferfvEXT(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
450 ALCcontext
*pContext
;
453 pContext
= GetContextSuspended();
454 if(!pContext
) return;
458 Device
= pContext
->Device
;
459 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
464 alSetError(pContext
, AL_INVALID_ENUM
);
469 alSetError(pContext
, AL_INVALID_NAME
);
472 alSetError(pContext
, AL_INVALID_VALUE
);
474 ProcessContext(pContext
);
477 ALvoid ALAPIENTRY
alGetDatabufferiEXT(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
479 ALCcontext
*pContext
;
480 ALdatabuffer
*pBuffer
;
483 pContext
= GetContextSuspended();
484 if(!pContext
) return;
488 Device
= pContext
->Device
;
489 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, buffer
)) != NULL
)
494 *plValue
= pBuffer
->size
;
498 alSetError(pContext
, AL_INVALID_ENUM
);
503 alSetError(pContext
, AL_INVALID_NAME
);
506 alSetError(pContext
, AL_INVALID_VALUE
);
508 ProcessContext(pContext
);
511 ALvoid ALAPIENTRY
alGetDatabufferivEXT(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
513 ALCcontext
*pContext
;
516 pContext
= GetContextSuspended();
517 if(!pContext
) return;
521 Device
= pContext
->Device
;
522 if(VerifyDatabuffer(Device
->DatabufferList
, buffer
) != NULL
)
527 alGetDatabufferiEXT(buffer
, eParam
, plValues
);
531 alSetError(pContext
, AL_INVALID_ENUM
);
536 alSetError(pContext
, AL_INVALID_NAME
);
539 alSetError(pContext
, AL_INVALID_VALUE
);
541 ProcessContext(pContext
);
545 ALvoid ALAPIENTRY
alSelectDatabufferEXT(ALenum target
, ALuint uiBuffer
)
547 ALCcontext
*pContext
;
548 ALdatabuffer
*pBuffer
= NULL
;
551 pContext
= GetContextSuspended();
552 if(!pContext
) return;
554 Device
= pContext
->Device
;
556 (pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
558 if(target
== AL_SAMPLE_SOURCE_EXT
)
559 pContext
->SampleSource
= pBuffer
;
560 else if(target
== AL_SAMPLE_SINK_EXT
)
561 pContext
->SampleSink
= pBuffer
;
563 alSetError(pContext
, AL_INVALID_VALUE
);
566 alSetError(pContext
, AL_INVALID_NAME
);
568 ProcessContext(pContext
);
572 ALvoid
* ALAPIENTRY
alMapDatabufferEXT(ALuint uiBuffer
, ALintptrEXT start
, ALsizeiptrEXT length
, ALenum access
)
574 ALCcontext
*pContext
;
575 ALdatabuffer
*pBuffer
;
579 pContext
= GetContextSuspended();
580 if(!pContext
) return NULL
;
582 Device
= pContext
->Device
;
583 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
585 if(start
>= 0 && length
>= 0 && start
+length
<= pBuffer
->size
)
587 if(access
== AL_READ_ONLY_EXT
|| access
== AL_WRITE_ONLY_EXT
||
588 access
== AL_READ_WRITE_EXT
)
590 if(pBuffer
->state
== UNMAPPED
)
592 ret
= pBuffer
->data
+ start
;
593 pBuffer
->state
= MAPPED
;
596 alSetError(pContext
, AL_INVALID_OPERATION
);
599 alSetError(pContext
, AL_INVALID_ENUM
);
602 alSetError(pContext
, AL_INVALID_VALUE
);
605 alSetError(pContext
, AL_INVALID_NAME
);
607 ProcessContext(pContext
);
612 ALvoid ALAPIENTRY
alUnmapDatabufferEXT(ALuint uiBuffer
)
614 ALCcontext
*pContext
;
615 ALdatabuffer
*pBuffer
;
618 pContext
= GetContextSuspended();
619 if(!pContext
) return;
621 Device
= pContext
->Device
;
622 if((pBuffer
=VerifyDatabuffer(Device
->DatabufferList
, uiBuffer
)) != NULL
)
624 if(pBuffer
->state
== MAPPED
)
625 pBuffer
->state
= UNMAPPED
;
627 alSetError(pContext
, AL_INVALID_OPERATION
);
630 alSetError(pContext
, AL_INVALID_NAME
);
632 ProcessContext(pContext
);
637 * ReleaseALDatabuffers()
639 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
641 ALvoid
ReleaseALDatabuffers(ALCdevice
*device
)
643 ALdatabuffer
*ALBuffer
;
644 ALdatabuffer
*ALBufferTemp
;
646 ALBuffer
= device
->DatabufferList
;
649 // Release sample data
650 free(ALBuffer
->data
);
652 // Release Buffer structure
653 ALBufferTemp
= ALBuffer
;
654 ALBuffer
= ALBuffer
->next
;
655 memset(ALBufferTemp
, 0, sizeof(ALdatabuffer
));
658 device
->DatabufferList
= NULL
;
659 device
->DatabufferCount
= 0;