Initial commit and fixing/working around compiler errors
This commit is contained in:
commit
33737e8c99
437
COPYING
Normal file
437
COPYING
Normal file
|
@ -0,0 +1,437 @@
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, so that any problems introduced by others will not reflect on
|
||||||
|
the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the source code distributed need not include anything that is normally
|
||||||
|
distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
64
ChangeLog
Normal file
64
ChangeLog
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
Thu Jul 1 21:22:16 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.1.2 releaased.
|
||||||
|
|
||||||
|
* Added a top level README with information about the
|
||||||
|
hw_params error message.
|
||||||
|
|
||||||
|
* Added more example speaker configurations.
|
||||||
|
Put a description for each in the README.
|
||||||
|
|
||||||
|
* It seems Audigy cards have twice the channels in the send
|
||||||
|
mixer controls. Added support for this.
|
||||||
|
|
||||||
|
* Changed the way it looks for a compatable card.
|
||||||
|
Instead of looking for a card with a "emu10k1" pcm device.
|
||||||
|
It now looks for a card with a "EMU10K1 PCM Send Routing"
|
||||||
|
mixer control.
|
||||||
|
|
||||||
|
* Removed float->int in the inner plackback loop.
|
||||||
|
Used 16.16 fixed point instead.
|
||||||
|
This should give us a speed increase.
|
||||||
|
|
||||||
|
* Changed the default value for the doppler factor.
|
||||||
|
|
||||||
|
Mon Jun 28 18:28:57 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.1.1 released.
|
||||||
|
|
||||||
|
* Fixed buffering of 8bit mono data.
|
||||||
|
|
||||||
|
* Fixed a bug in the matrix multiply function.
|
||||||
|
|
||||||
|
Sun Jun 12 00:26:16 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.1.0 released.
|
||||||
|
|
||||||
|
* Don't call snd_pcm_start() unless there is actually
|
||||||
|
some data to play.
|
||||||
|
|
||||||
|
Fri Jun 11 23:29:45 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.0.4 released.
|
||||||
|
|
||||||
|
* Much tweeking of plackback internals.
|
||||||
|
|
||||||
|
* Added ALUT WAV file loading functions.
|
||||||
|
|
||||||
|
Tue Jun 8 19:46:43 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.0.3 released.
|
||||||
|
|
||||||
|
* Fixed speaker config file parsing.
|
||||||
|
|
||||||
|
* Made thread safe.
|
||||||
|
|
||||||
|
Thu Jun 4 07:39:00 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.0.2 released.
|
||||||
|
|
||||||
|
* Removed some debugging output.
|
||||||
|
|
||||||
|
Thu Jun 3 22:55:21 GMT 2004 C.J.Purnell (cjp@lost.org.uk)
|
||||||
|
|
||||||
|
* Version 0.0.1 released.
|
29
README
Normal file
29
README
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
The error:
|
||||||
|
|
||||||
|
ALSA lib pcm_hw.c:324:(snd_pcm_hw_hw_params) SNDRV_PCM_IOCTL_HW_PARAMS failed: Cannot allocate memory
|
||||||
|
|
||||||
|
can be safely ignored in most cases. It is just the application trying to
|
||||||
|
allocate more sources than there are free hardware resources to accomodate.
|
||||||
|
|
||||||
|
This library can provide at most 21 sources. It may be more in the future.
|
||||||
|
Less sources will the avaiable if another application is doing audio playback.
|
||||||
|
|
||||||
|
If you are using UT2004 you can supress this message most of the time by
|
||||||
|
modifying your ~/.ut2004/System/UT2004.ini as follows:
|
||||||
|
|
||||||
|
[ALAudio.ALAudioSubsystem]
|
||||||
|
Channels=20
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If on a Soundblaster Live, in your ~/.openal-speakers you have volumes set
|
||||||
|
for any more than the first two speakers you should manually zero the
|
||||||
|
following mixer controls:
|
||||||
|
|
||||||
|
Wave Surround Playback Volume
|
||||||
|
Wave Center Playback Volume
|
||||||
|
Wave LFE Playback Volume
|
||||||
|
|
||||||
|
You may not need to do this on an Audigy or Audigy2 but I've not been able to
|
||||||
|
test that.
|
||||||
|
|
86
etc/README
Normal file
86
etc/README
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
This directory contains example speaker configuration files.
|
||||||
|
To use one simple copy it to $HOME/.openal-speakers
|
||||||
|
|
||||||
|
The format is simple:
|
||||||
|
|
||||||
|
<n>: <gain> <x> <y> <z>
|
||||||
|
|
||||||
|
where <n> is a number indication which speaker:
|
||||||
|
|
||||||
|
0: front left
|
||||||
|
1: front right
|
||||||
|
2: rear left
|
||||||
|
3: rear right
|
||||||
|
4: center
|
||||||
|
5: lfe
|
||||||
|
6: side left
|
||||||
|
7: side right
|
||||||
|
|
||||||
|
<gain> is a per speaker gain control between 0.0 and 1.0.
|
||||||
|
Setting the gain to 0.0 disables output to the speaker.
|
||||||
|
|
||||||
|
<x> <y> <z> is the speaker position.
|
||||||
|
<x> is forward, <y> is up and <z> is to the right.
|
||||||
|
Only the direction of this vector is used.
|
||||||
|
|
||||||
|
Anything after a "#" is considered a comment.
|
||||||
|
|
||||||
|
speakers-mono:
|
||||||
|
|
||||||
|
This one is just simple example.
|
||||||
|
|
||||||
|
speakers-stereo:
|
||||||
|
|
||||||
|
This is the default configuration. If you are going to use this
|
||||||
|
you may as well not bother with a speakers file.
|
||||||
|
|
||||||
|
speakers-quadraphonic:
|
||||||
|
|
||||||
|
Fourpoint output. Each speaker placed in different corner of a square.
|
||||||
|
|
||||||
|
speakers-fivepoint-a:
|
||||||
|
|
||||||
|
This is what I'm told is the correct placement of speakers in a 5.1
|
||||||
|
setup. The front speakers are 30° from the center speaker and the rear
|
||||||
|
speakers are 110° from the center speaker. This is very front biased.
|
||||||
|
Due to they way I calculate the speaker gain/volume sound behind you ends up
|
||||||
|
being very quiet. I know there are schemes I could use that would allow for
|
||||||
|
this but they don't seems to cope very well with the lack of above of below
|
||||||
|
speakers.
|
||||||
|
|
||||||
|
speakers-fivepoint-b:
|
||||||
|
|
||||||
|
This is the five speakers placed evenly around the listener, such
|
||||||
|
that they are all 72° from their neighbours.
|
||||||
|
|
||||||
|
speakers-fivepoint-c:
|
||||||
|
|
||||||
|
This has the front are rear speakers placed the same as for the
|
||||||
|
quadraphonic configuration with the addition of the front speaker.
|
||||||
|
|
||||||
|
speakers-fivepoint-d:
|
||||||
|
|
||||||
|
This has the speakers each placed 60° from their neighbours. The
|
||||||
|
speakers would be placed evenly around the listener in this configuration
|
||||||
|
if there was a single rear speaker.
|
||||||
|
|
||||||
|
speakers-sevenpoint-a:
|
||||||
|
|
||||||
|
I have no idea what the correct placement for 7.1 systems is. This
|
||||||
|
is with the front three speakers placed the same as the 5.1 setup. The
|
||||||
|
side speakers are placed 90° from the front. And the rear are placed at
|
||||||
|
60° from their neighbours. The end result is a configuration where
|
||||||
|
everything would be placed evenly around the listener if you take away the
|
||||||
|
front speaker.
|
||||||
|
|
||||||
|
speakers-sevenpoint-b:
|
||||||
|
|
||||||
|
This is the seven speakers placed evenly around the listener.
|
||||||
|
This has them all at some funny angle from their neighbours.
|
||||||
|
|
||||||
|
speakers-sevenpoint-c:
|
||||||
|
|
||||||
|
This has the front and rear speakers placed the same as for the
|
||||||
|
quadraphonic configuration. And the side speakers are placed 90° from the
|
||||||
|
front. The speakers would be placed evenly around the listener in this
|
||||||
|
configuration with the addition of a rear center speaker.
|
8
etc/speakers-fivepoint-a
Normal file
8
etc/speakers-fivepoint-a
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.5 0 0.8860254
|
||||||
|
1: 1 0.5 0 0.8860254
|
||||||
|
2: 1 -0.93969262 0 -0.34202014
|
||||||
|
3: 1 0.93969262 0 -0.34202014
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-fivepoint-b
Normal file
8
etc/speakers-fivepoint-b
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.95105652 0 0.30916994
|
||||||
|
1: 1 0.95105652 0 0.30916994
|
||||||
|
2: 1 -0.58778525 0 -0.80901699
|
||||||
|
3: 1 0.58778525 0 -0.80901699
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-fivepoint-c
Normal file
8
etc/speakers-fivepoint-c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.70710678 0 0.70710678
|
||||||
|
1: 1 0.70710678 0 0.70710678
|
||||||
|
2: 1 -0.70710678 0 -0.70710678
|
||||||
|
3: 1 0.70710678 0 -0.70710678
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-fivepoint-d
Normal file
8
etc/speakers-fivepoint-d
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.8860254 0 0.5
|
||||||
|
1: 1 0.8860254 0 0.5
|
||||||
|
2: 1 -0.8860254 0 -0.5
|
||||||
|
3: 1 0.8860254 0 -0.5
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-mono
Normal file
8
etc/speakers-mono
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 0 0 0
|
||||||
|
1: 1 0 0 0
|
||||||
|
2: 0 0 0 0
|
||||||
|
3: 0 0 0 0
|
||||||
|
4: 0 0 0 0
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-quadraphonic
Normal file
8
etc/speakers-quadraphonic
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.70710678 0 0.70710678
|
||||||
|
1: 1 0.70710678 0 0.70710678
|
||||||
|
2: 1 -0.70710678 0 -0.70710678
|
||||||
|
3: 1 0.70710678 0 -0.70710678
|
||||||
|
4: 0 0 0 0
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
8
etc/speakers-sevenpoint-a
Normal file
8
etc/speakers-sevenpoint-a
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.5 0 0.8860254
|
||||||
|
1: 1 0.5 0 0.8860254
|
||||||
|
2: 1 -0.5 0 -0.8860254
|
||||||
|
3: 1 0.5 0 -0.8860254
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 1 -1 0 0
|
||||||
|
7: 1 1 0 0
|
8
etc/speakers-sevenpoint-b
Normal file
8
etc/speakers-sevenpoint-b
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.78183148 0 0.6234898
|
||||||
|
1: 1 0.78183148 0 0.6234898
|
||||||
|
2: 1 -0.43388374 0 -0.90096777
|
||||||
|
3: 1 0.43388374 0 -0.90096777
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 1 0.97492791 0 -0.22252093
|
||||||
|
7: 1 -0.97492791 0 -0.22252093
|
8
etc/speakers-sevenpoint-c
Normal file
8
etc/speakers-sevenpoint-c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -0.70710678 0 0.70710678
|
||||||
|
1: 1 0.70710678 0 0.70710678
|
||||||
|
2: 1 -0.70710678 0 -0.70710678
|
||||||
|
3: 1 0.70710678 0 -0.70710678
|
||||||
|
4: 1 0 0 1
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 1 -1 0 0
|
||||||
|
7: 1 1 0 0
|
8
etc/speakers-stereo
Normal file
8
etc/speakers-stereo
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
0: 1 -1 0 0
|
||||||
|
1: 1 1 0 0
|
||||||
|
2: 0 0 0 0
|
||||||
|
3: 0 0 0 0
|
||||||
|
4: 0 0 0 0
|
||||||
|
5: 0 0 0 0
|
||||||
|
6: 0 0 0 0
|
||||||
|
7: 0 0 0 0
|
642
include/AL/al.h
Normal file
642
include/AL/al.h
Normal file
|
@ -0,0 +1,642 @@
|
||||||
|
#ifndef __al_h_
|
||||||
|
#define __al_h_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAL cross platform audio library
|
||||||
|
* Copyright (C) 1999-2000 by authors.
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||||
|
*/
|
||||||
|
#include "altypes.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef _OPENAL32LIB
|
||||||
|
#define ALAPI __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define ALAPI __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#define ALAPIENTRY __cdecl
|
||||||
|
#define AL_CALLBACK
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export on
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#ifndef ALAPI
|
||||||
|
#define ALAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALAPIENTRY
|
||||||
|
#define ALAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CALLBACK
|
||||||
|
#define AL_CALLBACK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#define OPENAL
|
||||||
|
|
||||||
|
#ifndef AL_NO_PROTOTYPES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAL Maintenance Functions
|
||||||
|
* State Management and Query.
|
||||||
|
* Error Handling.
|
||||||
|
* Extension Support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** Renderer State management. */
|
||||||
|
ALAPI void ALAPIENTRY alEnable( ALenum capability );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alDisable( ALenum capability );
|
||||||
|
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsEnabled( ALenum capability );
|
||||||
|
|
||||||
|
/** Application preferences for driver performance choices. */
|
||||||
|
ALAPI void ALAPIENTRY alHint( ALenum target, ALenum mode );
|
||||||
|
|
||||||
|
/** State retrieval. */
|
||||||
|
ALAPI void ALAPIENTRY alGetBooleanv( ALenum param, ALboolean* data );
|
||||||
|
|
||||||
|
/** State retrieval. */
|
||||||
|
ALAPI void ALAPIENTRY alGetIntegerv( ALenum param, ALint* data );
|
||||||
|
|
||||||
|
/** State retrieval. */
|
||||||
|
ALAPI void ALAPIENTRY alGetFloatv( ALenum param, ALfloat* data );
|
||||||
|
|
||||||
|
/** State retrieval. */
|
||||||
|
ALAPI void ALAPIENTRY alGetDoublev( ALenum param, ALdouble* data );
|
||||||
|
|
||||||
|
/** State retrieval. */
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALAPI const ALubyte* ALAPIENTRY alGetString( ALenum param );
|
||||||
|
#else
|
||||||
|
ALAPI ALubyte* ALAPIENTRY alGetString( ALenum param );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** State retrieval.through return value ( for compatibility ) */
|
||||||
|
ALAPI ALboolean ALAPIENTRY alGetBoolean( ALenum param );
|
||||||
|
ALAPI ALint ALAPIENTRY alGetInteger( ALenum param );
|
||||||
|
ALAPI ALfloat ALAPIENTRY alGetFloat( ALenum param );
|
||||||
|
ALAPI ALdouble ALAPIENTRY alGetDouble( ALenum param );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error support.
|
||||||
|
* Obtain the most recent error generated in the AL state machine.
|
||||||
|
*/
|
||||||
|
ALAPI ALenum ALAPIENTRY alGetError( ALvoid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Obtain the address of a function (usually an extension)
|
||||||
|
* with the name fname. All addresses are context-independent.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsExtensionPresent( const ALubyte* fname );
|
||||||
|
#else
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsExtensionPresent( ALubyte* fname );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Obtain the address of a function (usually an extension)
|
||||||
|
* with the name fname. All addresses are context-independent.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALAPI void* ALAPIENTRY alGetProcAddress( const ALubyte* fname );
|
||||||
|
#else
|
||||||
|
ALAPI void* ALAPIENTRY alGetProcAddress( ALubyte* fname );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Obtain the integer value of an enumeration (usually an extension) with the name ename.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALAPI ALenum ALAPIENTRY alGetEnumValue( const ALubyte* ename );
|
||||||
|
#else
|
||||||
|
ALAPI ALenum ALAPIENTRY alGetEnumValue( ALubyte* ename );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LISTENER
|
||||||
|
* Listener is the sample position for a given context.
|
||||||
|
* The multi-channel (usually stereo) output stream generated
|
||||||
|
* by the mixer is parametrized by this Listener object:
|
||||||
|
* its position and velocity relative to Sources, within
|
||||||
|
* occluder and reflector geometry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Listener Gain: default 1.0f.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alListenerf( ALenum pname, ALfloat param );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alListeneri( ALenum pname, ALint param );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Listener Position: ALfloat[3]
|
||||||
|
* Listener Velocity: ALfloat[3]
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alListener3f( ALenum pname,
|
||||||
|
ALfloat f1, ALfloat f2, ALfloat f3 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Listener Position: ALfloat[3]
|
||||||
|
* Listener Velocity: ALfloat[3]
|
||||||
|
* Listener Orientation: ALfloat[6] (forward and up vector).
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alListenerfv( ALenum pname, ALfloat* param );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve listener information.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alGetListeneri( ALenum pname, ALint* value );
|
||||||
|
ALAPI void ALAPIENTRY alGetListenerf( ALenum pname, ALfloat* value );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* not defined under Windows and MacOS */
|
||||||
|
ALAPI void ALAPIENTRY alGetListeneriv( ALenum pname, ALint* value );
|
||||||
|
#endif
|
||||||
|
ALAPI void ALAPIENTRY alGetListenerfv( ALenum pname, ALfloat* values );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alGetListener3f( ALenum pname,
|
||||||
|
ALfloat *f1, ALfloat *f2, ALfloat *f3 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SOURCE
|
||||||
|
* Source objects are by default localized. Sources
|
||||||
|
* take the PCM data provided in the specified Buffer,
|
||||||
|
* apply Source-specific modifications, and then
|
||||||
|
* submit them to be mixed according to spatial
|
||||||
|
* arrangement etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Create Source objects. */
|
||||||
|
ALAPI void ALAPIENTRY alGenSources( ALsizei n, ALuint* sources );
|
||||||
|
|
||||||
|
/** Delete Source objects. */
|
||||||
|
ALAPI void ALAPIENTRY alDeleteSources( ALsizei n, ALuint* sources );
|
||||||
|
|
||||||
|
/** Verify a handle is a valid Source. */
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsSource( ALuint sid );
|
||||||
|
|
||||||
|
|
||||||
|
/** Set an integer parameter for a Source object. */
|
||||||
|
ALAPI void ALAPIENTRY alSourcei( ALuint sid, ALenum param, ALint value );
|
||||||
|
ALAPI void ALAPIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value );
|
||||||
|
ALAPI void ALAPIENTRY alSource3f( ALuint sid, ALenum param,
|
||||||
|
ALfloat f1, ALfloat f2, ALfloat f3 );
|
||||||
|
ALAPI void ALAPIENTRY alSourcefv( ALuint sid, ALenum param, ALfloat* values );
|
||||||
|
|
||||||
|
/** Get an integer parameter for a Source object. */
|
||||||
|
ALAPI void ALAPIENTRY alGetSourcei( ALuint sid, ALenum pname, ALint* value );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* not defined under Windows and MacOS */
|
||||||
|
ALAPI void ALAPIENTRY alGetSourceiv( ALuint sid, ALenum pname, ALint* values );
|
||||||
|
#endif
|
||||||
|
ALAPI void ALAPIENTRY alGetSourcef( ALuint sid, ALenum pname, ALfloat* value );
|
||||||
|
ALAPI void ALAPIENTRY alGetSourcefv( ALuint sid, ALenum pname, ALfloat* values );
|
||||||
|
|
||||||
|
/* deprecated, included for Win compatibility */
|
||||||
|
ALAPI void ALAPIENTRY alGetSource3f( ALuint sid, ALenum pname, ALfloat* value1,
|
||||||
|
ALfloat* value2, ALfloat* value3);
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alSourcePlayv( ALsizei ns, ALuint *ids );
|
||||||
|
ALAPI void ALAPIENTRY alSourceStopv( ALsizei ns, ALuint *ids );
|
||||||
|
ALAPI void ALAPIENTRY alSourceRewindv( ALsizei ns, ALuint *ids );
|
||||||
|
ALAPI void ALAPIENTRY alSourcePausev( ALsizei ns, ALuint *ids );
|
||||||
|
|
||||||
|
/** Activate a source, start replay. */
|
||||||
|
ALAPI void ALAPIENTRY alSourcePlay( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause a source,
|
||||||
|
* temporarily remove it from the mixer list.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alSourcePause( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind a source,
|
||||||
|
* set the source to play at the beginning.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alSourceRewind( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop a source,
|
||||||
|
* temporarily remove it from the mixer list,
|
||||||
|
* and reset its internal state to pre-Play.
|
||||||
|
* To remove a Source completely, it has to be
|
||||||
|
* deleted following Stop, or before Play.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alSourceStop( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BUFFER
|
||||||
|
* Buffer objects are storage space for sample data.
|
||||||
|
* Buffers are referred to by Sources. There can be more than
|
||||||
|
* one Source using the same Buffer data. If Buffers have
|
||||||
|
* to be duplicated on a per-Source basis, the driver has to
|
||||||
|
* take care of allocation, copying, and deallocation as well
|
||||||
|
* as propagating buffer data changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Buffer object generation. */
|
||||||
|
ALAPI void ALAPIENTRY alGenBuffers( ALsizei n, ALuint* buffers );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alDeleteBuffers( ALsizei n, ALuint* buffers );
|
||||||
|
|
||||||
|
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsBuffer( ALuint buffer );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the data to be filled into a buffer.
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alBufferData( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alGetBufferi( ALuint buffer, ALenum param, ALint* value );
|
||||||
|
ALAPI void ALAPIENTRY alGetBufferf( ALuint buffer, ALenum param, ALfloat* value );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* not defined under Windows and MacOS */
|
||||||
|
ALAPI void ALAPIENTRY alGetBufferiv( ALuint buffer, ALenum param, ALint *v);
|
||||||
|
ALAPI void ALAPIENTRY alGetBufferfv( ALuint buffer, ALenum param, ALfloat *v);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frequency Domain Filters are band filters.
|
||||||
|
* Attenuation in Media (distance based)
|
||||||
|
* Reflection Material
|
||||||
|
* Occlusion Material (separating surface)
|
||||||
|
*
|
||||||
|
* Temporal Domain Filters:
|
||||||
|
* Early Reflections
|
||||||
|
* Late Reverb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* IASIG stuff never really used -- will probably be removed from Linux as well */
|
||||||
|
/**
|
||||||
|
* EXTENSION: IASIG Level 2 Environment.
|
||||||
|
* Environment object generation.
|
||||||
|
* This is an EXTension that describes the Environment/Reverb
|
||||||
|
* properties according to IASIG Level 2 specifications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate n environment ids and store them in the array environs.
|
||||||
|
* Returns the number of environments actually allocated.
|
||||||
|
*/
|
||||||
|
ALAPI ALsizei ALAPIENTRY alGenEnvironmentIASIG( ALsizei n, ALuint* environs );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alDeleteEnvironmentIASIG( ALsizei n, ALuint* environs );
|
||||||
|
|
||||||
|
ALAPI ALboolean ALAPIENTRY alIsEnvironmentIASIG( ALuint environ );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alEnvironmentiIASIG( ALuint eid, ALenum param, ALint value );
|
||||||
|
|
||||||
|
ALAPI void ALAPIENTRY alEnvironmentfIASIG( ALuint eid, ALenum param, ALuint value );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue stuff
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||||
|
ALAPI void ALAPIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* function no longer used */
|
||||||
|
ALAPI void ALAPIENTRY alQueuei( ALuint sid, ALenum param, ALint value );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Knobs and dials
|
||||||
|
*/
|
||||||
|
ALAPI void ALAPIENTRY alDopplerFactor( ALfloat value );
|
||||||
|
ALAPI void ALAPIENTRY alDopplerVelocity( ALfloat value );
|
||||||
|
ALAPI void ALAPIENTRY alDistanceModel( ALenum distanceModel );
|
||||||
|
|
||||||
|
#else /* AL_NO_PROTOTYPES */
|
||||||
|
|
||||||
|
|
||||||
|
/** OpenAL Maintenance Functions */
|
||||||
|
|
||||||
|
void (*alEnable)( ALenum capability );
|
||||||
|
void (*alDisable)( ALenum capability );
|
||||||
|
ALboolean (*alIsEnabled)( ALenum capability );
|
||||||
|
void (*alHint)( ALenum target, ALenum mode );
|
||||||
|
ALboolean (*alGetBoolean)( ALenum param );
|
||||||
|
ALint (*alGetInteger)( ALenum param );
|
||||||
|
ALfloat (*alGetFloat)( ALenum param );
|
||||||
|
ALdouble (*alGetDouble)( ALenum param );
|
||||||
|
void (*alGetBooleanv)( ALenum param,
|
||||||
|
ALboolean* data );
|
||||||
|
void (*alGetIntegerv)( ALenum param,
|
||||||
|
ALint* data );
|
||||||
|
void (*alGetFloatv)( ALenum param,
|
||||||
|
ALfloat* data );
|
||||||
|
void (*alGetDoublev)( ALenum param,
|
||||||
|
ALdouble* data );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
const ALubyte* (*alGetString)( ALenum param );
|
||||||
|
#else
|
||||||
|
ALubyte* (*alGetString)( ALenum param );
|
||||||
|
#endif
|
||||||
|
ALenum (*alGetError)( ALvoid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Query existance of extension
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALboolean (*alIsExtensionPresent)(const ALubyte* fname );
|
||||||
|
#else
|
||||||
|
ALboolean (*alIsExtensionPresent)(ALubyte* fname );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Obtain the address of a function (usually an extension)
|
||||||
|
* with the name fname. All addresses are context-independent.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
void* (*alGetProcAddress)( const ALubyte* fname );
|
||||||
|
#else
|
||||||
|
void* (*alGetProcAddress)( ALubyte* fname );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension support.
|
||||||
|
* Obtain the integer value of an enumeration (usually an extension) with the name ename.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALenum (*alGetEnumValue)( const ALubyte* ename );
|
||||||
|
#else
|
||||||
|
ALenum (*alGetEnumValue)( ALubyte* ename);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LISTENER
|
||||||
|
* Listener is the sample position for a given context.
|
||||||
|
* The multi-channel (usually stereo) output stream generated
|
||||||
|
* by the mixer is parametrized by this Listener object:
|
||||||
|
* its position and velocity relative to Sources, within
|
||||||
|
* occluder and reflector geometry.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Listener Gain: default 1.0f.
|
||||||
|
*/
|
||||||
|
void (*alListenerf)( ALenum pname, ALfloat param );
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Listener Position: ALfloat[3]
|
||||||
|
* Listener Velocity: ALfloat[3]
|
||||||
|
* Listener Orientation: ALfloat[6] (forward and up vector).
|
||||||
|
*/
|
||||||
|
void (*alListenerfv)( ALenum pname, ALfloat* param );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve listener information.
|
||||||
|
*/
|
||||||
|
void (*alGetListeneri)( ALenum pname, ALint* value );
|
||||||
|
void (*alGetListenerf)( ALenum pname, ALfloat* value );
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
void (*alGetListeneriv)( ALenum pname, ALint* values );
|
||||||
|
#endif
|
||||||
|
void (*alGetListenerfv)( ALenum pname, ALfloat* values );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SOURCE
|
||||||
|
* Source objects are by default localized. Sources
|
||||||
|
* take the PCM data provided in the specified Buffer,
|
||||||
|
* apply Source-specific modifications, and then
|
||||||
|
* submit them to be mixed according to spatial
|
||||||
|
* arrangement etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Create Source objects. */
|
||||||
|
void (*alGenSources)( ALsizei n, ALuint* sources );
|
||||||
|
|
||||||
|
/** Delete Source objects. */
|
||||||
|
void (*alDeleteSources)( ALsizei n, ALuint* sources );
|
||||||
|
|
||||||
|
/** Verify a handle is a valid Source. */
|
||||||
|
ALboolean (*alIsSource)( ALuint sid );
|
||||||
|
|
||||||
|
/** Set an integer parameter for a Source object. */
|
||||||
|
void (*alSourcei)( ALuint sid, ALenum param, ALint value);
|
||||||
|
|
||||||
|
/** Set a float parameter for a Source object. */
|
||||||
|
void (*alSourcef)( ALuint sid, ALenum param, ALfloat value);
|
||||||
|
|
||||||
|
/** Set a 3 float parameter for a Source object. */
|
||||||
|
void (*alSource3f)( ALuint sid, ALenum param,
|
||||||
|
ALfloat f1, ALfloat f2, ALfloat f3 );
|
||||||
|
|
||||||
|
/** Set a float vector parameter for a Source object. */
|
||||||
|
void (*alSourcefv)( ALuint sid, ALenum param,
|
||||||
|
ALfloat* values );
|
||||||
|
|
||||||
|
/** Get an integer scalar parameter for a Source object. */
|
||||||
|
void (*alGetSourcei)( ALuint sid,
|
||||||
|
ALenum pname, ALint* value );
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/** Get an integer parameter for a Source object. */
|
||||||
|
void (*alGetSourceiv)( ALuint sid,
|
||||||
|
ALenum pname, ALint* values );
|
||||||
|
#endif
|
||||||
|
/** Get a float scalar parameter for a Source object. */
|
||||||
|
void (*alGetSourcef)( ALuint sid,
|
||||||
|
ALenum pname, ALfloat* value );
|
||||||
|
|
||||||
|
/** Get three float scalar parameter for a Source object. */
|
||||||
|
void (*alGetSource3f)( ALuint sid, ALenum pname,
|
||||||
|
ALfloat* value1,
|
||||||
|
ALfloat* value2,
|
||||||
|
ALfloat* value3);
|
||||||
|
|
||||||
|
/** Get a float vector parameter for a Source object. */
|
||||||
|
void (*alGetSourcefv)( ALuint sid,
|
||||||
|
ALenum pname, ALfloat* values );
|
||||||
|
|
||||||
|
|
||||||
|
/** Activate a source, start replay. */
|
||||||
|
void (*alSourcePlay)( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause a source,
|
||||||
|
* temporarily remove it from the mixer list.
|
||||||
|
*/
|
||||||
|
void (*alSourcePause)( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop a source,
|
||||||
|
* temporarily remove it from the mixer list,
|
||||||
|
* and reset its internal state to pre-Play.
|
||||||
|
* To remove a Source completely, it has to be
|
||||||
|
* deleted following Stop, or before Play.
|
||||||
|
*/
|
||||||
|
void (*alSourceStop)( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind a souce. Stopped paused and playing sources,
|
||||||
|
* resets the offset into the PCM data and sets state to
|
||||||
|
* AL_INITIAL.
|
||||||
|
*/
|
||||||
|
void (*alSourceRewind)( ALuint sid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vector forms of those functions we all love
|
||||||
|
*/
|
||||||
|
void (*alSourcePlayv)( ALsizei ns, ALuint *ids );
|
||||||
|
void (*alSourceStopv)( ALsizei ns, ALuint *ids );
|
||||||
|
void (*alSourceRewindv)( ALsizei ns, ALuint *ids );
|
||||||
|
void (*alSourcePausev)( ALsizei ns, ALuint *ids );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BUFFER
|
||||||
|
* Buffer objects are storage space for sample data.
|
||||||
|
* Buffers are referred to by Sources. There can be more than
|
||||||
|
* one Source using the same Buffer data. If Buffers have
|
||||||
|
* to be duplicated on a per-Source basis, the driver has to
|
||||||
|
* take care of allocation, copying, and deallocation as well
|
||||||
|
* as propagating buffer data changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Buffer object generation. */
|
||||||
|
void (*alGenBuffers)( ALsizei n, ALuint* buffers );
|
||||||
|
void (*alDeleteBuffers)( ALsizei n, ALuint* buffers );
|
||||||
|
ALboolean (*alIsBuffer)( ALuint buffer );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the data to be filled into a buffer.
|
||||||
|
*/
|
||||||
|
void (*alBufferData)( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq );
|
||||||
|
|
||||||
|
void (*alGetBufferi)( ALuint buffer,
|
||||||
|
ALenum param, ALint* value );
|
||||||
|
void (*alGetBufferf)( ALuint buffer,
|
||||||
|
ALenum param, ALfloat* value );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
void (*alGetBufferiv)( ALuint buffer,
|
||||||
|
ALenum param, ALint* value );
|
||||||
|
void (*alGetBufferfv)( ALuint buffer,
|
||||||
|
ALenum param, ALfloat* value );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/**
|
||||||
|
* EXTENSION: IASIG Level 2 Environment.
|
||||||
|
* Environment object generation.
|
||||||
|
* This is an EXTension that describes the Environment/Reverb
|
||||||
|
* properties according to IASIG Level 2 specifications.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Allocate n environment ids and store them in the array environs.
|
||||||
|
* Returns the number of environments actually allocated.
|
||||||
|
*/
|
||||||
|
ALsizei (*alGenEnvironmentIASIG)( ALsizei n, ALuint* environs );
|
||||||
|
void (*alDeleteEnvironmentIASIG)(ALsizei n,
|
||||||
|
ALuint* environs);
|
||||||
|
ALboolean (*alIsEnvironmentIASIG)( ALuint environ );
|
||||||
|
void (*alEnvironmentiIASIG)( ALuint eid,
|
||||||
|
ALenum param, ALint value );
|
||||||
|
void (*alEnvironmentfIASIG)( ALuint eid,
|
||||||
|
ALenum param, ALuint value );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue stuff
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
void (*alQueuei)(ALuint sid, ALenum param, ALint value );
|
||||||
|
#endif
|
||||||
|
void (*alSourceUnqueueBuffers)(ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||||
|
void (*alSourceQueueBuffers)(ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||||
|
|
||||||
|
void (*alDopplerFactor)( ALfloat value );
|
||||||
|
void (*alDopplerVelocity)( ALfloat value );
|
||||||
|
void (*alDistanceModel)( ALenum distanceModel );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frequency Domain Filters are band filters.
|
||||||
|
* Attenuation in Media (distance based)
|
||||||
|
* Reflection Material
|
||||||
|
* Occlusion Material (separating surface)
|
||||||
|
*
|
||||||
|
* Temporal Domain Filters:
|
||||||
|
* Early Reflections
|
||||||
|
* Late Reverb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* AL_NO_PROTOTYPES */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export off
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __al_h_ */
|
163
include/AL/alc.h
Normal file
163
include/AL/alc.h
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
#ifndef ALC_CONTEXT_H_
|
||||||
|
#define ALC_CONTEXT_H_
|
||||||
|
|
||||||
|
#include "altypes.h"
|
||||||
|
#include "alctypes.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALC_VERSION_0_1 1
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef _OPENAL32LIB
|
||||||
|
#define ALCAPI __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define ALCAPI __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ALCdevice_struct ALCdevice;
|
||||||
|
typedef struct ALCcontext_struct ALCcontext;
|
||||||
|
|
||||||
|
#define ALCAPIENTRY __cdecl
|
||||||
|
#else
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export on
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALCAPI
|
||||||
|
#define ALCAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_NO_PROTOTYPES
|
||||||
|
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY alcCreateContext( ALCdevice *dev,
|
||||||
|
ALCint* attrlist );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There is no current context, as we can mix
|
||||||
|
* several active contexts. But al* calls
|
||||||
|
* only affect the current context.
|
||||||
|
*/
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* spec has return value as ALCboolean */
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY alcMakeContextCurrent( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *alcHandle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform processing on a synced context, non-op on a asynchronous
|
||||||
|
* context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* spec has return value as void */
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY alcProcessContext( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALvoid ALCAPIENTRY alcProcessContext(ALCcontext* context);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend processing on an asynchronous context, non-op on a
|
||||||
|
* synced context.
|
||||||
|
*/
|
||||||
|
ALCAPI void ALCAPIENTRY alcSuspendContext( ALCcontext *alcHandle );
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* spec has return value as void */
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY alcDestroyContext( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALvoid ALCAPIENTRY alcDestroyContext(ALCcontext* context);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY alcGetError( ALCdevice *dev );
|
||||||
|
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY alcGetCurrentContext( ALvoid );
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI ALCdevice * ALCAPIENTRY alcOpenDevice( const ALubyte *tokstr );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCdevice * ALCAPIENTRY alcOpenDevice( ALubyte *tokstr );
|
||||||
|
#endif
|
||||||
|
ALCAPI void ALCAPIENTRY alcCloseDevice( ALCdevice *dev );
|
||||||
|
|
||||||
|
ALCAPI ALCboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice *device, ALCubyte *extName);
|
||||||
|
ALCAPI ALCvoid * ALCAPIENTRY alcGetProcAddress(ALCdevice *device, ALCubyte *funcName);
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY alcGetEnumValue(ALCdevice *device, ALCubyte *enumName);
|
||||||
|
|
||||||
|
ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *context);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
const ALCubyte * ALCAPIENTRY alcGetString( ALCdevice *deviceHandle, ALCenum token );
|
||||||
|
#else
|
||||||
|
ALCAPI ALubyte* ALCAPIENTRY alcGetString(ALCdevice* device, ALenum param);
|
||||||
|
#endif
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI void ALCAPIENTRY alcGetIntegerv( ALCdevice *deviceHandle, ALCenum token , ALCsizei size , ALCint *dest );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALCsizei size,ALCint *data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY (*alcCreateContext)( ALCdevice *dev, ALCint* attrlist );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY (*alcMakeContextCurrent)( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCboolean ALCAPIENTRY (*alcMakeContextCurrent)(ALCcontext *context);
|
||||||
|
#endif
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY (*alcProcessContext)( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCvoid * ALCAPIENTRY (*alcProcessContext)( ALCcontext *alcHandle );
|
||||||
|
#endif
|
||||||
|
ALCAPI void ALCAPIENTRY (*alcSuspendContext)( ALCcontext *alcHandle );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY (*alcDestroyContext)( ALCcontext *alcHandle );
|
||||||
|
#else
|
||||||
|
ALCAPI ALvoid ALCAPIENTRY (*alcDestroyContext)( ALCcontext* context );
|
||||||
|
#endif
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY (*alcGetError)( ALCdevice *dev );
|
||||||
|
ALCAPI ALCcontext * ALCAPIENTRY (*alcGetCurrentContext)( ALCvoid );
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI ALCdevice * ALCAPIENTRY (*alcOpenDevice)( const ALCubyte *tokstr );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCdevice * ALCAPIENTRY (*alcOpenDevice)( ALubyte *tokstr );
|
||||||
|
#endif
|
||||||
|
ALCAPI void ALCAPIENTRY (*alcCloseDevice)( ALCdevice *dev );
|
||||||
|
ALCAPI ALCboolean ALCAPIENTRY (*alcIsExtensionPresent)( ALCdevice *device, ALCubyte *extName );
|
||||||
|
ALCAPI ALCvoid * ALCAPIENTRY (*alcGetProcAddress)(ALCdevice *device, ALCubyte *funcName );
|
||||||
|
ALCAPI ALCenum ALCAPIENTRY (*alcGetEnumValue)(ALCdevice *device, ALCubyte *enumName);
|
||||||
|
ALCAPI ALCdevice* ALCAPIENTRY (*alcGetContextsDevice)(ALCcontext *context);
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI const ALCubyte* ALCAPIENTRY (*alcGetString)( ALCdevice *deviceHandle, ALCenum token );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCubyte* ALCAPIENTRY (*alcGetString)( ALCdevice *deviceHandle, ALCenum token );
|
||||||
|
#endif
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
ALCAPI void ALCAPIENTRY (*alcGetIntegerv*)( ALCdevice *deviceHandle, ALCenum token , ALCsizei size , ALCint *dest );
|
||||||
|
#else
|
||||||
|
ALCAPI ALCvoid ALCAPIENTRY (*alcGetIntegerv*)( ALCdevice *deviceHandle, ALCenum token , ALCsizei size , ALCint *dest );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AL_NO_PROTOTYPES */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export off
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ALC_CONTEXT_H_ */
|
121
include/AL/alctypes.h
Normal file
121
include/AL/alctypes.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#ifndef _ALCTYPES_H_
|
||||||
|
#define _ALCTYPES_H_
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
struct _AL_device;
|
||||||
|
typedef struct _AL_device ALCdevice;
|
||||||
|
|
||||||
|
typedef void ALCcontext;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
typedef int ALCenum;
|
||||||
|
|
||||||
|
/** ALC boolean type. */
|
||||||
|
typedef char ALCboolean;
|
||||||
|
|
||||||
|
/** ALC 8bit signed byte. */
|
||||||
|
typedef char ALCbyte;
|
||||||
|
|
||||||
|
/** ALC 8bit unsigned byte. */
|
||||||
|
typedef unsigned char ALCubyte;
|
||||||
|
|
||||||
|
/** ALC 16bit signed short integer type. */
|
||||||
|
typedef short ALCshort;
|
||||||
|
|
||||||
|
/** ALC 16bit unsigned short integer type. */
|
||||||
|
typedef unsigned short ALCushort;
|
||||||
|
|
||||||
|
/** ALC 32bit unsigned integer type. */
|
||||||
|
typedef unsigned ALCuint;
|
||||||
|
|
||||||
|
/** ALC 32bit signed integer type. */
|
||||||
|
typedef int ALCint;
|
||||||
|
|
||||||
|
/** ALC 32bit floating point type. */
|
||||||
|
typedef float ALCfloat;
|
||||||
|
|
||||||
|
/** ALC 64bit double point type. */
|
||||||
|
typedef double ALCdouble;
|
||||||
|
|
||||||
|
/** ALC 32bit type. */
|
||||||
|
typedef unsigned int ALCsizei;
|
||||||
|
|
||||||
|
/** ALC void type */
|
||||||
|
typedef void ALCvoid;
|
||||||
|
|
||||||
|
/* Enumerant values begin at column 50. No tabs. */
|
||||||
|
|
||||||
|
/* bad value */
|
||||||
|
#define ALC_INVALID 0
|
||||||
|
|
||||||
|
/* Boolean False. */
|
||||||
|
#define ALC_FALSE 0
|
||||||
|
|
||||||
|
/* Boolean True. */
|
||||||
|
#define ALC_TRUE 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* followed by <int> Hz
|
||||||
|
*/
|
||||||
|
#define ALC_FREQUENCY 0x1007
|
||||||
|
|
||||||
|
/**
|
||||||
|
* followed by <int> Hz
|
||||||
|
*/
|
||||||
|
#define ALC_REFRESH 0x1008
|
||||||
|
|
||||||
|
/**
|
||||||
|
* followed by AL_TRUE, AL_FALSE
|
||||||
|
*/
|
||||||
|
#define ALC_SYNC 0x1009
|
||||||
|
|
||||||
|
/**
|
||||||
|
* errors
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No error
|
||||||
|
*/
|
||||||
|
#define ALC_NO_ERROR ALC_FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No device
|
||||||
|
*/
|
||||||
|
#define ALC_INVALID_DEVICE 0xA001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* invalid context ID
|
||||||
|
*/
|
||||||
|
#define ALC_INVALID_CONTEXT 0xA002
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bad enum
|
||||||
|
*/
|
||||||
|
#define ALC_INVALID_ENUM 0xA003
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bad value
|
||||||
|
*/
|
||||||
|
#define ALC_INVALID_VALUE 0xA004
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Out of memory.
|
||||||
|
*/
|
||||||
|
#define ALC_OUT_OF_MEMORY 0xA005
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Specifier string for default device
|
||||||
|
*/
|
||||||
|
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||||
|
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||||
|
#define ALC_EXTENSIONS 0x1006
|
||||||
|
|
||||||
|
#define ALC_MAJOR_VERSION 0x1000
|
||||||
|
#define ALC_MINOR_VERSION 0x1001
|
||||||
|
|
||||||
|
#define ALC_ATTRIBUTES_SIZE 0x1002
|
||||||
|
#define ALC_ALL_ATTRIBUTES 0x1003
|
||||||
|
|
||||||
|
#endif /* _ALCTYPES_H */
|
76
include/AL/alext.h
Normal file
76
include/AL/alext.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef _LAL_EXT_H_
|
||||||
|
#define _LAL_EXT_H_
|
||||||
|
|
||||||
|
#include "AL/altypes.h"
|
||||||
|
#include "alexttypes.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALAPI
|
||||||
|
#define ALAPI extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALAPIENTRY
|
||||||
|
#define ALAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* loki */
|
||||||
|
|
||||||
|
ALAPI ALfloat alcGetAudioChannel_LOKI(ALuint channel);
|
||||||
|
ALAPI void alcSetAudioChannel_LOKI(ALuint channel, ALfloat volume);
|
||||||
|
ALAPI void alBombOnError_LOKI(void);
|
||||||
|
ALAPI void alBufferi_LOKI(ALuint bid, ALenum param, ALint value);
|
||||||
|
ALAPI void alBufferDataWithCallback_LOKI(ALuint bid,
|
||||||
|
int (*Callback)(ALuint, ALuint, ALshort *, ALenum, ALint, ALint));
|
||||||
|
|
||||||
|
ALAPI void alBufferWriteData_LOKI( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq,
|
||||||
|
ALenum internalFormat );
|
||||||
|
ALAPI void ALAPIENTRY alGenStreamingBuffers_LOKI( ALsizei n, ALuint *samples );
|
||||||
|
ALAPI ALsizei alBufferAppendData_LOKI( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq );
|
||||||
|
|
||||||
|
ALAPI ALsizei alBufferAppendWriteData_LOKI( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq,
|
||||||
|
ALenum internalFormat );
|
||||||
|
|
||||||
|
/* Capture api */
|
||||||
|
|
||||||
|
ALAPI ALboolean alCaptureInit_EXT( ALenum format, ALuint rate, ALsizei bufferSize );
|
||||||
|
ALAPI ALboolean alCaptureDestroy_EXT( ALvoid );
|
||||||
|
ALAPI ALboolean alCaptureStart_EXT( ALvoid );
|
||||||
|
ALAPI ALboolean alCaptureStop_EXT( ALvoid );
|
||||||
|
|
||||||
|
/* Non-blocking device read */
|
||||||
|
ALAPI ALsizei alCaptureGetData_EXT( ALvoid* data, ALsizei n, ALenum format, ALuint rate );
|
||||||
|
|
||||||
|
/* custom loaders */
|
||||||
|
ALAPI ALboolean alutLoadVorbis_LOKI(ALuint bid, ALvoid *data, ALint size);
|
||||||
|
ALAPI ALboolean ALAPIENTRY alutLoadRAW_ADPCMData_LOKI(ALuint bid, ALvoid *data,
|
||||||
|
ALuint size, ALuint freq,
|
||||||
|
ALenum format);
|
||||||
|
|
||||||
|
ALAPI ALboolean ALAPIENTRY alutLoadIMA_ADPCMData_LOKI(ALuint bid, ALvoid *data,
|
||||||
|
ALuint size,
|
||||||
|
alIMAADPCM_state_LOKI *ias);
|
||||||
|
ALAPI ALboolean ALAPIENTRY alutLoadMS_ADPCMData_LOKI(ALuint bid,
|
||||||
|
void *data, int size,
|
||||||
|
alMSADPCM_state_LOKI *mss);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LAL_EXT_H_ */
|
161
include/AL/alexttypes.h
Normal file
161
include/AL/alexttypes.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
#ifndef _LAL_EXTTYPES_H_
|
||||||
|
#define _LAL_EXTTYPES_H_
|
||||||
|
|
||||||
|
#define LAL_OPENAL 1
|
||||||
|
|
||||||
|
/* format base 0x10000 */
|
||||||
|
#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
|
||||||
|
#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
|
||||||
|
#define AL_FORMAT_WAVE_EXT 0x10002
|
||||||
|
#define AL_FORMAT_VORBIS_EXT 0x10003
|
||||||
|
|
||||||
|
/* four point formats */
|
||||||
|
#define AL_FORMAT_QUAD8_LOKI 0x10004
|
||||||
|
#define AL_FORMAT_QUAD16_LOKI 0x10005
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token extensions, base 0x20000
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Indicate the gain (volume amplification) applied, in a
|
||||||
|
* normalized linear scale. This affects the value retrieved
|
||||||
|
* by AL_GAIN.
|
||||||
|
*
|
||||||
|
* Type: ALfloat.
|
||||||
|
* Range: ]0.0- ]
|
||||||
|
* A value of 1.0 means un-attenuated/unchanged.
|
||||||
|
* A value of 0.0 is interpreted as zero volume - the channel
|
||||||
|
* is effectively disabled.
|
||||||
|
*/
|
||||||
|
#define AL_GAIN_LINEAR_LOKI 0x20000
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* types for special loaders. This should be deprecated in favor
|
||||||
|
* of the special format tags.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct WaveFMT {
|
||||||
|
ALushort encoding;
|
||||||
|
ALushort channels; /* 1 = mono, 2 = stereo */
|
||||||
|
ALuint frequency; /* One of 11025, 22050, or 44100 Hz */
|
||||||
|
ALuint byterate; /* Average bytes per second */
|
||||||
|
ALushort blockalign; /* Bytes per sample block */
|
||||||
|
ALushort bitspersample;
|
||||||
|
} alWaveFMT_LOKI;
|
||||||
|
|
||||||
|
typedef struct _MS_ADPCM_decodestate {
|
||||||
|
ALubyte hPredictor;
|
||||||
|
ALushort iDelta;
|
||||||
|
ALshort iSamp1;
|
||||||
|
ALshort iSamp2;
|
||||||
|
} alMSADPCM_decodestate_LOKI;
|
||||||
|
|
||||||
|
typedef struct MS_ADPCM_decoder {
|
||||||
|
alWaveFMT_LOKI wavefmt;
|
||||||
|
ALushort wSamplesPerBlock;
|
||||||
|
ALushort wNumCoef;
|
||||||
|
ALshort aCoeff[7][2];
|
||||||
|
/* * * */
|
||||||
|
alMSADPCM_decodestate_LOKI state[2];
|
||||||
|
} alMSADPCM_state_LOKI;
|
||||||
|
|
||||||
|
typedef struct IMA_ADPCM_decodestate_s {
|
||||||
|
ALint valprev; /* Previous output value */
|
||||||
|
ALbyte index; /* Index into stepsize table */
|
||||||
|
} alIMAADPCM_decodestate_LOKI;
|
||||||
|
|
||||||
|
typedef struct IMA_ADPCM_decoder {
|
||||||
|
alWaveFMT_LOKI wavefmt;
|
||||||
|
ALushort wSamplesPerBlock;
|
||||||
|
/* * * */
|
||||||
|
alIMAADPCM_decodestate_LOKI state[2];
|
||||||
|
} alIMAADPCM_state_LOKI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context creation extension tokens
|
||||||
|
* base 0x200000
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* followed by ### of sources
|
||||||
|
*/
|
||||||
|
#define ALC_SOURCES_LOKI 0x200000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* followed by ### of buffers
|
||||||
|
*/
|
||||||
|
#define ALC_BUFFERS_LOKI 0x200001
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Channel operations are probably a big no-no and destined
|
||||||
|
* for obsolesence.
|
||||||
|
*
|
||||||
|
* base 0x300000
|
||||||
|
*/
|
||||||
|
#define ALC_CHAN_MAIN_LOKI 0x300000
|
||||||
|
#define ALC_CHAN_PCM_LOKI 0x300001
|
||||||
|
#define ALC_CHAN_CD_LOKI 0x300002
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*PFNALCSETAUDIOCHANNELPROC)(ALuint channel, ALfloat volume);
|
||||||
|
typedef ALfloat (*PFNALCGETAUDIOCHANNELPROC)(ALuint channel);
|
||||||
|
typedef void (*PFNALBOMBONERRORPROC)(void);
|
||||||
|
|
||||||
|
typedef void (*PFNALBUFFERIPROC)(ALuint bid, ALenum param, ALint value);
|
||||||
|
|
||||||
|
typedef void (*PFNALBUFFERDATAWITHCALLBACKPROC)(ALuint bid,
|
||||||
|
int (*Callback)(ALuint, ALuint, ALshort *, ALenum, ALint, ALint));
|
||||||
|
|
||||||
|
typedef void (*PFNALBUFFERWRITEDATAPROC)( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq,
|
||||||
|
ALenum internalFormat );
|
||||||
|
|
||||||
|
typedef void (*PFNALGENSTREAMINGBUFFERSPROC)( ALsizei n, ALuint *samples );
|
||||||
|
|
||||||
|
typedef ALsizei (*PFNALBUFFERAPPENDDATAPROC)( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq );
|
||||||
|
|
||||||
|
typedef ALsizei (*PFNALBUFFERAPPENDWRITEDATAPROC)( ALuint buffer,
|
||||||
|
ALenum format,
|
||||||
|
ALvoid* data,
|
||||||
|
ALsizei size,
|
||||||
|
ALsizei freq,
|
||||||
|
ALenum internalFormat );
|
||||||
|
|
||||||
|
/* captures */
|
||||||
|
|
||||||
|
typedef ALboolean (*PFNALCAPTUREINITPROC)( ALenum format, ALuint rate, ALsizei bufferSize );
|
||||||
|
|
||||||
|
typedef ALboolean (*PFNALCAPTUREDESTROYPROC)( ALvoid );
|
||||||
|
|
||||||
|
typedef ALboolean (*PFNALCAPTURESTARTPROC)( ALvoid );
|
||||||
|
|
||||||
|
typedef ALboolean (*PFNALCAPTURESTOPPROC)( ALvoid );
|
||||||
|
|
||||||
|
/* Non-blocking device read */
|
||||||
|
typedef ALsizei (*PFNALCAPTUREGETDATAPROC)( ALvoid* data, ALsizei n, ALenum format, ALuint rate );
|
||||||
|
|
||||||
|
/* vorbis */
|
||||||
|
typedef ALboolean (*PFNALUTLOADVORBISPROC)(ALuint bid, ALvoid *data, ALint size);
|
||||||
|
|
||||||
|
/* custom loaders */
|
||||||
|
typedef ALboolean (*PFNALUTLOADRAW_ADPCMDATAPROC)( ALuint bid,
|
||||||
|
ALvoid *data, ALuint size, ALuint freq,
|
||||||
|
ALenum format);
|
||||||
|
|
||||||
|
typedef ALboolean (*ALUTLOADIMA_ADPCMDATAPROC)(ALuint bid,
|
||||||
|
ALvoid *data, ALuint size,
|
||||||
|
alIMAADPCM_state_LOKI *ias);
|
||||||
|
|
||||||
|
typedef ALboolean (*ALUTLOADMS_ADPCMDATAPROC)(ALuint bid,
|
||||||
|
void *data, int size,
|
||||||
|
alMSADPCM_state_LOKI *mss);
|
||||||
|
|
||||||
|
#endif /* _LAL_EXTTYPES_H_ */
|
484
include/AL/altypes.h
Normal file
484
include/AL/altypes.h
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
#ifndef _AL_TYPES_H_
|
||||||
|
#define _AL_TYPES_H_
|
||||||
|
|
||||||
|
/* define platform type */
|
||||||
|
#if !defined(MACINTOSH_AL) && !defined(LINUX_AL) && !defined(WINDOWS_AL)
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define MACINTOSH_AL
|
||||||
|
#else
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WINDOWS_AL
|
||||||
|
#else
|
||||||
|
#define LINUX_AL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** OpenAL bool type. */
|
||||||
|
typedef char ALboolean;
|
||||||
|
|
||||||
|
/** OpenAL 8bit signed byte. */
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
typedef signed char ALbyte;
|
||||||
|
#else
|
||||||
|
typedef char ALbyte;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** OpenAL 8bit unsigned byte. */
|
||||||
|
typedef unsigned char ALubyte;
|
||||||
|
|
||||||
|
/** OpenAL 16bit signed short integer type. */
|
||||||
|
typedef short ALshort;
|
||||||
|
|
||||||
|
/** OpenAL 16bit unsigned short integer type. */
|
||||||
|
typedef unsigned short ALushort;
|
||||||
|
|
||||||
|
/** OpenAL 32bit unsigned integer type. */
|
||||||
|
typedef unsigned int ALuint;
|
||||||
|
|
||||||
|
/** OpenAL 32bit signed integer type. */
|
||||||
|
typedef int ALint;
|
||||||
|
|
||||||
|
/** OpenAL 32bit floating point type. */
|
||||||
|
typedef float ALfloat;
|
||||||
|
|
||||||
|
/** OpenAL 64bit double point type. */
|
||||||
|
typedef double ALdouble;
|
||||||
|
|
||||||
|
/** OpenAL 32bit type. */
|
||||||
|
/** OpenAL 8bit signed byte. */
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
typedef signed int ALsizei;
|
||||||
|
#else
|
||||||
|
typedef unsigned int ALsizei;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** OpenAL void type (for params, not returns). */
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
typedef void ALvoid;
|
||||||
|
#else
|
||||||
|
#define ALvoid void
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** OpenAL enumerations. */
|
||||||
|
typedef int ALenum;
|
||||||
|
|
||||||
|
/** OpenAL bitfields. */
|
||||||
|
typedef unsigned int ALbitfield;
|
||||||
|
|
||||||
|
/** OpenAL clamped float. */
|
||||||
|
typedef ALfloat ALclampf;
|
||||||
|
|
||||||
|
/** Openal clamped double. */
|
||||||
|
typedef ALdouble ALclampd;
|
||||||
|
|
||||||
|
/* Enumerant values begin at column 50. No tabs. */
|
||||||
|
|
||||||
|
/* bad value */
|
||||||
|
#define AL_INVALID -1
|
||||||
|
|
||||||
|
#define AL_NONE 0
|
||||||
|
|
||||||
|
/* Boolean False. */
|
||||||
|
#define AL_FALSE 0
|
||||||
|
|
||||||
|
/** Boolean True. */
|
||||||
|
#define AL_TRUE 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate the type of AL_SOURCE.
|
||||||
|
* Sources can be spatialized
|
||||||
|
*/
|
||||||
|
#define AL_SOURCE_TYPE 0x200
|
||||||
|
|
||||||
|
/** Indicate source has absolute coordinates. */
|
||||||
|
#define AL_SOURCE_ABSOLUTE 0x201
|
||||||
|
|
||||||
|
/** Indicate Source has relative coordinates. */
|
||||||
|
#define AL_SOURCE_RELATIVE 0x202
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directional source, inner cone angle, in degrees.
|
||||||
|
* Range: [0-360]
|
||||||
|
* Default: 360
|
||||||
|
*/
|
||||||
|
#define AL_CONE_INNER_ANGLE 0x1001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directional source, outer cone angle, in degrees.
|
||||||
|
* Range: [0-360]
|
||||||
|
* Default: 360
|
||||||
|
*/
|
||||||
|
#define AL_CONE_OUTER_ANGLE 0x1002
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the pitch to be applied, either at source,
|
||||||
|
* or on mixer results, at listener.
|
||||||
|
* Range: [0.5-2.0]
|
||||||
|
* Default: 1.0
|
||||||
|
*/
|
||||||
|
#define AL_PITCH 0x1003
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the current location in three dimensional space.
|
||||||
|
* OpenAL, like OpenGL, uses a right handed coordinate system,
|
||||||
|
* where in a frontal default view X (thumb) points right,
|
||||||
|
* Y points up (index finger), and Z points towards the
|
||||||
|
* viewer/camera (middle finger).
|
||||||
|
* To switch from a left handed coordinate system, flip the
|
||||||
|
* sign on the Z coordinate.
|
||||||
|
* Listener position is always in the world coordinate system.
|
||||||
|
*/
|
||||||
|
#define AL_POSITION 0x1004
|
||||||
|
|
||||||
|
/** Specify the current direction. */
|
||||||
|
#define AL_DIRECTION 0x1005
|
||||||
|
|
||||||
|
/** Specify the current velocity in three dimensional space. */
|
||||||
|
#define AL_VELOCITY 0x1006
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate whether source is looping.
|
||||||
|
* Type: ALboolean?
|
||||||
|
* Range: [AL_TRUE, AL_FALSE]
|
||||||
|
* Default: FALSE.
|
||||||
|
*/
|
||||||
|
#define AL_LOOPING 0x1007
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* no longer used -- will probably be removed */
|
||||||
|
/**
|
||||||
|
* Indicate whether source is meant to be streaming.
|
||||||
|
* Type: ALboolean?
|
||||||
|
* Range: [AL_TRUE, AL_FALSE]
|
||||||
|
* Default: FALSE.
|
||||||
|
*/
|
||||||
|
#define AL_STREAMING 0x1008
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate the buffer to provide sound samples.
|
||||||
|
* Type: ALuint.
|
||||||
|
* Range: any valid Buffer id.
|
||||||
|
*/
|
||||||
|
#define AL_BUFFER 0x1009
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate the gain (volume amplification) applied.
|
||||||
|
* Type: ALfloat.
|
||||||
|
* Range: ]0.0- ]
|
||||||
|
* A value of 1.0 means un-attenuated/unchanged.
|
||||||
|
* Each division by 2 equals an attenuation of -6dB.
|
||||||
|
* Each multiplicaton with 2 equals an amplification of +6dB.
|
||||||
|
* A value of 0.0 is meaningless with respect to a logarithmic
|
||||||
|
* scale; it is interpreted as zero volume - the channel
|
||||||
|
* is effectively disabled.
|
||||||
|
*/
|
||||||
|
#define AL_GAIN 0x100A
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* byte offset into source (in canon format). -1 if source
|
||||||
|
* is not playing. Don't set this, get this.
|
||||||
|
*
|
||||||
|
* Type: ALint
|
||||||
|
* Range: -1 - +inf
|
||||||
|
*/
|
||||||
|
#define AL_BYTE_LOKI 0x100C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicate minimum source attenuation
|
||||||
|
* Type: ALfloat
|
||||||
|
* Range: [0.0 - 1.0]
|
||||||
|
*
|
||||||
|
* Logarthmic
|
||||||
|
*/
|
||||||
|
#define AL_MIN_GAIN 0x100D
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate maximum source attenuation
|
||||||
|
* Type: ALfloat
|
||||||
|
* Range: [0.0 - 1.0]
|
||||||
|
*
|
||||||
|
* Logarthmic
|
||||||
|
*/
|
||||||
|
#define AL_MAX_GAIN 0x100E
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate listener orientation.
|
||||||
|
*
|
||||||
|
* at/up
|
||||||
|
*/
|
||||||
|
#define AL_ORIENTATION 0x100F
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the channel mask. (Creative)
|
||||||
|
* Type: ALuint
|
||||||
|
* Range: [0 - 255]
|
||||||
|
*/
|
||||||
|
#define AL_CHANNEL_MASK 0x3000
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source state information.
|
||||||
|
*/
|
||||||
|
#define AL_SOURCE_STATE 0x1010
|
||||||
|
#define AL_INITIAL 0x1011
|
||||||
|
#define AL_PLAYING 0x1012
|
||||||
|
#define AL_PAUSED 0x1013
|
||||||
|
#define AL_STOPPED 0x1014
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer Queue params
|
||||||
|
*/
|
||||||
|
#define AL_BUFFERS_QUEUED 0x1015
|
||||||
|
#define AL_BUFFERS_PROCESSED 0x1016
|
||||||
|
|
||||||
|
/** Sound samples: format specifier. */
|
||||||
|
#define AL_FORMAT_MONO8 0x1100
|
||||||
|
#define AL_FORMAT_MONO16 0x1101
|
||||||
|
#define AL_FORMAT_STEREO8 0x1102
|
||||||
|
#define AL_FORMAT_STEREO16 0x1103
|
||||||
|
|
||||||
|
/**
|
||||||
|
* source specific reference distance
|
||||||
|
* Type: ALfloat
|
||||||
|
* Range: 0.0 - +inf
|
||||||
|
*
|
||||||
|
* At 0.0, no distance attenuation occurs. Default is
|
||||||
|
* 1.0.
|
||||||
|
*/
|
||||||
|
#define AL_REFERENCE_DISTANCE 0x1020
|
||||||
|
|
||||||
|
/**
|
||||||
|
* source specific rolloff factor
|
||||||
|
* Type: ALfloat
|
||||||
|
* Range: 0.0 - +inf
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define AL_ROLLOFF_FACTOR 0x1021
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directional source, outer cone gain.
|
||||||
|
*
|
||||||
|
* Default: 0.0
|
||||||
|
* Range: [0.0 - 1.0]
|
||||||
|
* Logarithmic
|
||||||
|
*/
|
||||||
|
#define AL_CONE_OUTER_GAIN 0x1022
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate distance above which sources are not
|
||||||
|
* attenuated using the inverse clamped distance model.
|
||||||
|
*
|
||||||
|
* Default: +inf
|
||||||
|
* Type: ALfloat
|
||||||
|
* Range: 0.0 - +inf
|
||||||
|
*/
|
||||||
|
#define AL_MAX_DISTANCE 0x1023
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sound samples: frequency, in units of Hertz [Hz].
|
||||||
|
* This is the number of samples per second. Half of the
|
||||||
|
* sample frequency marks the maximum significant
|
||||||
|
* frequency component.
|
||||||
|
*/
|
||||||
|
#define AL_FREQUENCY 0x2001
|
||||||
|
#define AL_BITS 0x2002
|
||||||
|
#define AL_CHANNELS 0x2003
|
||||||
|
#define AL_SIZE 0x2004
|
||||||
|
#define AL_DATA 0x2005
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer state.
|
||||||
|
*
|
||||||
|
* Not supported for public use (yet).
|
||||||
|
*/
|
||||||
|
#define AL_UNUSED 0x2010
|
||||||
|
#define AL_PENDING 0x2011
|
||||||
|
#define AL_PROCESSED 0x2012
|
||||||
|
|
||||||
|
|
||||||
|
/** Errors: No Error. */
|
||||||
|
#define AL_NO_ERROR AL_FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid Name paramater passed to AL call.
|
||||||
|
*/
|
||||||
|
#define AL_INVALID_NAME 0xA001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid parameter passed to AL call.
|
||||||
|
*/
|
||||||
|
#define AL_ILLEGAL_ENUM 0xA002
|
||||||
|
#define AL_INVALID_ENUM 0xA002
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid enum parameter value.
|
||||||
|
*/
|
||||||
|
#define AL_INVALID_VALUE 0xA003
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Illegal call.
|
||||||
|
*/
|
||||||
|
#define AL_ILLEGAL_COMMAND 0xA004
|
||||||
|
#define AL_INVALID_OPERATION 0xA004
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No mojo.
|
||||||
|
*/
|
||||||
|
#define AL_OUT_OF_MEMORY 0xA005
|
||||||
|
|
||||||
|
|
||||||
|
/** Context strings: Vendor Name. */
|
||||||
|
#define AL_VENDOR 0xB001
|
||||||
|
#define AL_VERSION 0xB002
|
||||||
|
#define AL_RENDERER 0xB003
|
||||||
|
#define AL_EXTENSIONS 0xB004
|
||||||
|
|
||||||
|
/** Global tweakage. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Doppler scale. Default 1.0
|
||||||
|
*/
|
||||||
|
#define AL_DOPPLER_FACTOR 0xC000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tweaks speed of propagation.
|
||||||
|
*/
|
||||||
|
#define AL_DOPPLER_VELOCITY 0xC001
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* no longer used -- will probably be removed */
|
||||||
|
/**
|
||||||
|
* Distance scaling
|
||||||
|
*/
|
||||||
|
#define AL_DISTANCE_SCALE 0xC002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distance models
|
||||||
|
*
|
||||||
|
* used in conjunction with DistanceModel
|
||||||
|
*
|
||||||
|
* implicit: NONE, which disances distance attenuation.
|
||||||
|
*/
|
||||||
|
#define AL_DISTANCE_MODEL 0xD000
|
||||||
|
#define AL_INVERSE_DISTANCE 0xD001
|
||||||
|
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
|
||||||
|
/* all the IASIG stuff was never used -- will probably be removed */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #define AL_SOME_ENABLE 0xE000 */
|
||||||
|
|
||||||
|
/** IASIG Level 2 Environment. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG ROOM blah
|
||||||
|
* Type: intgeger
|
||||||
|
* Range: [-10000, 0]
|
||||||
|
* Default: -10000
|
||||||
|
*/
|
||||||
|
#define AL_ENV_ROOM_IASIG 0x3001
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG ROOM_HIGH_FREQUENCY
|
||||||
|
* Type: integer
|
||||||
|
* Range: [-10000, 0]
|
||||||
|
* Default: 0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_ROOM_HIGH_FREQUENCY_IASIG 0x3002
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG ROOM_ROLLOFF_FACTOR
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.0, 10.0]
|
||||||
|
* Default: 0.0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_ROOM_ROLLOFF_FACTOR_IASIG 0x3003
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG DECAY_TIME
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.1, 20.0]
|
||||||
|
* Default: 1.0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_DECAY_TIME_IASIG 0x3004
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG DECAY_HIGH_FREQUENCY_RATIO
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.1, 2.0]
|
||||||
|
* Default: 0.5
|
||||||
|
*/
|
||||||
|
#define AL_ENV_DECAY_HIGH_FREQUENCY_RATIO_IASIG 0x3005
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG REFLECTIONS
|
||||||
|
* Type: integer
|
||||||
|
* Range: [-10000, 1000]
|
||||||
|
* Default: -10000
|
||||||
|
*/
|
||||||
|
#define AL_ENV_REFLECTIONS_IASIG 0x3006
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG REFLECTIONS_DELAY
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.0, 0.3]
|
||||||
|
* Default: 0.02
|
||||||
|
*/
|
||||||
|
#define AL_ENV_REFLECTIONS_DELAY_IASIG 0x3006
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG REVERB
|
||||||
|
* Type: integer
|
||||||
|
* Range: [-10000,2000]
|
||||||
|
* Default: -10000
|
||||||
|
*/
|
||||||
|
#define AL_ENV_REVERB_IASIG 0x3007
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG REVERB_DELAY
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.0, 0.1]
|
||||||
|
* Default: 0.04
|
||||||
|
*/
|
||||||
|
#define AL_ENV_REVERB_DELAY_IASIG 0x3008
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG DIFFUSION
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.0, 100.0]
|
||||||
|
* Default: 100.0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_DIFFUSION_IASIG 0x3009
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG DENSITY
|
||||||
|
* Type: float
|
||||||
|
* Range: [0.0, 100.0]
|
||||||
|
* Default: 100.0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_DENSITY_IASIG 0x300A
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter: IASIG HIGH_FREQUENCY_REFERENCE
|
||||||
|
* Type: float
|
||||||
|
* Range: [20.0, 20000.0]
|
||||||
|
* Default: 5000.0
|
||||||
|
*/
|
||||||
|
#define AL_ENV_HIGH_FREQUENCY_REFERENCE_IASIG 0x300B
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
61
include/AL/alu.h
Normal file
61
include/AL/alu.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef __alu_h_
|
||||||
|
#define __alu_h_
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define ALUAPI
|
||||||
|
#define ALUAPIENTRY __cdecl
|
||||||
|
|
||||||
|
#define BUFFERSIZE 48000
|
||||||
|
#define FRACTIONBITS 14
|
||||||
|
#define FRACTIONMASK ((1L<<FRACTIONBITS)-1)
|
||||||
|
#define OUTPUTCHANNELS 2
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export on
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#define ALAPI
|
||||||
|
#define ALAPIENTRY
|
||||||
|
#define AL_CALLBACK
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#if defined(__MACH__) && defined(__APPLE__)
|
||||||
|
#include <OpenAL/al.h>
|
||||||
|
#include <OpenAL/alutypes.h>
|
||||||
|
#else
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alutypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
ALUAPI ALint ALUAPIENTRY aluF2L(ALfloat value);
|
||||||
|
ALUAPI ALshort ALUAPIENTRY aluF2S(ALfloat value);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluCrossproduct(ALfloat *inVector1,ALfloat *inVector2,ALfloat *outVector);
|
||||||
|
ALUAPI ALfloat ALUAPIENTRY aluDotproduct(ALfloat *inVector1,ALfloat *inVector2);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluNormalize(ALfloat *inVector);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluMatrixVector(ALfloat *vector,ALfloat matrix[3][3]);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluCalculateSourceParameters(ALuint source,ALuint channels,ALfloat *drysend,ALfloat *wetsend,ALfloat *pitch);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluMixData(ALvoid *context,ALvoid *buffer,ALsizei size,ALenum format);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluSetReverb(ALvoid *Reverb,ALuint Environment);
|
||||||
|
ALUAPI ALvoid ALUAPIENTRY aluReverb(ALvoid *Reverb,ALfloat Buffer[][2],ALsizei BufferSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export off
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __alu_h_ */
|
||||||
|
|
101
include/AL/alut.h
Normal file
101
include/AL/alut.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#ifndef _ALUT_H_
|
||||||
|
#define _ALUT_H_
|
||||||
|
|
||||||
|
/* define platform type */
|
||||||
|
#if !defined(MACINTOSH_AL) && !defined(LINUX_AL) && !defined(WINDOWS_AL)
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define MACINTOSH_AL
|
||||||
|
#else
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WINDOWS_AL
|
||||||
|
#else
|
||||||
|
#define LINUX_AL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "altypes.h"
|
||||||
|
#include "aluttypes.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define ALUTAPI
|
||||||
|
#define ALUTAPIENTRY __cdecl
|
||||||
|
#define AL_CALLBACK
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export on
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#ifndef ALUTAPI
|
||||||
|
#define ALUTAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALUTAPIENTRY
|
||||||
|
#define ALUTAPIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_CALLBACK
|
||||||
|
#define AL_CALLBACK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_NO_PROTOTYPES
|
||||||
|
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutInit(int *argc, char *argv[]);
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutExit(ALvoid);
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* this function is Linux-specific and will probably be removed from this header */
|
||||||
|
ALUTAPI ALboolean ALUTAPIENTRY alutLoadWAV( const char *fname, ALvoid **wave, ALsizei *format, ALsizei *size, ALsizei *bits, ALsizei *freq );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MACINTOSH_AL
|
||||||
|
/* Windows and Linux versions have a loop parameter, Macintosh doesn't */
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutLoadWAVFile(ALbyte *file, ALenum *format, ALvoid **data, ALsizei *size, ALsizei *freq, ALboolean *loop);
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory, ALenum *format, ALvoid **data, ALsizei *size, ALsizei *freq, ALboolean *loop);
|
||||||
|
#else
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutLoadWAVFile(ALbyte *file, ALenum *format, ALvoid **data, ALsizei *size, ALsizei *freq);
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutLoadWAVMemory(ALbyte *memory, ALenum *format, ALvoid **data, ALsizei *size, ALsizei *freq);
|
||||||
|
#endif
|
||||||
|
ALUTAPI void ALUTAPIENTRY alutUnloadWAV(ALenum format, ALvoid *data, ALsizei size, ALsizei freq);
|
||||||
|
|
||||||
|
#else
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutInit)(int *argc, char *argv[]);
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutExit)(ALvoid);
|
||||||
|
|
||||||
|
#ifdef LINUX_AL
|
||||||
|
/* this function is Linux-specific and will probably be removed from this header */
|
||||||
|
ALUTAPI ALboolean ALUTAPIENTRY (*alutLoadWAV)( const char *fname, ALvoid **wave, ALsizei *format, ALsizei *size, ALsizei *bits, ALsizei *freq );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MACINTOSH_AL
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop);
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutLoadWAVMemory)(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop);
|
||||||
|
#else
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutLoadWAVMemory)(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq);
|
||||||
|
#endif
|
||||||
|
ALUTAPI void ALUTAPIENTRY (*alutUnloadWAV)(ALenum format,ALvoid *data,ALsizei size,ALsizei freq);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* AL_NO_PROTOTYPES */
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
#pragma export off
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
#endif /* TARGET_OS_MAC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
6
include/AL/aluttypes.h
Normal file
6
include/AL/aluttypes.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _ALUTTYPES_H_
|
||||||
|
#define _ALUTTYPES_H_
|
||||||
|
|
||||||
|
#define AL_PROVIDES_ALUT 1
|
||||||
|
|
||||||
|
#endif /* _ALUTTYPES_H_ */
|
5
include/AL/alutypes.h
Normal file
5
include/AL/alutypes.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef _ALUTYPES_H_
|
||||||
|
#define _ALUTYPES_H_
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _ALUTYPES_H_ */
|
62
src/Makefile
Normal file
62
src/Makefile
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# Copyright (C) 2004 Christopher John Purnell
|
||||||
|
# cjp@lost.org.uk
|
||||||
|
#
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Library General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public
|
||||||
|
# License along with this library; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
SONAME = libopenal.so.0
|
||||||
|
SUFFIX = 1.2
|
||||||
|
|
||||||
|
LIB=$(SONAME).$(SUFFIX)
|
||||||
|
PIC=-fPIC
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
#CFLAGS=-O2 -W -Wall -Wmissing-prototypes -Werror $(PIC)
|
||||||
|
CFLAGS=-O2 -W -Wall -Wmissing-prototypes $(PIC)
|
||||||
|
LIBS=-lasound -lpthread -lm
|
||||||
|
SHARED=-shared -Wl,-soname,$(SONAME)
|
||||||
|
CPPFLAGS=-I../include
|
||||||
|
|
||||||
|
OFILES= al_listener.o al_source.o al_buffer.o al_play.o al_able.o al_state.o \
|
||||||
|
al_doppler.o al_distance.o al_error.o al_ext.o al_vector.o \
|
||||||
|
alc_context.o alc_speaker.o alc_device.o alc_state.o alc_error.o \
|
||||||
|
alc_ext.o alut_main.o alut_wav.o
|
||||||
|
CFILES= al_listener.c al_source.c al_buffer.c al_play.c al_able.c al_state.c \
|
||||||
|
al_doppler.c al_distance.c al_error.c al_ext.c al_vector.c \
|
||||||
|
alc_context.c alc_speaker.c alc_device.c alc_state.c alc_error.c \
|
||||||
|
alc_ext.c alut_main.c alut_wav.c
|
||||||
|
|
||||||
|
all: $(LIB)
|
||||||
|
|
||||||
|
$(LIB): $(OFILES)
|
||||||
|
$(CC) $(SHARED) -o $(LIB) $(OFILES) $(LIBS)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f $(LIB) $(PROGS) .depend
|
||||||
|
|
||||||
|
clean: tidy
|
||||||
|
rm -f *.o
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
rm -f *~ *.bak *.orig
|
||||||
|
|
||||||
|
depend:
|
||||||
|
$(CC) $(CPPFLAGS) -M $(CFILES) > .depend
|
||||||
|
|
||||||
|
ifeq (.depend, $(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
38
src/al_able.c
Normal file
38
src/al_able.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include "al_error.h"
|
||||||
|
|
||||||
|
ALvoid alEnable(ALenum cap ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
_alSetError(AL_ILLEGAL_ENUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alDisable(ALenum cap ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
_alSetError(AL_ILLEGAL_ENUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALboolean alIsEnabled(ALenum cap ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
_alSetError(AL_ILLEGAL_ENUM);
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
462
src/al_buffer.c
Normal file
462
src/al_buffer.c
Normal file
|
@ -0,0 +1,462 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "al_buffer.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
|
||||||
|
#define HASH_SIZE 0x100
|
||||||
|
#define HASH_MASK 0x0FF
|
||||||
|
|
||||||
|
static pthread_mutex_t _al_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static ALuint _al_last_buffer_id = 0;
|
||||||
|
static AL_buffer *_al_buffers[HASH_SIZE];
|
||||||
|
|
||||||
|
static AL_buffer *_alFindBuffer(ALuint bid)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
for (buf = _al_buffers[bid & HASH_MASK]; buf; buf = buf->next)
|
||||||
|
{
|
||||||
|
if (buf->id == bid)
|
||||||
|
{
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AL_buffer *_alLockBuffer(ALuint bid)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
if ((buf = _alFindBuffer(bid)))
|
||||||
|
{
|
||||||
|
buf->used++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alUnlockBuffer(AL_buffer *buf)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
buf->used--;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AL_buffer *_alGenBuffer(ALvoid)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
ALuint bid;
|
||||||
|
|
||||||
|
if (!(buf = malloc(sizeof(AL_buffer))))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->used = 0;
|
||||||
|
buf->data = 0;
|
||||||
|
buf->size = 0;
|
||||||
|
buf->freq = 0;
|
||||||
|
|
||||||
|
bid = _al_last_buffer_id;
|
||||||
|
while (!++bid || _alFindBuffer(bid));
|
||||||
|
_al_last_buffer_id = bid;
|
||||||
|
|
||||||
|
buf->id = bid;
|
||||||
|
|
||||||
|
buf->next = _al_buffers[bid & HASH_MASK];
|
||||||
|
_al_buffers[bid & HASH_MASK] = buf;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alDeleteBuffer(AL_buffer *buf)
|
||||||
|
{
|
||||||
|
AL_buffer *b, **p;
|
||||||
|
|
||||||
|
for (p = &_al_buffers[buf->id & HASH_MASK]; (b = *p); p = &b->next)
|
||||||
|
{
|
||||||
|
if (b->id == buf->id)
|
||||||
|
{
|
||||||
|
*p = b->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->data) free(buf->data);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGenBuffers(ALsizei n, ALuint *buffers)
|
||||||
|
{
|
||||||
|
ALsizei i;
|
||||||
|
AL_buffer **temp;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = alloca(n * sizeof(AL_buffer *));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
if (!(temp[i] = _alGenBuffer()))
|
||||||
|
{
|
||||||
|
ALsizei j;
|
||||||
|
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
_alDeleteBuffer(temp[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
buffers[i] = temp[i]->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alDeleteBuffers(ALsizei n, ALuint *buffers)
|
||||||
|
{
|
||||||
|
ALsizei i;
|
||||||
|
AL_buffer **temp;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = alloca(n * sizeof(AL_buffer *));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
if (!(temp[i] = _alFindBuffer(buffers[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp[i]->used)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
_alDeleteBuffer(temp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALboolean alIsBuffer(ALuint bid)
|
||||||
|
{
|
||||||
|
ALboolean value;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
value = _alFindBuffer(bid) ? AL_TRUE : AL_FALSE;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alBufferMono8(AL_buffer *buf, ALvoid *data,
|
||||||
|
ALsizei size, ALsizei freq)
|
||||||
|
{
|
||||||
|
ALvoid *copy;
|
||||||
|
ALsizei frames = size;
|
||||||
|
|
||||||
|
if (!(copy = malloc(frames << 2)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
__uint8_t *from = data;
|
||||||
|
__int16_t *to = copy;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
for (i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
__int16_t value = (*(from++) - 128) << 8;
|
||||||
|
*(to++) = value;
|
||||||
|
*(to++) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->data = copy;
|
||||||
|
buf->size = frames;
|
||||||
|
buf->freq = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alBufferMono16(AL_buffer *buf, ALvoid *data,
|
||||||
|
ALsizei size, ALsizei freq)
|
||||||
|
{
|
||||||
|
ALvoid *copy;
|
||||||
|
ALsizei frames = size >> 1;
|
||||||
|
|
||||||
|
if (!(copy = malloc(frames << 2)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
__int16_t *from = data;
|
||||||
|
__int16_t *to = copy;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
for (i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
__int16_t value = *(from++);
|
||||||
|
*(to++) = value;
|
||||||
|
*(to++) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->data = copy;
|
||||||
|
buf->size = frames;
|
||||||
|
buf->freq = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alBufferStereo8(AL_buffer *buf, ALvoid *data,
|
||||||
|
ALsizei size, ALsizei freq)
|
||||||
|
{
|
||||||
|
ALvoid *copy;
|
||||||
|
ALsizei frames = size >> 1;
|
||||||
|
|
||||||
|
if (!(copy = malloc(frames << 2)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
__uint8_t *from = data;
|
||||||
|
__int16_t *to = copy;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
for (i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
*(to++) = (*(from++) - 128) << 8;
|
||||||
|
*(to++) = (*(from++) - 128) << 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->data = copy;
|
||||||
|
buf->size = frames;
|
||||||
|
buf->freq = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alBufferStereo16(AL_buffer *buf, ALvoid *data,
|
||||||
|
ALsizei size, ALsizei freq)
|
||||||
|
{
|
||||||
|
ALvoid *copy;
|
||||||
|
ALsizei frames = size >> 2;
|
||||||
|
|
||||||
|
if (!(copy = malloc(frames << 2)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
__int32_t *from = data;
|
||||||
|
__int32_t *to = copy;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
for (i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
*(to++) = *(from++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->data = copy;
|
||||||
|
buf->size = frames;
|
||||||
|
buf->freq = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alBufferData(ALuint bid, ALenum format, ALvoid *data,
|
||||||
|
ALsizei size, ALsizei freq)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
if (!(buf = _alLockBuffer(bid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->used > 1)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->data)
|
||||||
|
{
|
||||||
|
free(buf->data);
|
||||||
|
buf->data = 0;
|
||||||
|
buf->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case AL_FORMAT_MONO8:
|
||||||
|
_alBufferMono8(buf, data, size, freq);
|
||||||
|
break;
|
||||||
|
case AL_FORMAT_MONO16:
|
||||||
|
_alBufferMono16(buf, data, size, freq);
|
||||||
|
break;
|
||||||
|
case AL_FORMAT_STEREO8:
|
||||||
|
_alBufferStereo8(buf, data, size, freq);
|
||||||
|
break;
|
||||||
|
case AL_FORMAT_STEREO16:
|
||||||
|
_alBufferStereo16(buf, data, size, freq);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alUnlockBuffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetBufferi(ALuint bid, ALenum param, ALint *value)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
if (!(buf = _alFindBuffer(bid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case AL_FREQUENCY:
|
||||||
|
*value = (ALint)buf->freq;
|
||||||
|
break;
|
||||||
|
case AL_BITS:
|
||||||
|
*value = 16;
|
||||||
|
break;
|
||||||
|
case AL_CHANNELS:
|
||||||
|
*value = 2;
|
||||||
|
break;
|
||||||
|
case AL_SIZE:
|
||||||
|
*value = (ALint)(buf->size << 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
pthread_mutex_unlock(&_al_buffer_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetBufferf(ALuint bid, ALenum param, ALfloat *value)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
|
||||||
|
if (!(buf = _alLockBuffer(bid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case AL_FREQUENCY:
|
||||||
|
*value = (ALfloat)buf->freq;
|
||||||
|
break;
|
||||||
|
case AL_BITS:
|
||||||
|
*value = 16.0f;
|
||||||
|
break;
|
||||||
|
case AL_CHANNELS:
|
||||||
|
*value = 2.0f;
|
||||||
|
break;
|
||||||
|
case AL_SIZE:
|
||||||
|
*value = (ALfloat)(buf->size << 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
pthread_mutex_lock(&_al_buffer_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetBufferiv(ALuint bid, ALenum param, ALint *values)
|
||||||
|
{
|
||||||
|
alGetBufferi(bid, param, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetBufferfv(ALuint bid, ALenum param, ALfloat *values)
|
||||||
|
{
|
||||||
|
alGetBufferf(bid, param, values);
|
||||||
|
}
|
40
src/al_buffer.h
Normal file
40
src/al_buffer.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AL_BUFFER_H_
|
||||||
|
#define _AL_BUFFER_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
typedef struct _AL_buffer
|
||||||
|
{
|
||||||
|
struct _AL_buffer *next;
|
||||||
|
ALuint id;
|
||||||
|
ALuint used;
|
||||||
|
int32_t *data;
|
||||||
|
ALuint size;
|
||||||
|
ALuint freq;
|
||||||
|
}
|
||||||
|
AL_buffer;
|
||||||
|
|
||||||
|
AL_buffer *_alLockBuffer(ALuint);
|
||||||
|
ALvoid _alUnlockBuffer(AL_buffer *);
|
||||||
|
|
||||||
|
#endif
|
93
src/al_distance.c
Normal file
93
src/al_distance.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "al_source.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
|
||||||
|
static ALfloat _alDistanceNone(AL_source *src, ALfloat dist ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return src->gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALfloat _alDistanceInverse(AL_source *src, ALfloat dist)
|
||||||
|
{
|
||||||
|
ALfloat ref = src->reference_distance;
|
||||||
|
|
||||||
|
if (dist < ref)
|
||||||
|
{
|
||||||
|
dist = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
return src->gain * ref / (ref + src->rolloff_factor * (dist - ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALfloat _alDistanceInverseClamped(AL_source *src, ALfloat dist)
|
||||||
|
{
|
||||||
|
ALfloat ref = src->reference_distance;
|
||||||
|
|
||||||
|
if (dist < ref)
|
||||||
|
{
|
||||||
|
dist = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dist > src->max_distance)
|
||||||
|
{
|
||||||
|
dist = src->max_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return src->gain * ref / (ref + src->rolloff_factor * (dist - ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALvoid alDistanceModel(ALenum model)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
ALfloat (*df)(AL_source *, ALfloat);
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (model)
|
||||||
|
{
|
||||||
|
case AL_NONE:
|
||||||
|
df = _alDistanceNone;
|
||||||
|
break;
|
||||||
|
case AL_INVERSE_DISTANCE:
|
||||||
|
df = _alDistanceInverse;
|
||||||
|
break;
|
||||||
|
case AL_INVERSE_DISTANCE_CLAMPED:
|
||||||
|
df = _alDistanceInverseClamped;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_ILLEGAL_ENUM);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->distance_model = model;
|
||||||
|
ctx->distance_func = df;
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
55
src/al_doppler.c
Normal file
55
src/al_doppler.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "alc_context.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
|
||||||
|
ALvoid alDopplerFactor(ALfloat value)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
_alRangedAssign1(ctx->doppler_factor, value, 0.0f);
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alDopplerVelocity(ALfloat value)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
_alRangedAssign1(ctx->doppler_velocity, value, 0.0f);
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
37
src/al_error.c
Normal file
37
src/al_error.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "al_error.h"
|
||||||
|
|
||||||
|
static ALenum __al_error = AL_NO_ERROR;
|
||||||
|
|
||||||
|
ALenum alGetError(ALvoid)
|
||||||
|
{
|
||||||
|
ALenum err = __al_error;
|
||||||
|
__al_error = AL_NO_ERROR;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alSetError(ALenum err)
|
||||||
|
{
|
||||||
|
if (__al_error == AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
__al_error = err;
|
||||||
|
}
|
||||||
|
}
|
42
src/al_error.h
Normal file
42
src/al_error.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AL_ERROR_H_
|
||||||
|
#define _AL_ERROR_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
extern ALvoid _alSetError(ALenum);
|
||||||
|
|
||||||
|
#define _alRangedAssignB(x, v) \
|
||||||
|
x = v ? AL_TRUE : AL_FALSE
|
||||||
|
|
||||||
|
#define _alRangedAssign1(x, v, lo) \
|
||||||
|
if (v < lo) \
|
||||||
|
_alSetError(AL_INVALID_VALUE); \
|
||||||
|
else \
|
||||||
|
x = (ALfloat)v
|
||||||
|
|
||||||
|
#define _alRangedAssign2(x, v, lo, hi) \
|
||||||
|
if (v < lo || v > hi) \
|
||||||
|
_alSetError(AL_INVALID_VALUE); \
|
||||||
|
else \
|
||||||
|
x = (ALfloat)v
|
||||||
|
|
||||||
|
#endif
|
140
src/al_ext.c
Normal file
140
src/al_ext.c
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
static struct { const ALubyte *name; ALenum value; } _al_enums[]= {
|
||||||
|
{ "AL_INVALID", AL_INVALID },
|
||||||
|
{ "AL_NONE", AL_NONE },
|
||||||
|
{ "AL_FALSE", AL_FALSE },
|
||||||
|
{ "AL_TRUE", AL_TRUE },
|
||||||
|
|
||||||
|
{ "ALC_INVALID", ALC_INVALID },
|
||||||
|
{ "ALC_TRUE", ALC_TRUE },
|
||||||
|
{ "ALC_FALSE", ALC_FALSE },
|
||||||
|
|
||||||
|
{ "AL_SOURCE_RELATIVE", AL_SOURCE_RELATIVE },
|
||||||
|
{ "AL_CONE_INNER_ANGLE", AL_CONE_INNER_ANGLE },
|
||||||
|
{ "AL_CONE_OUTER_ANGLE", AL_CONE_OUTER_ANGLE },
|
||||||
|
{ "AL_PITCH", AL_PITCH },
|
||||||
|
{ "AL_POSITION", AL_POSITION },
|
||||||
|
{ "AL_DIRECTION", AL_DIRECTION },
|
||||||
|
{ "AL_VELOCITY", AL_VELOCITY },
|
||||||
|
{ "AL_LOOPING", AL_LOOPING },
|
||||||
|
{ "AL_BUFFER", AL_BUFFER },
|
||||||
|
{ "AL_GAIN", AL_GAIN },
|
||||||
|
{ "AL_MIN_GAIN", AL_MIN_GAIN },
|
||||||
|
{ "AL_MAX_GAIN", AL_MAX_GAIN },
|
||||||
|
{ "AL_ORIENTATION", AL_ORIENTATION },
|
||||||
|
{ "AL_REFERENCE_DISTANCE", AL_REFERENCE_DISTANCE },
|
||||||
|
{ "AL_ROLLOFF_FACTOR", AL_ROLLOFF_FACTOR },
|
||||||
|
{ "AL_CONE_OUTER_GAIN", AL_CONE_OUTER_GAIN },
|
||||||
|
{ "AL_MAX_DISTANCE", AL_MAX_DISTANCE },
|
||||||
|
|
||||||
|
{ "AL_SOURCE_STATE", AL_SOURCE_STATE },
|
||||||
|
{ "AL_INITIAL", AL_INITIAL },
|
||||||
|
{ "AL_PLAYING", AL_PLAYING },
|
||||||
|
{ "AL_PAUSED", AL_PAUSED },
|
||||||
|
{ "AL_STOPPED", AL_STOPPED },
|
||||||
|
|
||||||
|
{ "AL_BUFFERS_QUEUED", AL_BUFFERS_QUEUED },
|
||||||
|
{ "AL_BUFFERS_PROCESSED", AL_BUFFERS_PROCESSED },
|
||||||
|
|
||||||
|
{ "AL_FORMAT_MONO8", AL_FORMAT_MONO8 },
|
||||||
|
{ "AL_FORMAT_MONO16", AL_FORMAT_MONO16 },
|
||||||
|
{ "AL_FORMAT_STEREO8", AL_FORMAT_STEREO8 },
|
||||||
|
{ "AL_FORMAT_STEREO16", AL_FORMAT_STEREO16 },
|
||||||
|
|
||||||
|
{ "AL_FREQUENCY", AL_FREQUENCY },
|
||||||
|
{ "AL_BITS", AL_BITS },
|
||||||
|
{ "AL_CHANNELS", AL_CHANNELS },
|
||||||
|
{ "AL_SIZE", AL_SIZE },
|
||||||
|
{ "AL_DATA", AL_DATA },
|
||||||
|
|
||||||
|
{ "AL_UNUSED", AL_UNUSED },
|
||||||
|
{ "AL_PENDING", AL_PENDING },
|
||||||
|
{ "AL_PROCESSED", AL_PROCESSED },
|
||||||
|
|
||||||
|
{ "ALC_MAJOR_VERSION", ALC_MAJOR_VERSION },
|
||||||
|
{ "ALC_MINOR_VERSION", ALC_MINOR_VERSION },
|
||||||
|
{ "ALC_ATTRIBUTES_SIZE", ALC_ATTRIBUTES_SIZE },
|
||||||
|
{ "ALC_ALL_ATTRIBUTES", ALC_ALL_ATTRIBUTES },
|
||||||
|
{ "ALC_DEFAULT_DEVICE_SPECIFIER", ALC_DEFAULT_DEVICE_SPECIFIER },
|
||||||
|
{ "ALC_DEVICE_SPECIFIER", ALC_DEVICE_SPECIFIER },
|
||||||
|
{ "ALC_EXTENSIONS", ALC_EXTENSIONS },
|
||||||
|
{ "ALC_FREQUENCY", ALC_FREQUENCY },
|
||||||
|
{ "ALC_REFRESH", ALC_REFRESH },
|
||||||
|
{ "ALC_SYNC", ALC_SYNC },
|
||||||
|
|
||||||
|
{ "AL_NO_ERROR", AL_NO_ERROR },
|
||||||
|
{ "AL_INVALID_NAME", AL_INVALID_NAME },
|
||||||
|
{ "AL_INVALID_ENUM", AL_INVALID_ENUM },
|
||||||
|
{ "AL_INVALID_VALUE", AL_INVALID_VALUE },
|
||||||
|
{ "AL_INVALID_OPERATION", AL_INVALID_OPERATION },
|
||||||
|
{ "AL_OUT_OF_MEMORY", AL_OUT_OF_MEMORY },
|
||||||
|
|
||||||
|
{ "ALC_NO_ERROR", ALC_NO_ERROR },
|
||||||
|
{ "ALC_INVALID_DEVICE", ALC_INVALID_DEVICE },
|
||||||
|
{ "ALC_INVALID_CONTEXT", ALC_INVALID_CONTEXT },
|
||||||
|
{ "ALC_INVALID_ENUM", ALC_INVALID_ENUM },
|
||||||
|
{ "ALC_INVALID_VALUE", ALC_INVALID_VALUE },
|
||||||
|
{ "ALC_OUT_OF_MEMORY", ALC_OUT_OF_MEMORY },
|
||||||
|
|
||||||
|
{ "AL_VENDOR", AL_VENDOR },
|
||||||
|
{ "AL_VERSION", AL_VERSION },
|
||||||
|
{ "AL_RENDERER", AL_RENDERER },
|
||||||
|
{ "AL_EXTENSIONS", AL_EXTENSIONS },
|
||||||
|
|
||||||
|
{ "AL_DOPPLER_FACTOR", AL_DOPPLER_FACTOR },
|
||||||
|
{ "AL_DOPPLER_VELOCITY", AL_DOPPLER_VELOCITY },
|
||||||
|
{ "AL_DISTANCE_MODEL", AL_DISTANCE_MODEL },
|
||||||
|
|
||||||
|
{ "AL_INVERSE_DISTANCE", AL_INVERSE_DISTANCE },
|
||||||
|
{ "AL_INVERSE_DISTANCE_CLAMPED", AL_INVERSE_DISTANCE_CLAMPED },
|
||||||
|
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
ALboolean alIsExtensionPresent(const ALubyte *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALvoid *alGetProcAddress(const ALubyte *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALenum alGetEnumValue(const ALubyte *name)
|
||||||
|
{
|
||||||
|
ALuint i=0;
|
||||||
|
|
||||||
|
while ((_al_enums[i].name) && strcmp(_al_enums[i].name, name))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _al_enums[i].value;
|
||||||
|
}
|
300
src/al_listener.c
Normal file
300
src/al_listener.c
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "al_listener.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
#include "al_vector.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
|
||||||
|
static ALvoid _alListenerSetSpeakers(AL_listener *listener,
|
||||||
|
AL_speaker *speakers)
|
||||||
|
{
|
||||||
|
ALfloat matrix[9];
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
_alVectorCrossProduct(matrix + 0, listener->orientation,
|
||||||
|
listener->orientation + 3);
|
||||||
|
_alVectorNormalize(matrix + 0, matrix + 0);
|
||||||
|
|
||||||
|
_alVectorCrossProduct(matrix + 3, listener->orientation + 0,
|
||||||
|
matrix + 0);
|
||||||
|
_alVectorNormalize(matrix + 3, matrix + 3);
|
||||||
|
|
||||||
|
_alVectorNormalize(matrix + 6, listener->orientation + 0);
|
||||||
|
|
||||||
|
for (i = 0; i < _ALC_NUM_SPEAKERS; i++)
|
||||||
|
{
|
||||||
|
_alVectorMatrix(listener->speakers[i].position,
|
||||||
|
speakers[i].position, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alInitListener(AL_listener *listener, AL_speaker *speakers)
|
||||||
|
{
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
listener->gain = 1.0f;
|
||||||
|
|
||||||
|
listener->position[0] = 0.0f;
|
||||||
|
listener->position[1] = 0.0f;
|
||||||
|
listener->position[2] = 0.0f;
|
||||||
|
|
||||||
|
listener->velocity[0] = 0.0f;
|
||||||
|
listener->velocity[1] = 0.0f;
|
||||||
|
listener->velocity[2] = 0.0f;
|
||||||
|
|
||||||
|
listener->orientation[0] = 0.0f;
|
||||||
|
listener->orientation[1] = 0.0f;
|
||||||
|
listener->orientation[2] = 0.0f;
|
||||||
|
listener->orientation[3] = 0.0f;
|
||||||
|
listener->orientation[4] = 0.0f;
|
||||||
|
listener->orientation[5] = 0.0f;
|
||||||
|
|
||||||
|
for (i = 0; i < _ALC_NUM_SPEAKERS; i++)
|
||||||
|
{
|
||||||
|
listener->speakers[i].gain = speakers[i].gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alListenerSetSpeakers(listener, speakers);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alListeneri(ALenum pname, ALint value)
|
||||||
|
{
|
||||||
|
alListenerf(pname, (ALfloat)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alListenerf(ALenum pname, ALfloat value)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (pname)
|
||||||
|
{
|
||||||
|
case AL_GAIN:
|
||||||
|
_alRangedAssign1(ctx->listener.gain, value, 0.0f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alListener3f(ALenum pname, ALfloat f1, ALfloat f2, ALfloat f3)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (pname)
|
||||||
|
{
|
||||||
|
case AL_POSITION:
|
||||||
|
ctx->listener.position[0] = f1;
|
||||||
|
ctx->listener.position[1] = f2;
|
||||||
|
ctx->listener.position[2] = f3;
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
ctx->listener.velocity[0] = f1;
|
||||||
|
ctx->listener.velocity[1] = f2;
|
||||||
|
ctx->listener.velocity[2] = f3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alListenerfv(ALenum pname, ALfloat* values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (pname)
|
||||||
|
{
|
||||||
|
case AL_POSITION:
|
||||||
|
ctx->listener.position[0] = values[0];
|
||||||
|
ctx->listener.position[1] = values[1];
|
||||||
|
ctx->listener.position[2] = values[2];
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
ctx->listener.velocity[0] = values[0];
|
||||||
|
ctx->listener.velocity[1] = values[1];
|
||||||
|
ctx->listener.velocity[2] = values[2];
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
_alRangedAssign1(ctx->listener.gain, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
ctx->listener.orientation[0] = values[0];
|
||||||
|
ctx->listener.orientation[1] = values[1];
|
||||||
|
ctx->listener.orientation[2] = values[2];
|
||||||
|
ctx->listener.orientation[3] = values[3];
|
||||||
|
ctx->listener.orientation[4] = values[4];
|
||||||
|
ctx->listener.orientation[5] = values[5];
|
||||||
|
_alListenerSetSpeakers(&ctx->listener, ctx->speakers);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetListeneri(ALenum pname, ALint *value)
|
||||||
|
{
|
||||||
|
ALint values[6];
|
||||||
|
|
||||||
|
values[0] = *value;
|
||||||
|
alGetListeneriv(pname, values);
|
||||||
|
*value = values[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetListeneriv(ALenum pname, ALint* values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (pname)
|
||||||
|
{
|
||||||
|
case AL_POSITION:
|
||||||
|
values[0] = (ALint)ctx->listener.position[0];
|
||||||
|
values[1] = (ALint)ctx->listener.position[1];
|
||||||
|
values[2] = (ALint)ctx->listener.position[2];
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
values[0] = (ALint)ctx->listener.velocity[0];
|
||||||
|
values[1] = (ALint)ctx->listener.velocity[1];
|
||||||
|
values[2] = (ALint)ctx->listener.velocity[2];
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
values[0] = (ALint)ctx->listener.gain;
|
||||||
|
break;
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
values[0] = (ALint)ctx->listener.orientation[0];
|
||||||
|
values[1] = (ALint)ctx->listener.orientation[1];
|
||||||
|
values[2] = (ALint)ctx->listener.orientation[2];
|
||||||
|
values[3] = (ALint)ctx->listener.orientation[3];
|
||||||
|
values[4] = (ALint)ctx->listener.orientation[4];
|
||||||
|
values[5] = (ALint)ctx->listener.orientation[5];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetListenerf(ALenum pname, ALfloat *value)
|
||||||
|
{
|
||||||
|
ALfloat values[6];
|
||||||
|
|
||||||
|
values[0] = *value;
|
||||||
|
alGetListenerfv(pname, values);
|
||||||
|
*value = values[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetListener3f(ALenum pname, ALfloat *f1, ALfloat *f2, ALfloat *f3)
|
||||||
|
{
|
||||||
|
ALfloat values[6];
|
||||||
|
|
||||||
|
values[0] = *f1;
|
||||||
|
values[1] = *f2;
|
||||||
|
values[2] = *f3;
|
||||||
|
|
||||||
|
alGetListenerfv(pname, values);
|
||||||
|
|
||||||
|
*f1 = values[0];
|
||||||
|
*f2 = values[1];
|
||||||
|
*f3 = values[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetListenerfv(ALenum pname, ALfloat* values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch (pname)
|
||||||
|
{
|
||||||
|
case AL_POSITION:
|
||||||
|
values[0] = ctx->listener.position[0];
|
||||||
|
values[1] = ctx->listener.position[1];
|
||||||
|
values[2] = ctx->listener.position[2];
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
values[0] = ctx->listener.velocity[0];
|
||||||
|
values[1] = ctx->listener.velocity[1];
|
||||||
|
values[2] = ctx->listener.velocity[2];
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
values[0] = ctx->listener.gain;
|
||||||
|
break;
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
values[0] = ctx->listener.orientation[0];
|
||||||
|
values[1] = ctx->listener.orientation[1];
|
||||||
|
values[2] = ctx->listener.orientation[2];
|
||||||
|
values[3] = ctx->listener.orientation[3];
|
||||||
|
values[4] = ctx->listener.orientation[4];
|
||||||
|
values[5] = ctx->listener.orientation[5];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
37
src/al_listener.h
Normal file
37
src/al_listener.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AL_LISTENER_H_
|
||||||
|
#define _AL_LISTENER_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
#include "alc_speaker.h"
|
||||||
|
|
||||||
|
typedef struct _AL_listener {
|
||||||
|
ALfloat gain;
|
||||||
|
ALfloat position[3];
|
||||||
|
ALfloat velocity[3];
|
||||||
|
ALfloat orientation[6];
|
||||||
|
AL_speaker speakers[_ALC_NUM_SPEAKERS];
|
||||||
|
} AL_listener;
|
||||||
|
|
||||||
|
extern ALvoid _alInitListener(AL_listener *, AL_speaker *);
|
||||||
|
|
||||||
|
#endif
|
642
src/al_play.c
Normal file
642
src/al_play.c
Normal file
|
@ -0,0 +1,642 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "al_source.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
#include "al_vector.h"
|
||||||
|
#include "alc_device.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
|
||||||
|
static ALfloat _alCalculateGainAndPitch(AL_source *src)
|
||||||
|
{
|
||||||
|
AL_context *ctx = src->context;
|
||||||
|
ALCdevice *dev = ctx->device;
|
||||||
|
ALfloat position[3];
|
||||||
|
|
||||||
|
position[0] = src->position[0];
|
||||||
|
position[1] = src->position[1];
|
||||||
|
position[2] = src->position[2];
|
||||||
|
|
||||||
|
if (!src->relative)
|
||||||
|
{
|
||||||
|
position[0] -= ctx->listener.position[0];
|
||||||
|
position[1] -= ctx->listener.position[1];
|
||||||
|
position[2] -= ctx->listener.position[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Master Gain */
|
||||||
|
{
|
||||||
|
ALint volume;
|
||||||
|
ALfloat gain = ctx->listener.gain;
|
||||||
|
ALfloat dist = _alVectorMagnitude(position);
|
||||||
|
|
||||||
|
gain *= ctx->distance_func(src, dist);
|
||||||
|
|
||||||
|
if (dist)
|
||||||
|
{
|
||||||
|
position[0] /= dist;
|
||||||
|
position[1] /= dist;
|
||||||
|
position[2] /= dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->conic)
|
||||||
|
{
|
||||||
|
ALfloat a;
|
||||||
|
|
||||||
|
a = _alVectorDotProduct(position, src->direction);
|
||||||
|
|
||||||
|
a = acos(-a) * 360.0 / M_PI;
|
||||||
|
|
||||||
|
if (a > src->cone_inner_angle)
|
||||||
|
{
|
||||||
|
if (a >= src->cone_outer_angle)
|
||||||
|
{
|
||||||
|
gain *= src->cone_outer_gain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a -= src->cone_inner_angle;
|
||||||
|
a *= (src->cone_outer_gain - 1.0f);
|
||||||
|
a /= (src->cone_outer_angle -
|
||||||
|
src->cone_inner_angle);
|
||||||
|
gain *= (1.0f + a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gain > src->max_gain)
|
||||||
|
{
|
||||||
|
gain = src->max_gain;
|
||||||
|
}
|
||||||
|
else if (gain < src->min_gain)
|
||||||
|
{
|
||||||
|
gain = src->min_gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = (ALint)(65535.0f * gain);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->vol_ctl, 1, volume);
|
||||||
|
snd_ctl_elem_value_set_integer(src->vol_ctl, 2, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Speaker Gains */
|
||||||
|
{
|
||||||
|
ALuint i;
|
||||||
|
ALint volume[_ALC_NUM_SPEAKERS];
|
||||||
|
|
||||||
|
for (i = 0; i < _ALC_NUM_SPEAKERS; i++)
|
||||||
|
{
|
||||||
|
AL_speaker *speaker = &ctx->listener.speakers[i];
|
||||||
|
|
||||||
|
volume[i] = speaker->gain ?
|
||||||
|
(ALint)((_alVectorDotProduct
|
||||||
|
(position, speaker->position) + 1.0f)
|
||||||
|
* speaker->gain) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->send_count == 24)
|
||||||
|
{
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 8,
|
||||||
|
volume[0]);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 10,
|
||||||
|
volume[2]);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 12,
|
||||||
|
(volume[4] + 1) >> 1);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 13,
|
||||||
|
(volume[5] + 1) >> 1);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 14,
|
||||||
|
volume[6]);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 17,
|
||||||
|
volume[1]);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 19,
|
||||||
|
volume[3]);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 20,
|
||||||
|
volume[4] >> 1);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 21,
|
||||||
|
volume[5] >> 1);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 23,
|
||||||
|
volume[7]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 4,
|
||||||
|
volume[0]);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 5,
|
||||||
|
volume[2]);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 6,
|
||||||
|
(volume[4] + 1) >> 1);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 7,
|
||||||
|
(volume[5] + 1) >> 1);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 8,
|
||||||
|
volume[1]);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 9,
|
||||||
|
volume[3]);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 10,
|
||||||
|
volume[4] >> 1);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, 11,
|
||||||
|
volume[5] >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pitch */
|
||||||
|
{
|
||||||
|
ALfloat vl, vs;
|
||||||
|
ALfloat pitch = src->pitch;
|
||||||
|
|
||||||
|
if (ctx->doppler_factor)
|
||||||
|
{
|
||||||
|
vl = _alVectorDotProduct(ctx->listener.velocity,
|
||||||
|
position);
|
||||||
|
vs = _alVectorDotProduct(src->velocity, position);
|
||||||
|
|
||||||
|
vl *= ctx->doppler_factor;
|
||||||
|
vs *= ctx->doppler_factor;
|
||||||
|
|
||||||
|
vl += ctx->doppler_velocity;
|
||||||
|
vs += ctx->doppler_velocity;
|
||||||
|
|
||||||
|
pitch *= vl / vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pitch < 0.0f)
|
||||||
|
{
|
||||||
|
pitch = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static snd_pcm_uframes_t _alWriteData(AL_source *src, ALfloat pitch,
|
||||||
|
int32_t *dest, snd_pcm_uframes_t frames)
|
||||||
|
{
|
||||||
|
AL_queue *que;
|
||||||
|
AL_buffer *buf;
|
||||||
|
ALfloat f;
|
||||||
|
ALuint inc, acc;
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
if (!src->playing)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((que = src->current_q) ||
|
||||||
|
((que = src->first_q) && (que->state == AL_PENDING)))
|
||||||
|
{
|
||||||
|
buf = que->buffer;
|
||||||
|
}
|
||||||
|
else if ((buf = src->buffer))
|
||||||
|
{
|
||||||
|
que = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->playing = AL_FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = pitch * (ALfloat)buf->freq / (ALfloat)src->freq;
|
||||||
|
inc = (f >= 65535.0) ? 0xFFFF0000 : (ALuint)(f * 65536.0);
|
||||||
|
acc = 0;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (i < frames)
|
||||||
|
{
|
||||||
|
ALuint j = src->index;
|
||||||
|
|
||||||
|
if (j >= buf->size)
|
||||||
|
{
|
||||||
|
src->index = 0;
|
||||||
|
|
||||||
|
if (que)
|
||||||
|
{
|
||||||
|
que->state = AL_PROCESSED;
|
||||||
|
src->current_q = que->next;
|
||||||
|
}
|
||||||
|
else if(!src->looping)
|
||||||
|
{
|
||||||
|
src->playing = AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[i++] = buf->data[j];
|
||||||
|
acc += inc;
|
||||||
|
src->index = j + (acc >> 16);
|
||||||
|
acc &= 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alProcessSource(AL_source *src)
|
||||||
|
{
|
||||||
|
const snd_pcm_channel_area_t *area;
|
||||||
|
snd_pcm_sframes_t avail;
|
||||||
|
ALfloat pitch;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if (src->state != AL_PLAYING)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_hwsync(src->handle);
|
||||||
|
|
||||||
|
state = snd_pcm_state(src->handle);
|
||||||
|
|
||||||
|
if (state != SND_PCM_STATE_RUNNING)
|
||||||
|
{
|
||||||
|
if (src->playing)
|
||||||
|
{
|
||||||
|
snd_pcm_prepare(src->handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->state = AL_STOPPED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pitch = _alCalculateGainAndPitch(src);
|
||||||
|
|
||||||
|
avail = snd_pcm_avail_update(src->handle);
|
||||||
|
|
||||||
|
while (avail > 0)
|
||||||
|
{
|
||||||
|
snd_pcm_uframes_t offset;
|
||||||
|
snd_pcm_uframes_t frames = avail;
|
||||||
|
snd_pcm_uframes_t written = 0;
|
||||||
|
int32_t *map;
|
||||||
|
|
||||||
|
if (snd_pcm_mmap_begin(src->handle, &area, &offset, &frames))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
avail -= frames;
|
||||||
|
|
||||||
|
map = area->addr + ((area->first + area->step * offset) >> 3);
|
||||||
|
|
||||||
|
while (frames)
|
||||||
|
{
|
||||||
|
snd_pcm_uframes_t f;
|
||||||
|
|
||||||
|
if (!(f = _alWriteData(src, pitch, map, frames)))
|
||||||
|
{
|
||||||
|
bzero(map, frames << 2);
|
||||||
|
avail = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
map += f;
|
||||||
|
written += f;
|
||||||
|
frames -= f;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_mmap_commit(src->handle, offset, written);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AL_context *ctx = src->context;
|
||||||
|
ALCdevice *dev = ctx->device;
|
||||||
|
|
||||||
|
snd_ctl_elem_write(dev->ctl, src->vol_ctl);
|
||||||
|
snd_ctl_elem_write(dev->ctl, src->send_ctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != SND_PCM_STATE_RUNNING)
|
||||||
|
{
|
||||||
|
if (!snd_pcm_delay(src->handle, &avail))
|
||||||
|
{
|
||||||
|
if (avail)
|
||||||
|
{
|
||||||
|
snd_pcm_start(src->handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src->playing)
|
||||||
|
{
|
||||||
|
snd_pcm_drain(src->handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alSourcePlay(AL_source *src)
|
||||||
|
{
|
||||||
|
switch(src->state)
|
||||||
|
{
|
||||||
|
case AL_PAUSED:
|
||||||
|
snd_pcm_pause(src->handle, 0);
|
||||||
|
break;
|
||||||
|
case AL_PLAYING:
|
||||||
|
src->index = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src->state = AL_PLAYING;
|
||||||
|
src->playing = AL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alSourceStop(AL_source *src)
|
||||||
|
{
|
||||||
|
switch (src->state)
|
||||||
|
{
|
||||||
|
case AL_PAUSED:
|
||||||
|
snd_pcm_pause(src->handle, 0);
|
||||||
|
break;
|
||||||
|
case AL_PLAYING:
|
||||||
|
snd_pcm_drop(src->handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src->state = AL_STOPPED;
|
||||||
|
src->index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alSourcePause(AL_source *src)
|
||||||
|
{
|
||||||
|
if (src->state == AL_PLAYING)
|
||||||
|
{
|
||||||
|
snd_pcm_pause(src->handle, 1);
|
||||||
|
src->state = AL_PAUSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alSourceRewind(AL_source *src)
|
||||||
|
{
|
||||||
|
switch (src->state)
|
||||||
|
{
|
||||||
|
case AL_PAUSED:
|
||||||
|
snd_pcm_pause(src->handle, 0);
|
||||||
|
break;
|
||||||
|
case AL_PLAYING:
|
||||||
|
snd_pcm_drop(src->handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src->state = AL_INITIAL;
|
||||||
|
src->index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcePlay(ALuint sid)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_alSourcePlay(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourceStop(ALuint sid)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_alSourceStop(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcePause(ALuint sid)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_alSourcePause(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourceRewind(ALuint sid)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_alSourceRewind(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcePlayv(ALsizei ns, ALuint *ids)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **src;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
src = alloca(ns * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
if (!(src[i] = _alFindSource(ctx, ids[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
_alSourcePlay(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourceStopv(ALsizei ns, ALuint *ids)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **src;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
src = alloca(ns * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
if (!(src[i] = _alFindSource(ctx, ids[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
_alSourceStop(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcePausev(ALsizei ns, ALuint *ids)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **src;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
src = alloca(ns * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
if (!(src[i] = _alFindSource(ctx, ids[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
_alSourcePause(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourceRewindv(ALsizei ns, ALuint *ids)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **src;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
src = alloca(ns * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
if (!(src[i] = _alFindSource(ctx, ids[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ns; i++)
|
||||||
|
{
|
||||||
|
_alSourceRewind(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
939
src/al_source.c
Normal file
939
src/al_source.c
Normal file
|
@ -0,0 +1,939 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
|
#include "al_source.h"
|
||||||
|
#include "al_vector.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
#include "alc_device.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
|
||||||
|
#define AL_FIRST_SOURCE_ID 0x4000
|
||||||
|
|
||||||
|
AL_source *_alFindSource(AL_context *ctx, ALuint cid)
|
||||||
|
{
|
||||||
|
cid -= AL_FIRST_SOURCE_ID;
|
||||||
|
|
||||||
|
if (cid >= ctx->device->subdevs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->sources[cid];
|
||||||
|
}
|
||||||
|
|
||||||
|
static AL_source *_alGenSource(AL_context *ctx)
|
||||||
|
{
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(src = malloc(sizeof(AL_source))))
|
||||||
|
{
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
src->context = ctx;
|
||||||
|
src->handle = 0;
|
||||||
|
src->vol_ctl = 0;
|
||||||
|
src->send_ctl = 0;
|
||||||
|
src->subdev = -1;
|
||||||
|
src->freq = 0;
|
||||||
|
|
||||||
|
src->state = AL_INITIAL;
|
||||||
|
src->playing = AL_FALSE;
|
||||||
|
src->buffer = 0;
|
||||||
|
src->index = 0;
|
||||||
|
|
||||||
|
src->first_q = 0;
|
||||||
|
src->current_q = 0;
|
||||||
|
src->last_q = &src->first_q;
|
||||||
|
|
||||||
|
if (!_alcOpenSource(src))
|
||||||
|
{
|
||||||
|
_alcCloseSource(src);
|
||||||
|
free(src);
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
src->relative = AL_FALSE;
|
||||||
|
src->looping = AL_FALSE;
|
||||||
|
src->conic = AL_FALSE;
|
||||||
|
|
||||||
|
src->position[0] = 0.0f;
|
||||||
|
src->position[1] = 0.0f;
|
||||||
|
src->position[2] = 0.0f;
|
||||||
|
|
||||||
|
src->direction[0] = 0.0f;
|
||||||
|
src->direction[1] = 0.0f;
|
||||||
|
src->direction[2] = 0.0f;
|
||||||
|
|
||||||
|
src->velocity[0] = 0.0f;
|
||||||
|
src->velocity[1] = 0.0f;
|
||||||
|
src->velocity[2] = 0.0f;
|
||||||
|
|
||||||
|
src->pitch = 1.0f;
|
||||||
|
src->gain = 1.0f;
|
||||||
|
src->min_gain = 0.0f;
|
||||||
|
src->max_gain = 1.0f;
|
||||||
|
src->reference_distance = 1.0f;
|
||||||
|
src->rolloff_factor = 1.0f;
|
||||||
|
src->max_distance = FLT_MAX;
|
||||||
|
src->cone_inner_angle = 360.0f;
|
||||||
|
src->cone_outer_angle = 360.0f;
|
||||||
|
src->cone_outer_gain = 0.0f;
|
||||||
|
|
||||||
|
ctx->sources[src->subdev] = src;
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alDeleteSource(AL_source *src)
|
||||||
|
{
|
||||||
|
AL_queue *que;
|
||||||
|
AL_context *ctx = src->context;
|
||||||
|
|
||||||
|
ctx->sources[src->subdev] = 0;
|
||||||
|
_alcCloseSource(src);
|
||||||
|
|
||||||
|
que = src->first_q;
|
||||||
|
while (que)
|
||||||
|
{
|
||||||
|
AL_queue *next = que->next;
|
||||||
|
_alUnlockBuffer(que->buffer);
|
||||||
|
free(que);
|
||||||
|
que = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->buffer)
|
||||||
|
{
|
||||||
|
_alUnlockBuffer(src->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGenSources(ALsizei n, ALuint *sources)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **temp;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
temp = alloca(n * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
if (!(temp[i] = _alGenSource(ctx)))
|
||||||
|
{
|
||||||
|
ALsizei j;
|
||||||
|
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
_alDeleteSource(temp[j]);
|
||||||
|
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
sources[i] = temp[i]->subdev + AL_FIRST_SOURCE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alDeleteSources(ALsizei n, ALuint* sources)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source **temp;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
temp = alloca(n * sizeof(AL_source *));
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
if (!(temp[i] = _alFindSource(ctx, sources[i])))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
_alDeleteSource(temp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALboolean alIsSource(ALuint sid)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
ALboolean value;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
value = _alFindSource(ctx, sid) ? AL_TRUE : AL_FALSE;
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALvoid _alNormalizeDirection(AL_source *src)
|
||||||
|
{
|
||||||
|
ALfloat mag = _alVectorMagnitude(src->direction);
|
||||||
|
|
||||||
|
if (mag)
|
||||||
|
{
|
||||||
|
src->conic = AL_TRUE;
|
||||||
|
src->direction[0] /= mag;
|
||||||
|
src->direction[1] /= mag;
|
||||||
|
src->direction[2] /= mag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src->conic = AL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcei(ALuint sid, ALenum param, ALint value)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_SOURCE_RELATIVE:
|
||||||
|
_alRangedAssignB(src->relative, value);
|
||||||
|
break;
|
||||||
|
case AL_LOOPING:
|
||||||
|
_alRangedAssignB(src->looping, value);
|
||||||
|
break;
|
||||||
|
case AL_PITCH:
|
||||||
|
_alRangedAssign1(src->pitch, value, 0);
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
_alRangedAssign1(src->gain, value, 0);
|
||||||
|
break;
|
||||||
|
case AL_MIN_GAIN:
|
||||||
|
_alRangedAssign2(src->min_gain, value, 0, 1);
|
||||||
|
break;
|
||||||
|
case AL_MAX_GAIN:
|
||||||
|
_alRangedAssign2(src->max_gain, value, 0, 1);
|
||||||
|
break;
|
||||||
|
case AL_REFERENCE_DISTANCE:
|
||||||
|
_alRangedAssign1(src->reference_distance, value, 0);
|
||||||
|
break;
|
||||||
|
case AL_ROLLOFF_FACTOR:
|
||||||
|
_alRangedAssign1(src->rolloff_factor, value, 0);
|
||||||
|
break;
|
||||||
|
case AL_MAX_DISTANCE:
|
||||||
|
_alRangedAssign1(src->max_distance, value, 0);
|
||||||
|
break;
|
||||||
|
case AL_CONE_INNER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_inner_angle, value, 0, 360);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_outer_angle, value, 0, 360);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_GAIN:
|
||||||
|
_alRangedAssign2(src->cone_outer_gain, value, 0, 1);
|
||||||
|
break;
|
||||||
|
case AL_BUFFER:
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
if (!(buf = _alLockBuffer(value)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->buffer)
|
||||||
|
{
|
||||||
|
_alUnlockBuffer(src->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
src->buffer = buf;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcef(ALuint sid, ALenum param, ALfloat value)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_SOURCE_RELATIVE:
|
||||||
|
_alRangedAssignB(src->relative, value);
|
||||||
|
break;
|
||||||
|
case AL_LOOPING:
|
||||||
|
_alRangedAssignB(src->looping, value);
|
||||||
|
break;
|
||||||
|
case AL_PITCH:
|
||||||
|
_alRangedAssign1(src->pitch, value, 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
_alRangedAssign1(src->gain, value, 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_MIN_GAIN:
|
||||||
|
_alRangedAssign2(src->min_gain, value, 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case AL_MAX_GAIN:
|
||||||
|
_alRangedAssign2(src->max_gain, value, 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case AL_REFERENCE_DISTANCE:
|
||||||
|
_alRangedAssign1(src->reference_distance, value, 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_ROLLOFF_FACTOR:
|
||||||
|
_alRangedAssign1(src->rolloff_factor, value, 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_MAX_DISTANCE:
|
||||||
|
_alRangedAssign1(src->max_distance, value, 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_INNER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_inner_angle, value, 0.0f, 360.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_outer_angle, value, 0.0f, 360.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_GAIN:
|
||||||
|
_alRangedAssign2(src->cone_outer_gain, value, 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSource3f(ALuint sid, ALenum param, ALfloat f1, ALfloat f2, ALfloat f3)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_POSITION:
|
||||||
|
src->position[0] = f1;
|
||||||
|
src->position[1] = f2;
|
||||||
|
src->position[2] = f3;
|
||||||
|
break;
|
||||||
|
case AL_DIRECTION:
|
||||||
|
src->direction[0] = f1;
|
||||||
|
src->direction[1] = f2;
|
||||||
|
src->direction[2] = f3;
|
||||||
|
_alNormalizeDirection(src);
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
src->velocity[0] = f1;
|
||||||
|
src->velocity[1] = f2;
|
||||||
|
src->velocity[2] = f3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourcefv(ALuint sid, ALenum param, ALfloat *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_SOURCE_RELATIVE:
|
||||||
|
_alRangedAssignB(src->relative, values[0]);
|
||||||
|
break;
|
||||||
|
case AL_LOOPING:
|
||||||
|
_alRangedAssignB(src->looping, values[0]);
|
||||||
|
break;
|
||||||
|
case AL_PITCH:
|
||||||
|
_alRangedAssign1(src->pitch, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
_alRangedAssign1(src->gain, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_MIN_GAIN:
|
||||||
|
_alRangedAssign2(src->min_gain, values[0], 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case AL_MAX_GAIN:
|
||||||
|
_alRangedAssign2(src->max_gain, values[0], 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case AL_REFERENCE_DISTANCE:
|
||||||
|
_alRangedAssign1(src->reference_distance, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_ROLLOFF_FACTOR:
|
||||||
|
_alRangedAssign1(src->rolloff_factor, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_MAX_DISTANCE:
|
||||||
|
_alRangedAssign1(src->max_distance, values[0], 0.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_INNER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_inner_angle, values[0],
|
||||||
|
0.0f, 360.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_ANGLE:
|
||||||
|
_alRangedAssign2(src->cone_outer_angle, values[0],
|
||||||
|
0.0f, 360.0f);
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_GAIN:
|
||||||
|
_alRangedAssign2(src->cone_outer_gain, values[0], 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case AL_POSITION:
|
||||||
|
src->position[0] = values[0];
|
||||||
|
src->position[1] = values[1];
|
||||||
|
src->position[2] = values[2];
|
||||||
|
break;
|
||||||
|
case AL_DIRECTION:
|
||||||
|
src->direction[0] = values[0];
|
||||||
|
src->direction[1] = values[1];
|
||||||
|
src->direction[2] = values[2];
|
||||||
|
_alNormalizeDirection(src);
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
src->velocity[0] = values[0];
|
||||||
|
src->velocity[1] = values[1];
|
||||||
|
src->velocity[2] = values[2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALint _alBuffersQueued(AL_source *src)
|
||||||
|
{
|
||||||
|
AL_queue *q;
|
||||||
|
ALint count = 0;
|
||||||
|
|
||||||
|
for (q = src->first_q; q; q = q->next)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALint _alBuffersProcessed(AL_source *src)
|
||||||
|
{
|
||||||
|
AL_queue *q;
|
||||||
|
ALint count = 0;
|
||||||
|
|
||||||
|
for (q = src->first_q; q; q = q->next)
|
||||||
|
{
|
||||||
|
if (q->state != AL_PROCESSED)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetSourcei(ALuint sid, ALenum param, ALint *value)
|
||||||
|
{
|
||||||
|
ALint values[3];
|
||||||
|
|
||||||
|
values[0] = *value;
|
||||||
|
alGetSourceiv(sid, param, values);
|
||||||
|
*value = values[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetSourceiv(ALuint sid, ALenum param, ALint *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_SOURCE_RELATIVE:
|
||||||
|
values[0] = src->relative;
|
||||||
|
break;
|
||||||
|
case AL_SOURCE_STATE:
|
||||||
|
values[0] = src->state;
|
||||||
|
break;
|
||||||
|
case AL_LOOPING:
|
||||||
|
values[0] = src->looping;
|
||||||
|
break;
|
||||||
|
case AL_PITCH:
|
||||||
|
values[0] = (ALint)src->pitch;
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
values[0] = (ALint)src->gain;
|
||||||
|
break;
|
||||||
|
case AL_MIN_GAIN:
|
||||||
|
values[0] = (ALint)src->min_gain;
|
||||||
|
break;
|
||||||
|
case AL_MAX_GAIN:
|
||||||
|
values[0] = (ALint)src->max_gain;
|
||||||
|
break;
|
||||||
|
case AL_REFERENCE_DISTANCE:
|
||||||
|
values[0] = (ALint)src->reference_distance;
|
||||||
|
break;
|
||||||
|
case AL_ROLLOFF_FACTOR:
|
||||||
|
values[0] = (ALint)src->rolloff_factor;
|
||||||
|
break;
|
||||||
|
case AL_MAX_DISTANCE:
|
||||||
|
values[0] = (ALint)src->max_distance;
|
||||||
|
break;
|
||||||
|
case AL_CONE_INNER_ANGLE:
|
||||||
|
values[0] = (ALint)src->cone_inner_angle;
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_ANGLE:
|
||||||
|
values[0] = (ALint)src->cone_outer_angle;
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_GAIN:
|
||||||
|
values[0] = (ALint)src->cone_outer_gain;
|
||||||
|
break;
|
||||||
|
case AL_POSITION:
|
||||||
|
values[0] = (ALint)src->position[0];
|
||||||
|
values[1] = (ALint)src->position[1];
|
||||||
|
values[2] = (ALint)src->position[2];
|
||||||
|
break;
|
||||||
|
case AL_DIRECTION:
|
||||||
|
values[0] = (ALint)src->direction[0];
|
||||||
|
values[1] = (ALint)src->direction[1];
|
||||||
|
values[2] = (ALint)src->direction[2];
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
values[0] = (ALint)src->velocity[0];
|
||||||
|
values[1] = (ALint)src->velocity[1];
|
||||||
|
values[2] = (ALint)src->velocity[2];
|
||||||
|
break;
|
||||||
|
case AL_BUFFER:
|
||||||
|
values[0] = src->buffer ? src->buffer->id : 0;
|
||||||
|
break;
|
||||||
|
case AL_BUFFERS_QUEUED:
|
||||||
|
values[0] = _alBuffersQueued(src);
|
||||||
|
break;
|
||||||
|
case AL_BUFFERS_PROCESSED:
|
||||||
|
values[0] = _alBuffersProcessed(src);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetSourcef(ALuint sid, ALenum param, ALfloat *value)
|
||||||
|
{
|
||||||
|
ALfloat values[3];
|
||||||
|
|
||||||
|
values[0] = *value;
|
||||||
|
alGetSourcefv(sid, param, values);
|
||||||
|
*value = values[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetSource3f(ALuint sid, ALenum param,
|
||||||
|
ALfloat *f1, ALfloat *f2, ALfloat *f3)
|
||||||
|
{
|
||||||
|
ALfloat values[6];
|
||||||
|
|
||||||
|
values[0] = *f1;
|
||||||
|
values[1] = *f2;
|
||||||
|
values[2] = *f3;
|
||||||
|
|
||||||
|
alGetSourcefv(sid, param, values);
|
||||||
|
|
||||||
|
*f1 = values[0];
|
||||||
|
*f2 = values[1];
|
||||||
|
*f3 = values[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetSourcefv(ALuint sid, ALenum param, ALfloat* values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_SOURCE_RELATIVE:
|
||||||
|
values[0] = src->relative;
|
||||||
|
break;
|
||||||
|
case AL_SOURCE_STATE:
|
||||||
|
values[0] = (ALfloat)src->state;
|
||||||
|
break;
|
||||||
|
case AL_LOOPING:
|
||||||
|
values[0] = (ALfloat)src->looping;
|
||||||
|
break;
|
||||||
|
case AL_PITCH:
|
||||||
|
values[0] = src->pitch;
|
||||||
|
break;
|
||||||
|
case AL_GAIN:
|
||||||
|
values[0] = src->gain;
|
||||||
|
break;
|
||||||
|
case AL_MIN_GAIN:
|
||||||
|
values[0] = src->min_gain;
|
||||||
|
break;
|
||||||
|
case AL_MAX_GAIN:
|
||||||
|
values[0] = src->max_gain;
|
||||||
|
break;
|
||||||
|
case AL_REFERENCE_DISTANCE:
|
||||||
|
values[0] = src->reference_distance;
|
||||||
|
break;
|
||||||
|
case AL_ROLLOFF_FACTOR:
|
||||||
|
values[0] = src->rolloff_factor;
|
||||||
|
break;
|
||||||
|
case AL_MAX_DISTANCE:
|
||||||
|
values[0] = src->max_distance;
|
||||||
|
break;
|
||||||
|
case AL_CONE_INNER_ANGLE:
|
||||||
|
values[0] = src->cone_inner_angle;
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_ANGLE:
|
||||||
|
values[0] = src->cone_outer_angle;
|
||||||
|
break;
|
||||||
|
case AL_CONE_OUTER_GAIN:
|
||||||
|
values[0] = src->cone_outer_gain;
|
||||||
|
break;
|
||||||
|
case AL_POSITION:
|
||||||
|
values[0] = src->position[0];
|
||||||
|
values[1] = src->position[1];
|
||||||
|
values[2] = src->position[2];
|
||||||
|
break;
|
||||||
|
case AL_DIRECTION:
|
||||||
|
values[0] = src->direction[0];
|
||||||
|
values[1] = src->direction[1];
|
||||||
|
values[2] = src->direction[2];
|
||||||
|
break;
|
||||||
|
case AL_VELOCITY:
|
||||||
|
values[0] = src->velocity[0];
|
||||||
|
values[1] = src->velocity[1];
|
||||||
|
values[2] = src->velocity[2];
|
||||||
|
break;
|
||||||
|
case AL_BUFFERS_QUEUED:
|
||||||
|
values[0] = (ALfloat)_alBuffersQueued(src);
|
||||||
|
break;
|
||||||
|
case AL_BUFFERS_PROCESSED:
|
||||||
|
values[0] = (ALfloat)_alBuffersProcessed(src);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alSourceQueueBuffers(ALuint sid, ALsizei n, ALuint *buffers)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
ALsizei i;
|
||||||
|
AL_queue *first_q;
|
||||||
|
AL_queue **last_q;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_q = 0;
|
||||||
|
last_q = &first_q;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
AL_buffer *buf;
|
||||||
|
AL_queue *que;
|
||||||
|
|
||||||
|
if (!buffers[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(buf = _alLockBuffer(buffers[i])))
|
||||||
|
{
|
||||||
|
while ((que = first_q))
|
||||||
|
{
|
||||||
|
first_q = que->next;
|
||||||
|
_alUnlockBuffer(que->buffer);
|
||||||
|
free(que);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(que = malloc(sizeof(AL_queue))))
|
||||||
|
{
|
||||||
|
while ((que = first_q))
|
||||||
|
{
|
||||||
|
first_q = que->next;
|
||||||
|
_alUnlockBuffer(que->buffer);
|
||||||
|
free(que);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alSetError(AL_OUT_OF_MEMORY);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
que->next = 0;
|
||||||
|
que->buffer = buf;
|
||||||
|
que->state = AL_PENDING;
|
||||||
|
|
||||||
|
*last_q = que;
|
||||||
|
last_q = &que->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_q)
|
||||||
|
{
|
||||||
|
*src->last_q = first_q;
|
||||||
|
src->last_q = last_q;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALvoid alSourceUnqueueBuffers(ALuint sid, ALsizei n, ALuint *buffers)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
AL_source *src;
|
||||||
|
ALsizei i;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
if (!(src = _alFindSource(ctx, sid)))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_NAME);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_alBuffersProcessed(src) < n)
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
AL_queue *que = src->first_q;
|
||||||
|
|
||||||
|
src->first_q = que->next;
|
||||||
|
|
||||||
|
buffers[i] = que->buffer->id;
|
||||||
|
|
||||||
|
_alUnlockBuffer(que->buffer);
|
||||||
|
free(que);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
81
src/al_source.h
Normal file
81
src/al_source.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AL_SOURCE_H_
|
||||||
|
#define _AL_SOURCE_H_
|
||||||
|
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
#include "al_buffer.h"
|
||||||
|
|
||||||
|
typedef struct _AL_queue
|
||||||
|
{
|
||||||
|
struct _AL_queue *next;
|
||||||
|
AL_buffer *buffer;
|
||||||
|
ALenum state;
|
||||||
|
}
|
||||||
|
AL_queue;
|
||||||
|
|
||||||
|
typedef struct _AL_source
|
||||||
|
{
|
||||||
|
ALCcontext *context;
|
||||||
|
|
||||||
|
snd_pcm_t *handle;
|
||||||
|
snd_ctl_elem_value_t *vol_ctl;
|
||||||
|
snd_ctl_elem_value_t *send_ctl;
|
||||||
|
ALint subdev;
|
||||||
|
ALuint freq;
|
||||||
|
|
||||||
|
ALenum state;
|
||||||
|
ALboolean playing;
|
||||||
|
AL_buffer *buffer;
|
||||||
|
ALuint index;
|
||||||
|
|
||||||
|
AL_queue *first_q;
|
||||||
|
AL_queue **last_q;
|
||||||
|
AL_queue *current_q;
|
||||||
|
|
||||||
|
ALboolean relative;
|
||||||
|
ALboolean looping;
|
||||||
|
ALboolean conic;
|
||||||
|
|
||||||
|
ALfloat position[3];
|
||||||
|
ALfloat direction[3];
|
||||||
|
ALfloat velocity[3];
|
||||||
|
|
||||||
|
ALfloat pitch;
|
||||||
|
ALfloat gain;
|
||||||
|
ALfloat min_gain;
|
||||||
|
ALfloat max_gain;
|
||||||
|
ALfloat reference_distance;
|
||||||
|
ALfloat rolloff_factor;
|
||||||
|
ALfloat max_distance;
|
||||||
|
ALfloat cone_inner_angle;
|
||||||
|
ALfloat cone_outer_angle;
|
||||||
|
ALfloat cone_outer_gain;
|
||||||
|
}
|
||||||
|
AL_source;
|
||||||
|
|
||||||
|
ALvoid _alDeleteSource(AL_source *);
|
||||||
|
ALvoid _alProcessSource(AL_source *);
|
||||||
|
|
||||||
|
#endif
|
216
src/al_state.c
Normal file
216
src/al_state.c
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "alc_context.h"
|
||||||
|
#include "al_error.h"
|
||||||
|
|
||||||
|
ALboolean alGetBoolean(ALenum param)
|
||||||
|
{
|
||||||
|
ALboolean value = AL_FALSE;
|
||||||
|
|
||||||
|
alGetBooleanv(param, &value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALint alGetInteger(ALenum param)
|
||||||
|
{
|
||||||
|
ALint value = AL_FALSE;
|
||||||
|
|
||||||
|
alGetIntegerv(param, &value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALfloat alGetFloat(ALenum param)
|
||||||
|
{
|
||||||
|
ALfloat value = AL_FALSE;
|
||||||
|
|
||||||
|
alGetFloatv(param, &value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALdouble alGetDouble(ALenum param)
|
||||||
|
{
|
||||||
|
ALdouble value = AL_FALSE;
|
||||||
|
|
||||||
|
alGetDoublev(param, &value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetBooleanv(ALenum param, ALboolean *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_DOPPLER_FACTOR:
|
||||||
|
*values = (ctx->doppler_factor != 0.0f) ?
|
||||||
|
AL_TRUE : AL_FALSE;
|
||||||
|
break;
|
||||||
|
case AL_DOPPLER_VELOCITY:
|
||||||
|
*values = (ctx->doppler_velocity != 0.0f) ?
|
||||||
|
AL_TRUE : AL_FALSE;
|
||||||
|
break;
|
||||||
|
case AL_DISTANCE_MODEL:
|
||||||
|
*values = (ctx->distance_model != AL_INVERSE_DISTANCE) ?
|
||||||
|
AL_TRUE : AL_FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetIntegerv(ALenum param, ALint *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_DOPPLER_FACTOR:
|
||||||
|
*values = (ALint)ctx->doppler_factor;
|
||||||
|
break;
|
||||||
|
case AL_DOPPLER_VELOCITY:
|
||||||
|
*values = (ALint)ctx->doppler_velocity;
|
||||||
|
break;
|
||||||
|
case AL_DISTANCE_MODEL:
|
||||||
|
*values = ctx->distance_model;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetFloatv(ALenum param, ALfloat *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_DOPPLER_FACTOR:
|
||||||
|
*values = ctx->doppler_factor;
|
||||||
|
break;
|
||||||
|
case AL_DOPPLER_VELOCITY:
|
||||||
|
*values = ctx->doppler_velocity;
|
||||||
|
break;
|
||||||
|
case AL_DISTANCE_MODEL:
|
||||||
|
*values = (ALfloat)ctx->distance_model;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alGetDoublev(ALenum param, ALdouble *values)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = _alcCurrentContext))
|
||||||
|
{
|
||||||
|
_alSetError(AL_INVALID_OPERATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case AL_DOPPLER_FACTOR:
|
||||||
|
*values = (ALdouble)ctx->doppler_factor;
|
||||||
|
break;
|
||||||
|
case AL_DOPPLER_VELOCITY:
|
||||||
|
*values = (ALdouble)ctx->doppler_velocity;
|
||||||
|
break;
|
||||||
|
case AL_DISTANCE_MODEL:
|
||||||
|
*values = (ALdouble)ctx->distance_model;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ALubyte *alGetString(ALenum param)
|
||||||
|
{
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case AL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case AL_INVALID_NAME:
|
||||||
|
return "Invalid Name parameter";
|
||||||
|
case AL_INVALID_ENUM:
|
||||||
|
return "Illegal paramater";
|
||||||
|
case AL_INVALID_VALUE:
|
||||||
|
return "Invalid enum parameter value";
|
||||||
|
case AL_INVALID_OPERATION:
|
||||||
|
return "Illegal call";
|
||||||
|
case AL_OUT_OF_MEMORY:
|
||||||
|
return "Unable to allocate memory";
|
||||||
|
case AL_VENDOR:
|
||||||
|
return "Christopher John Purnell";
|
||||||
|
case AL_VERSION:
|
||||||
|
return "0.1.2";
|
||||||
|
case AL_RENDERER:
|
||||||
|
return "EMU10K1";
|
||||||
|
case AL_EXTENSIONS:
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
_alSetError(AL_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
64
src/al_vector.c
Normal file
64
src/al_vector.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "al_vector.h"
|
||||||
|
|
||||||
|
ALfloat _alVectorMagnitude(ALfloat *v)
|
||||||
|
{
|
||||||
|
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alVectorNormalize(ALfloat *d, ALfloat *s)
|
||||||
|
{
|
||||||
|
ALfloat mag;
|
||||||
|
|
||||||
|
if (!(mag = _alVectorMagnitude(s)))
|
||||||
|
{
|
||||||
|
d[0] = 0.0f;
|
||||||
|
d[1] = 0.0f;
|
||||||
|
d[2] = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d[0] = s[0] / mag;
|
||||||
|
d[1] = s[1] / mag;
|
||||||
|
d[2] = s[2] / mag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alVectorCrossProduct(ALfloat *d, ALfloat *v1, ALfloat *v2)
|
||||||
|
{
|
||||||
|
d[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
||||||
|
d[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
||||||
|
d[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ALfloat _alVectorDotProduct(ALfloat *v1, ALfloat *v2)
|
||||||
|
{
|
||||||
|
return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid _alVectorMatrix(ALfloat *d, ALfloat *s, ALfloat *m)
|
||||||
|
{
|
||||||
|
d[0] = s[0] * m[0] + s[1] * m[3] + s[2] * m[6];
|
||||||
|
d[1] = s[0] * m[1] + s[1] * m[4] + s[2] * m[7];
|
||||||
|
d[2] = s[0] * m[2] + s[1] * m[5] + s[2] * m[8];
|
||||||
|
}
|
31
src/al_vector.h
Normal file
31
src/al_vector.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AL_VECTOR_H_
|
||||||
|
#define _AL_VECTOR_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
ALfloat _alVectorMagnitude(ALfloat *);
|
||||||
|
ALvoid _alVectorNormalize(ALfloat *, ALfloat *);
|
||||||
|
ALvoid _alVectorCrossProduct(ALfloat *, ALfloat *, ALfloat *);
|
||||||
|
ALfloat _alVectorDotProduct(ALfloat *, ALfloat *);
|
||||||
|
ALvoid _alVectorMatrix(ALfloat *, ALfloat *, ALfloat *);
|
||||||
|
|
||||||
|
#endif
|
292
src/alc_context.c
Normal file
292
src/alc_context.c
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include "al_listener.h"
|
||||||
|
#include "al_source.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
#include "alc_error.h"
|
||||||
|
|
||||||
|
AL_context *_alcCurrentContext = 0;
|
||||||
|
|
||||||
|
static ALCvoid *_alcThread(ALCcontext *cc)
|
||||||
|
{
|
||||||
|
AL_context *ctx = cc;
|
||||||
|
ALCdevice *dev = ctx->device;
|
||||||
|
ALuint i;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timespec ts;
|
||||||
|
long ns = 1000000000 / dev->refresh;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&ctx->mutex);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < dev->subdevs; i++)
|
||||||
|
{
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if ((src = ctx->sources[i]))
|
||||||
|
{
|
||||||
|
_alProcessSource(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.tv_sec = tv.tv_sec;
|
||||||
|
if ((ts.tv_nsec = (tv.tv_usec * 1000) + ns) >= 1000000000)
|
||||||
|
{
|
||||||
|
ts.tv_sec += 1;
|
||||||
|
ts.tv_nsec -= 1000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pthread_cond_timedwait(&ctx->cond, &ctx->mutex, &ts));
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ctx->mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALCboolean _alcCreateContext(AL_context *ctx)
|
||||||
|
{
|
||||||
|
ALCdevice *dev = ctx->device;
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
pthread_mutex_init(&ctx->mutex, 0);
|
||||||
|
|
||||||
|
if (!(ctx->sources = malloc(dev->subdevs * sizeof(AL_source*))))
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < dev->subdevs; i++)
|
||||||
|
{
|
||||||
|
ctx->sources[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dev->sync)
|
||||||
|
{
|
||||||
|
|
||||||
|
pthread_cond_init(&ctx->cond, 0);
|
||||||
|
|
||||||
|
if (pthread_create(&ctx->thread, 0, _alcThread, ctx))
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ALC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALCvoid _alcDestroyContext(AL_context *ctx)
|
||||||
|
{
|
||||||
|
ALCdevice *dev;
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
dev = ctx->device;
|
||||||
|
|
||||||
|
for (i = 0; i < dev->subdevs; i++)
|
||||||
|
{
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if ((src = ctx->sources[i]))
|
||||||
|
{
|
||||||
|
_alDeleteSource(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->thread)
|
||||||
|
{
|
||||||
|
pthread_cond_signal(&ctx->cond);
|
||||||
|
|
||||||
|
pthread_join(ctx->thread, 0);
|
||||||
|
|
||||||
|
pthread_cond_destroy(&ctx->cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->sources)
|
||||||
|
{
|
||||||
|
free(ctx->sources);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&ctx->mutex);
|
||||||
|
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCcontext *alcCreateContext(ALCdevice *dev, ALCint *attrlist)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_DEVICE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = malloc(sizeof(AL_context))))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->device = dev;
|
||||||
|
|
||||||
|
while (attrlist)
|
||||||
|
{
|
||||||
|
ALCint value;
|
||||||
|
|
||||||
|
switch (*(attrlist++))
|
||||||
|
{
|
||||||
|
case ALC_FREQUENCY:
|
||||||
|
if ((value = *(attrlist++)) > 0)
|
||||||
|
{
|
||||||
|
dev->freq = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ALC_REFRESH:
|
||||||
|
if ((value = *(attrlist++)) > 0)
|
||||||
|
{
|
||||||
|
dev->refresh = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ALC_SYNC:
|
||||||
|
dev->sync = *(attrlist++) ? AL_TRUE: AL_FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
attrlist = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->refresh > dev->freq)
|
||||||
|
{
|
||||||
|
dev->refresh = dev->freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->sources = 0;
|
||||||
|
ctx->thread = 0;
|
||||||
|
|
||||||
|
_alcLoadSpeakers(ctx->speakers);
|
||||||
|
_alInitListener(&ctx->listener, ctx->speakers);
|
||||||
|
|
||||||
|
ctx->doppler_factor = 1.0f;
|
||||||
|
ctx->doppler_velocity = 1.0f;
|
||||||
|
ctx->distance_model = AL_INVERSE_DISTANCE;
|
||||||
|
ctx->distance_func = _alDistanceInverse;
|
||||||
|
|
||||||
|
if (_alcCreateContext(ctx))
|
||||||
|
return ctx;
|
||||||
|
|
||||||
|
_alcDestroyContext(ctx);
|
||||||
|
|
||||||
|
_alcSetError(ALC_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCenum alcDestroyContext(ALCcontext *cc)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = cc))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_CONTEXT);
|
||||||
|
return ALC_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx == _alcCurrentContext)
|
||||||
|
{
|
||||||
|
_alcCurrentContext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcDestroyContext(ctx);
|
||||||
|
|
||||||
|
return ALC_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCenum alcMakeContextCurrent(ALCcontext *cc)
|
||||||
|
{
|
||||||
|
_alcCurrentContext = cc;
|
||||||
|
|
||||||
|
return ALC_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCcontext *alcGetCurrentContext(ALCvoid)
|
||||||
|
{
|
||||||
|
return _alcCurrentContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCdevice *alcGetContextsDevice(ALCcontext *cc)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
|
||||||
|
if (!(ctx = cc))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_CONTEXT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCvoid alcSuspendContext(ALCcontext *cc ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCvoid *alcProcessContext(ALCcontext *cc)
|
||||||
|
{
|
||||||
|
AL_context *ctx;
|
||||||
|
ALCdevice *dev;
|
||||||
|
ALuint i;
|
||||||
|
|
||||||
|
if (!(ctx = cc))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_CONTEXT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->thread)
|
||||||
|
{
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcLockContext(ctx);
|
||||||
|
|
||||||
|
dev = ctx->device;
|
||||||
|
|
||||||
|
for (i = 0; i < dev->subdevs; i++)
|
||||||
|
{
|
||||||
|
AL_source *src;
|
||||||
|
|
||||||
|
if ((src = ctx->sources[i]))
|
||||||
|
{
|
||||||
|
_alProcessSource(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_alcUnlockContext(ctx);
|
||||||
|
|
||||||
|
return cc;
|
||||||
|
}
|
62
src/alc_context.h
Normal file
62
src/alc_context.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALC_CONTEXT_H_
|
||||||
|
#define _ALC_CONTEXT_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
#include "alc_speaker.h"
|
||||||
|
#include "alc_device.h"
|
||||||
|
#include "al_source.h"
|
||||||
|
#include "al_listener.h"
|
||||||
|
|
||||||
|
typedef struct _AL_context
|
||||||
|
{
|
||||||
|
ALCdevice *device;
|
||||||
|
AL_source **sources;
|
||||||
|
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
|
||||||
|
AL_listener listener;
|
||||||
|
AL_speaker speakers[_ALC_NUM_SPEAKERS];
|
||||||
|
|
||||||
|
ALfloat doppler_factor;
|
||||||
|
ALfloat doppler_velocity;
|
||||||
|
ALenum distance_model;
|
||||||
|
ALfloat (*distance_func)(AL_source *, ALfloat);
|
||||||
|
}
|
||||||
|
AL_context;
|
||||||
|
|
||||||
|
extern AL_context *_alcCurrentContext;
|
||||||
|
|
||||||
|
#define _alcLockContext(ctx) pthread_mutex_lock(&ctx->mutex)
|
||||||
|
#define _alcUnlockContext(ctx) pthread_mutex_unlock(&ctx->mutex)
|
||||||
|
|
||||||
|
AL_source *_alFindSource(AL_context *, ALuint);
|
||||||
|
|
||||||
|
ALfloat _alDistanceInverse(AL_source *, ALfloat);
|
||||||
|
|
||||||
|
#endif
|
227
src/alc_device.c
Normal file
227
src/alc_device.c
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ansidecl.h>
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
#include "alc_device.h"
|
||||||
|
#include "alc_context.h"
|
||||||
|
#include "alc_error.h"
|
||||||
|
|
||||||
|
#define _ALC_DEF_FREQ 44100
|
||||||
|
#define _ALC_DEF_REFRESH 20
|
||||||
|
#define _ALC_NUM_PERIODS 2
|
||||||
|
|
||||||
|
static int live_send_routing[] = {
|
||||||
|
0, 1, 2, 3,
|
||||||
|
0, 2, 6, 7,
|
||||||
|
1, 3, 6, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static int audigy_send_routing[] = {
|
||||||
|
8, 9, 2, 3, 6, 7, 14, 15,
|
||||||
|
8, 9, 2, 3, 6, 7, 14, 15,
|
||||||
|
8, 9, 2, 3, 6, 7, 14, 15
|
||||||
|
};
|
||||||
|
|
||||||
|
ALCboolean _alcOpenSource(AL_source *src)
|
||||||
|
{
|
||||||
|
snd_pcm_hw_params_t *hw_params;
|
||||||
|
snd_pcm_info_t *info;
|
||||||
|
snd_ctl_elem_value_t *route_ctl;
|
||||||
|
snd_pcm_uframes_t size;
|
||||||
|
unsigned i;
|
||||||
|
AL_context *ctx = src->context;
|
||||||
|
ALCdevice *dev = ctx->device;
|
||||||
|
int *send_routing;
|
||||||
|
|
||||||
|
if (snd_pcm_open(&src->handle, dev->device, SND_PCM_STREAM_PLAYBACK,
|
||||||
|
SND_PCM_NONBLOCK))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
snd_pcm_hw_params_alloca(&hw_params);
|
||||||
|
|
||||||
|
if (snd_pcm_hw_params_any(src->handle, hw_params))
|
||||||
|
return ALC_FALSE;
|
||||||
|
if (snd_pcm_hw_params_set_access(src->handle, hw_params,
|
||||||
|
SND_PCM_ACCESS_MMAP_INTERLEAVED))
|
||||||
|
return ALC_FALSE;
|
||||||
|
if (snd_pcm_hw_params_set_format(src->handle, hw_params,
|
||||||
|
SND_PCM_FORMAT_S16))
|
||||||
|
return ALC_FALSE;
|
||||||
|
if (snd_pcm_hw_params_set_channels(src->handle, hw_params, 2))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
src->freq = dev->freq;
|
||||||
|
if (snd_pcm_hw_params_set_rate_near(src->handle, hw_params,
|
||||||
|
&src->freq, 0))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
if (snd_pcm_hw_params_set_periods(src->handle, hw_params,
|
||||||
|
_ALC_NUM_PERIODS, 0))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
size = src->freq * _ALC_NUM_PERIODS / dev->refresh;
|
||||||
|
if (snd_pcm_hw_params_set_buffer_size_near(src->handle, hw_params,
|
||||||
|
&size))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
if (snd_pcm_hw_params(src->handle, hw_params))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
snd_pcm_info_alloca(&info);
|
||||||
|
|
||||||
|
if (snd_pcm_info(src->handle, info))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
src->subdev = snd_pcm_info_get_subdevice(info);
|
||||||
|
|
||||||
|
if (snd_ctl_elem_value_malloc(&src->vol_ctl))
|
||||||
|
return ALC_FALSE;
|
||||||
|
snd_ctl_elem_value_clear(src->vol_ctl);
|
||||||
|
snd_ctl_elem_value_set_interface(src->vol_ctl,
|
||||||
|
SND_CTL_ELEM_IFACE_MIXER);
|
||||||
|
snd_ctl_elem_value_set_name(src->vol_ctl,
|
||||||
|
"EMU10K1 PCM Volume");
|
||||||
|
snd_ctl_elem_value_set_index(src->vol_ctl, src->subdev);
|
||||||
|
|
||||||
|
if (snd_ctl_elem_value_malloc(&src->send_ctl))
|
||||||
|
return ALC_FALSE;
|
||||||
|
snd_ctl_elem_value_clear(src->send_ctl);
|
||||||
|
snd_ctl_elem_value_set_interface(src->send_ctl,
|
||||||
|
SND_CTL_ELEM_IFACE_MIXER);
|
||||||
|
snd_ctl_elem_value_set_name(src->send_ctl,
|
||||||
|
"EMU10K1 PCM Send Volume");
|
||||||
|
snd_ctl_elem_value_set_index(src->send_ctl, src->subdev);
|
||||||
|
|
||||||
|
snd_ctl_elem_value_alloca(&route_ctl);
|
||||||
|
snd_ctl_elem_value_clear(route_ctl);
|
||||||
|
snd_ctl_elem_value_set_interface(route_ctl,
|
||||||
|
SND_CTL_ELEM_IFACE_MIXER);
|
||||||
|
snd_ctl_elem_value_set_name(route_ctl,
|
||||||
|
"EMU10K1 PCM Send Routing");
|
||||||
|
snd_ctl_elem_value_set_index(route_ctl, src->subdev);
|
||||||
|
|
||||||
|
send_routing = (dev->send_count == 24) ?
|
||||||
|
audigy_send_routing : live_send_routing;
|
||||||
|
|
||||||
|
for (i = 0; i < dev->send_count; i++)
|
||||||
|
{
|
||||||
|
snd_ctl_elem_value_set_integer(route_ctl, i, send_routing[i]);
|
||||||
|
snd_ctl_elem_value_set_integer(src->send_ctl, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snd_ctl_elem_write(dev->ctl, route_ctl))
|
||||||
|
return ALC_FALSE;
|
||||||
|
|
||||||
|
return ALC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCvoid _alcCloseSource(AL_source *src)
|
||||||
|
{
|
||||||
|
if (src->send_ctl) snd_ctl_elem_value_free(src->send_ctl);
|
||||||
|
if (src->vol_ctl) snd_ctl_elem_value_free(src->vol_ctl);
|
||||||
|
if (src->handle) snd_pcm_close(src->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALCboolean _alcOpenDevice(ALCdevice *dev)
|
||||||
|
{
|
||||||
|
snd_ctl_elem_info_t *ctl_info;
|
||||||
|
snd_pcm_info_t *pcm_info;
|
||||||
|
int card = -1;
|
||||||
|
|
||||||
|
snd_ctl_elem_info_alloca(&ctl_info);
|
||||||
|
snd_ctl_elem_info_set_interface(ctl_info, SND_CTL_ELEM_IFACE_MIXER);
|
||||||
|
snd_ctl_elem_info_set_name(ctl_info, "EMU10K1 PCM Send Routing");
|
||||||
|
snd_ctl_elem_info_set_index(ctl_info, 0);
|
||||||
|
|
||||||
|
snd_pcm_info_alloca(&pcm_info);
|
||||||
|
|
||||||
|
while (snd_card_next(&card) >= 0 && card >= 0)
|
||||||
|
{
|
||||||
|
sprintf(dev->device, "hw:%d", card);
|
||||||
|
|
||||||
|
if (snd_ctl_open(&dev->ctl, dev->device, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (snd_ctl_elem_info(dev->ctl, ctl_info))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dev->send_count = snd_ctl_elem_info_get_count(ctl_info);
|
||||||
|
|
||||||
|
if ((dev->send_count != 12) && (dev->send_count != 24))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (snd_ctl_pcm_info(dev->ctl, pcm_info))
|
||||||
|
break;
|
||||||
|
|
||||||
|
dev->subdevs = snd_pcm_info_get_subdevices_count(pcm_info);
|
||||||
|
|
||||||
|
return ALC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ALC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALCvoid _alcCloseDevice(ALCdevice *dev)
|
||||||
|
{
|
||||||
|
if (dev->ctl) snd_ctl_close(dev->ctl);
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCdevice *alcOpenDevice(const ALubyte *spec ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
ALCdevice *dev;
|
||||||
|
|
||||||
|
if (!(dev = malloc(sizeof(ALCdevice))))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->ctl = 0;
|
||||||
|
dev->sync = ALC_FALSE;
|
||||||
|
dev->freq = _ALC_DEF_FREQ;
|
||||||
|
dev->refresh = _ALC_DEF_REFRESH;
|
||||||
|
|
||||||
|
if (_alcOpenDevice(dev))
|
||||||
|
return dev;
|
||||||
|
|
||||||
|
_alcCloseDevice(dev);
|
||||||
|
|
||||||
|
_alcSetError(ALC_INVALID_DEVICE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCvoid alcCloseDevice(ALCdevice *dev)
|
||||||
|
{
|
||||||
|
if (dev)
|
||||||
|
{
|
||||||
|
_alcCloseDevice(dev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_DEVICE);
|
||||||
|
}
|
||||||
|
}
|
44
src/alc_device.h
Normal file
44
src/alc_device.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALC_DEVICE_H_
|
||||||
|
#define _ALC_DEVICE_H_
|
||||||
|
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
#include "al_source.h"
|
||||||
|
|
||||||
|
struct _AL_device
|
||||||
|
{
|
||||||
|
char device[16];
|
||||||
|
ALuint subdevs;
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
ALuint send_count;
|
||||||
|
ALCboolean sync;
|
||||||
|
ALuint freq;
|
||||||
|
ALuint refresh;
|
||||||
|
};
|
||||||
|
|
||||||
|
ALCboolean _alcOpenSource(AL_source *);
|
||||||
|
ALCvoid _alcCloseSource(AL_source *);
|
||||||
|
|
||||||
|
#endif
|
39
src/alc_error.c
Normal file
39
src/alc_error.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include "alc_error.h"
|
||||||
|
|
||||||
|
static ALCenum __alc_error = ALC_NO_ERROR;
|
||||||
|
|
||||||
|
ALCenum alcGetError(ALCdevice *dev ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
ALCenum err = __alc_error;
|
||||||
|
__alc_error = ALC_NO_ERROR;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALCvoid _alcSetError(ALCenum err)
|
||||||
|
{
|
||||||
|
if (__alc_error == ALC_NO_ERROR)
|
||||||
|
{
|
||||||
|
__alc_error = err;
|
||||||
|
}
|
||||||
|
}
|
28
src/alc_error.h
Normal file
28
src/alc_error.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALC_ERROR_H_
|
||||||
|
#define _ALC_ERROR_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
extern ALCvoid _alcSetError(ALCenum);
|
||||||
|
|
||||||
|
#endif
|
42
src/alc_ext.c
Normal file
42
src/alc_ext.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
ALCboolean alcIsExtensionPresent(ALCdevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
ALCubyte *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return ALC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALCvoid *alcGetProcAddress(ALCdevice *dev ATTRIBUTE_UNUSED,
|
||||||
|
ALubyte *name ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALCenum alcGetEnumValue(ALCdevice *dev ATTRIBUTE_UNUSED, ALCubyte *name)
|
||||||
|
{
|
||||||
|
return alGetEnumValue(name);
|
||||||
|
}
|
91
src/alc_speaker.c
Normal file
91
src/alc_speaker.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "alc_speaker.h"
|
||||||
|
#include "al_vector.h"
|
||||||
|
|
||||||
|
static AL_speaker _alcDefaultSpeakers[_ALC_NUM_SPEAKERS] =
|
||||||
|
{
|
||||||
|
{ 127.5f, { -1.0f, 0.0f, 0.0f } }, /* Front Left */
|
||||||
|
{ 127.5f, { 1.0f, 0.0f, 0.0f } }, /* Front Right */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } }, /* Rear Left */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } }, /* Rear Right */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } }, /* Center */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } }, /* LFE */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } }, /* Side Left */
|
||||||
|
{ 0.0f, { 0.0f, 0.0f, 0.0f } } /* Side Right */
|
||||||
|
};
|
||||||
|
|
||||||
|
ALvoid _alcLoadSpeakers(AL_speaker *speakers)
|
||||||
|
{
|
||||||
|
char *s, buf[1024];
|
||||||
|
FILE *fp;
|
||||||
|
ALuint i;
|
||||||
|
ALfloat gain;
|
||||||
|
ALfloat pos[3];
|
||||||
|
|
||||||
|
memcpy(speakers, _alcDefaultSpeakers, sizeof(_alcDefaultSpeakers));
|
||||||
|
|
||||||
|
if (!(s = getenv("HOME")))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buf, "%s/.openal-speakers", s);
|
||||||
|
|
||||||
|
if (!(fp = fopen(buf, "r")))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(buf, 1024, fp))
|
||||||
|
{
|
||||||
|
if ((s = strchr(buf, '#')))
|
||||||
|
{
|
||||||
|
*s = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sscanf(buf, "%u: %f %f %f %f", &i, &gain,
|
||||||
|
pos + 0, pos + 1, pos + 2) == 5)
|
||||||
|
{
|
||||||
|
if (i >= _ALC_NUM_SPEAKERS)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gain < 0.0)
|
||||||
|
{
|
||||||
|
gain = 0.0;
|
||||||
|
}
|
||||||
|
else if (gain > 1.0)
|
||||||
|
{
|
||||||
|
gain = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
speakers[i].gain = gain * 127.5;
|
||||||
|
_alVectorNormalize(speakers[i].position, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
37
src/alc_speaker.h
Normal file
37
src/alc_speaker.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALC_SPEAKER_H_
|
||||||
|
#define _ALC_SPEAKER_H_
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
|
||||||
|
#define _ALC_NUM_SPEAKERS 8
|
||||||
|
|
||||||
|
typedef struct _AL_speaker
|
||||||
|
{
|
||||||
|
ALfloat gain;
|
||||||
|
ALfloat position[3];
|
||||||
|
}
|
||||||
|
AL_speaker;
|
||||||
|
|
||||||
|
ALvoid _alcLoadSpeakers(AL_speaker *);
|
||||||
|
|
||||||
|
#endif
|
104
src/alc_state.c
Normal file
104
src/alc_state.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include "alc_device.h"
|
||||||
|
#include "alc_error.h"
|
||||||
|
|
||||||
|
ALCvoid alcGetIntegerv(ALCdevice *dev, ALCenum param,
|
||||||
|
ALCsizei size, ALCint *data)
|
||||||
|
{
|
||||||
|
if (!data || size < sizeof(ALCint))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_VALUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(param)
|
||||||
|
{
|
||||||
|
case ALC_MAJOR_VERSION:
|
||||||
|
*data = 1;
|
||||||
|
break;
|
||||||
|
case ALC_MINOR_VERSION:
|
||||||
|
*data = 0;
|
||||||
|
break;
|
||||||
|
case ALC_ATTRIBUTES_SIZE:
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_DEVICE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*data = 8 * sizeof(ALCint);
|
||||||
|
break;
|
||||||
|
case ALC_ALL_ATTRIBUTES:
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_DEVICE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (size < (8 * sizeof(ALCint)))
|
||||||
|
{
|
||||||
|
_alcSetError(ALC_INVALID_VALUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data[0] = ALC_FREQUENCY;
|
||||||
|
data[1] = dev->freq;
|
||||||
|
data[2] = ALC_REFRESH;
|
||||||
|
data[3] = dev->refresh;
|
||||||
|
data[4] = ALC_SYNC;
|
||||||
|
data[5] = dev->sync;
|
||||||
|
data[6] = ALC_INVALID;
|
||||||
|
data[7] = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_alcSetError(ALC_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ALubyte *alcGetString(ALCdevice *dev ATTRIBUTE_UNUSED, ALCenum param)
|
||||||
|
{
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case ALC_DEFAULT_DEVICE_SPECIFIER:
|
||||||
|
return "";
|
||||||
|
case ALC_DEVICE_SPECIFIER:
|
||||||
|
return "";
|
||||||
|
case ALC_EXTENSIONS:
|
||||||
|
return "";
|
||||||
|
case ALC_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case ALC_INVALID_DEVICE:
|
||||||
|
return "There is no accessible sound device/driver/server";
|
||||||
|
case ALC_INVALID_CONTEXT:
|
||||||
|
return "The Context argument does not name a valid context";
|
||||||
|
case ALC_INVALID_ENUM:
|
||||||
|
return "Illegal paramater";
|
||||||
|
case ALC_INVALID_VALUE:
|
||||||
|
return "Invalid enum parameter value";
|
||||||
|
case ALC_OUT_OF_MEMORY:
|
||||||
|
return "Unable to allocate memory";
|
||||||
|
default:
|
||||||
|
_alcSetError(ALC_INVALID_ENUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
60
src/alut_main.c
Normal file
60
src/alut_main.c
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
#include <AL/alut.h>
|
||||||
|
|
||||||
|
void alutInit(int *argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
ALCcontext *ctx;
|
||||||
|
ALCdevice *dev;
|
||||||
|
|
||||||
|
if (!(dev = alcOpenDevice(0)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctx = alcCreateContext(dev, 0)))
|
||||||
|
{
|
||||||
|
alcCloseDevice(dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alcMakeContextCurrent(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void alutExit(void)
|
||||||
|
{
|
||||||
|
ALCcontext *ctx;
|
||||||
|
ALCdevice *dev;
|
||||||
|
|
||||||
|
if (!(ctx = alcGetCurrentContext()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = alcGetContextsDevice(ctx);
|
||||||
|
|
||||||
|
alcMakeContextCurrent(0);
|
||||||
|
alcDestroyContext(ctx);
|
||||||
|
alcCloseDevice(dev);
|
||||||
|
}
|
288
src/alut_wav.c
Normal file
288
src/alut_wav.c
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Christopher John Purnell
|
||||||
|
* cjp@lost.org.uk
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ansidecl.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <AL/alut.h>
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
|
||||||
|
#define WAV_RIFF 0x46464952
|
||||||
|
#define WAV_WAVE 0x45564157
|
||||||
|
#define WAV_fmt 0x20746D66
|
||||||
|
#define WAV_data 0x61746164
|
||||||
|
#define WAV_smpl 0x6C706D73
|
||||||
|
|
||||||
|
#define swap16le(D) (D)
|
||||||
|
#define swap32le(D) (D)
|
||||||
|
|
||||||
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
|
||||||
|
#define WAV_RIFF 0x52494646
|
||||||
|
#define WAV_WAVE 0x57415645
|
||||||
|
#define WAV_fmt 0x666D7420
|
||||||
|
#define WAV_data 0x64617461
|
||||||
|
#define WAV_smpl 0x736D706C
|
||||||
|
|
||||||
|
#define swap16le(D) (((D)<<8) | ((D)>>8))
|
||||||
|
#define swap32le(D) ((((D)<<24) | (((D)<<8)&0x00FF0000) | (((D)>>8)&0x0000FF00) | ((D)>>24)))
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unknown endian"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u_int32_t id;
|
||||||
|
u_int32_t size;
|
||||||
|
u_int32_t type;
|
||||||
|
u_int32_t *data;
|
||||||
|
u_int32_t len;
|
||||||
|
}
|
||||||
|
AL_wav_file;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u_int32_t id;
|
||||||
|
u_int32_t size;
|
||||||
|
u_int32_t *data;
|
||||||
|
}
|
||||||
|
AL_wav_chunk;
|
||||||
|
|
||||||
|
static ALboolean _alutReadWavHeader(AL_wav_file *file, u_int32_t *memory)
|
||||||
|
{
|
||||||
|
if ((file->id = *(memory++)) != WAV_RIFF)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->size = swap32le(*(memory++));
|
||||||
|
|
||||||
|
if (file->size < 4)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((file->type = *(memory++)) != WAV_WAVE)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->data = memory;
|
||||||
|
file->len = (file->size - 1) >> 2;
|
||||||
|
|
||||||
|
return AL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALboolean _alutReadWavChunk(AL_wav_file *file, AL_wav_chunk *chunk)
|
||||||
|
{
|
||||||
|
ALuint len;
|
||||||
|
|
||||||
|
if (file->len < 2)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk->id = file->data[0];
|
||||||
|
chunk->size = swap32le(file->data[1]);
|
||||||
|
|
||||||
|
len = (chunk->size + 11) >> 2;
|
||||||
|
|
||||||
|
if (file->len < len)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk->data = file->data + 2;
|
||||||
|
|
||||||
|
file->data += len;
|
||||||
|
file->len -= len;
|
||||||
|
|
||||||
|
return AL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alutLoadWAVMemory(ALbyte *memory, ALenum *format, ALvoid **data,
|
||||||
|
ALsizei *size, ALsizei *freq, ALboolean *loop)
|
||||||
|
{
|
||||||
|
AL_wav_file file;
|
||||||
|
AL_wav_chunk chunk;
|
||||||
|
ALuint bits = 0;
|
||||||
|
|
||||||
|
*data = 0;
|
||||||
|
*size = 0;
|
||||||
|
*freq = 0;
|
||||||
|
*format = 0;
|
||||||
|
*loop = 0;
|
||||||
|
|
||||||
|
if (!_alutReadWavHeader(&file, (u_int32_t *)memory))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (_alutReadWavChunk(&file, &chunk))
|
||||||
|
{
|
||||||
|
u_int16_t *data16 = (u_int16_t *)chunk.data;
|
||||||
|
|
||||||
|
switch (chunk.id)
|
||||||
|
{
|
||||||
|
case WAV_fmt:
|
||||||
|
if (data16[0] != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = swap16le(data16[7]);
|
||||||
|
*freq = swap32le(chunk.data[1]);
|
||||||
|
|
||||||
|
switch (swap16le(data16[1]))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
switch (bits)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
*format = AL_FORMAT_MONO8;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
*format = AL_FORMAT_MONO16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (bits)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
*format = AL_FORMAT_STEREO8;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
*format = AL_FORMAT_STEREO16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WAV_data:
|
||||||
|
if (!bits)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = malloc(chunk.size);
|
||||||
|
*size = chunk.size;
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
memcpy(*data, chunk.data, chunk.size);
|
||||||
|
#else
|
||||||
|
if (bits == 16)
|
||||||
|
{
|
||||||
|
u_int16_t *ptr = *data;
|
||||||
|
ALuint i, s = chunk.size << 1;
|
||||||
|
|
||||||
|
for (i = 0; i < s; i++)
|
||||||
|
{
|
||||||
|
ptr[i] = swap16le(data16[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(*data, chunk.data, chunk.size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case WAV_smpl:
|
||||||
|
*loop = swap32le(chunk.data[7]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alutLoadWAVFile(ALbyte *file, ALenum *format, ALvoid **data,
|
||||||
|
ALsizei *size, ALsizei *freq, ALboolean *loop)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
void *memory;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if ((fd = open(file, O_RDONLY)) < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fstat(fd, &st))
|
||||||
|
{
|
||||||
|
memory = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (memory != MAP_FAILED)
|
||||||
|
{
|
||||||
|
alutLoadWAVMemory(memory, format, data,
|
||||||
|
size, freq, loop);
|
||||||
|
munmap(memory, st.st_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALboolean alutLoadWAV(const char *fname, ALvoid **wave, ALsizei *format, ALsizei *size, ALsizei *bits, ALsizei *freq )
|
||||||
|
{
|
||||||
|
ALboolean loop;
|
||||||
|
|
||||||
|
alutLoadWAVFile((ALubyte *)fname, format, wave, size, freq, &loop);
|
||||||
|
|
||||||
|
if (! *wave)
|
||||||
|
{
|
||||||
|
return AL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*format)
|
||||||
|
{
|
||||||
|
case AL_FORMAT_MONO8:
|
||||||
|
case AL_FORMAT_STEREO8:
|
||||||
|
*bits = 8;
|
||||||
|
break;
|
||||||
|
case AL_FORMAT_MONO16:
|
||||||
|
case AL_FORMAT_STEREO16:
|
||||||
|
*bits = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALvoid alutUnloadWAV(ALenum format ATTRIBUTE_UNUSED, ALvoid *data,
|
||||||
|
ALsizei size ATTRIBUTE_UNUSED,
|
||||||
|
ALsizei freq ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user