mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Initial revision
This commit is contained in:
commit
5abac67626
47 changed files with 7915 additions and 0 deletions
41
CHANGELOG
Normal file
41
CHANGELOG
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
0.0.8 -> 0.0.9
|
||||||
|
|
||||||
|
* Makefile and configure.in changes
|
||||||
|
- added check for alsa driver package
|
||||||
|
- added spec file for RPM
|
||||||
|
|
||||||
|
0.0.7 -> 0.0.8
|
||||||
|
|
||||||
|
* added LGPL notice to all source and header files
|
||||||
|
|
||||||
|
0.0.6 -> 0.0.7
|
||||||
|
|
||||||
|
* added snd_cards_name function
|
||||||
|
|
||||||
|
0.0.5 -> 0.0.6
|
||||||
|
|
||||||
|
* fixed SND_PCM_OPEN constants
|
||||||
|
|
||||||
|
0.0.4 -> 0.0.5
|
||||||
|
|
||||||
|
* added snd_cards_mask function
|
||||||
|
* added info functions for pcm playback/record in control interface
|
||||||
|
* fixed Makefile bugs for shared library (added -fPIC)
|
||||||
|
|
||||||
|
0.0.3 -> 0.0.4
|
||||||
|
|
||||||
|
* changed COPYING policy from GPL to LGPL
|
||||||
|
* fixed bug in snd_mixer_channel_read & write
|
||||||
|
* added mixer exact support
|
||||||
|
* added pcm time mode support
|
||||||
|
* 'make install' is now possible
|
||||||
|
|
||||||
|
0.0.2 -> 0.0.3
|
||||||
|
|
||||||
|
* corrected documentation
|
||||||
|
|
||||||
|
0.0.1 -> 0.0.2
|
||||||
|
|
||||||
|
* added file COPYING
|
||||||
|
* added documentation in sgml + plan.txt
|
||||||
|
* minor changes in API for MIXER & PCM
|
||||||
481
COPYING
Normal file
481
COPYING
Normal file
|
|
@ -0,0 +1,481 @@
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, 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
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
54
Makefile
Normal file
54
Makefile
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
ifeq (Makefile.conf,$(wildcard Makefile.conf))
|
||||||
|
include Makefile.conf
|
||||||
|
else
|
||||||
|
dummy:
|
||||||
|
@echo
|
||||||
|
@echo "Please, run configure script as first..."
|
||||||
|
@echo
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all: include/soundlib.h
|
||||||
|
$(MAKE) -C src
|
||||||
|
$(MAKE) -C doc
|
||||||
|
@echo
|
||||||
|
@echo "ALSA library were sucessfully compiled."
|
||||||
|
@echo
|
||||||
|
|
||||||
|
include/soundlib.h: include/header.h include/version.h include/error.h include/footer.h \
|
||||||
|
include/control.h include/mixer.h include/pcm.h
|
||||||
|
cat include/header.h include/version.h include/error.h \
|
||||||
|
include/control.h include/mixer.h \
|
||||||
|
include/pcm.h \
|
||||||
|
include/footer.h > include/soundlib.h
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL) -m 644 -o root -g root include/soundlib.h ${includedir}/sys
|
||||||
|
$(INSTALL) -m 644 -o root -g root lib/libsound.a ${libdir}
|
||||||
|
$(LN_S) -f libsound.so.${SND_LIB_VERSION} ${libdir}/libsound.so
|
||||||
|
$(LN_S) -f libsound.so.${SND_LIB_VERSION} ${libdir}/libsound.so.${SND_LIB_MAJOR}
|
||||||
|
$(INSTALL) -m 644 -o root -g root lib/libsound.so.${SND_LIB_VERSION} ${libdir}
|
||||||
|
/sbin/ldconfig
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C include clean
|
||||||
|
$(MAKE) -C src clean
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
$(MAKE) -C doc clean
|
||||||
|
$(MAKE) -C utils clean
|
||||||
|
rm -f core .depend *.o *.orig *~
|
||||||
|
rm -f `find . -name "out.txt"`
|
||||||
|
|
||||||
|
pack: clean
|
||||||
|
rm -f config.cache config.log config.status Makefile.conf
|
||||||
|
chown -R root.root ../alsa-lib
|
||||||
|
tar cvz -C .. -f ../alsa-lib-$(SND_LIB_VERSION).tar.gz alsa-lib
|
||||||
|
|
||||||
|
publish: pack
|
||||||
|
cat ../alsa-lib-$(SND_LIB_VERSION).tar.gz | \
|
||||||
|
ssh -l root zarquon.jcu.cz /home/alsa/publishlib alsa-lib-$(SND_LIB_VERSION).tar.gz
|
||||||
25
Makefile.conf.in
Normal file
25
Makefile.conf.in
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#
|
||||||
|
# Configuration Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
srcdir=@srcdir@
|
||||||
|
VPATH=@srcdir@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
includedir=@includedir@
|
||||||
|
libdir=@libdir@
|
||||||
|
c_opts=@CFLAGS@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
SND_LIB_VERSION=@SND_LIB_VERSION@
|
||||||
|
SND_LIB_MAJOR=@SND_LIB_MAJOR@
|
||||||
|
SND_LIB_MINOR=@SND_LIB_MINOR@
|
||||||
|
SND_LIB_SUBMINOR=@SND_LIB_SUBMINOR@
|
||||||
|
|
||||||
|
CC=@CC@
|
||||||
|
CPP=@CPP@
|
||||||
|
INCLUDE=-I../include -I../../include
|
||||||
|
COPTS = $(c_opts)
|
||||||
|
COPTS += -Wall -Wstrict-prototypes -fomit-frame-pointer -pipe
|
||||||
|
LINKER=ld
|
||||||
|
LN_S=@LN_S@
|
||||||
63
configure.in
Normal file
63
configure.in
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_INIT(Makefile.conf.in)
|
||||||
|
AC_PREFIX_DEFAULT(/usr)
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_LN_S
|
||||||
|
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CONFIG_HEADER(include/config.h)
|
||||||
|
AC_CHECK_HEADERS(linux/sound.h)
|
||||||
|
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
dnl Checks for library functions.
|
||||||
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
|
||||||
|
dnl Check for ALSA driver package.
|
||||||
|
myprefix=$prefix
|
||||||
|
if test "$myprefix" = "NONE"; then
|
||||||
|
myprefix=$ac_default_prefix
|
||||||
|
fi
|
||||||
|
CFLAGS="-I$myprefix/include"
|
||||||
|
#echo "CFLAGS=$CFLAGS"
|
||||||
|
AC_MSG_CHECKING(for alsa-driver package)
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <linux/sound.h>
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
#ifndef SND_PROTOCOL_VERSION
|
||||||
|
exit(1);
|
||||||
|
#else
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AC_MSG_RESULT("present"),
|
||||||
|
AC_MSG_RESULT("not found"); echo "Fatal error: Install alsa-driver package at first..."; exit 1;,
|
||||||
|
AC_MSG_RESULT("not supported"); echo "Fatal error: Cross-compiling isn't supported..."; exit 1;,
|
||||||
|
)
|
||||||
|
|
||||||
|
dnl Check for version...
|
||||||
|
AC_MSG_CHECKING(for library version)
|
||||||
|
SND_LIB_VERSION=`cat $srcdir/version`
|
||||||
|
AC_DEFINE_UNQUOTED(SND_LIB_VERSION, "$SND_LIB_VERSION")
|
||||||
|
AC_SUBST(SND_LIB_VERSION)
|
||||||
|
SND_LIB_MAJOR=`echo $SND_LIB_VERSION | cut -d . -f 1`
|
||||||
|
AC_SUBST(SND_LIB_MAJOR)
|
||||||
|
SND_LIB_MINOR=`echo $SND_LIB_VERSION | cut -d . -f 2`
|
||||||
|
AC_SUBST(SND_LIB_MINOR)
|
||||||
|
SND_LIB_SUBMINOR=`echo $SND_LIB_VERSION | cut -d . -f 3`
|
||||||
|
AC_SUBST(SND_LIB_SUBMINOR)
|
||||||
|
AC_MSG_RESULT($SND_LIB_VERSION)
|
||||||
|
|
||||||
|
AC_OUTPUT(Makefile.conf include/version.h utils/alsa-lib.spec)
|
||||||
20
doc/Makefile
Normal file
20
doc/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../Makefile.conf
|
||||||
|
|
||||||
|
TARGETS=soundapi.txt \
|
||||||
|
soundapi.html
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
soundapi.txt: soundapi.sgml
|
||||||
|
sgml2txt soundapi.sgml
|
||||||
|
|
||||||
|
soundapi.html: soundapi.sgml
|
||||||
|
sgml2html soundapi.sgml
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.orig *~
|
||||||
47
doc/plan.txt
Normal file
47
doc/plan.txt
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
ALSA library plan
|
||||||
|
=================
|
||||||
|
|
||||||
|
=====
|
||||||
|
ST: Status of coding
|
||||||
|
NT: Note
|
||||||
|
RP: Responsible person
|
||||||
|
|
||||||
|
This file is maintained by Jaroslav Kysela <perex@jcu.cz>.
|
||||||
|
=====
|
||||||
|
|
||||||
|
Library code
|
||||||
|
============
|
||||||
|
|
||||||
|
1: Control interface routines
|
||||||
|
ST: Low-Level code done
|
||||||
|
RP: Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
1.1: Network layer
|
||||||
|
2: MIXER routines
|
||||||
|
ST: Low-Level code done
|
||||||
|
RP: Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
2.1: Network layer
|
||||||
|
3: PCM routines
|
||||||
|
ST: Low-Level code done
|
||||||
|
RP: Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
3.1: Network layer + mixing routines to allow playback more than one input
|
||||||
|
to one exclusive device
|
||||||
|
3.2: Player routines for digital data (.wav,.snd,.mp3 etc...) (???)
|
||||||
|
4: Instrument loading routines
|
||||||
|
4.1: Network layer
|
||||||
|
4.2: Instrument format interface
|
||||||
|
4.2.1: GF1 patches (.pat)
|
||||||
|
4.2.2: AMD FFFF
|
||||||
|
4.2.3: SoundFont (for SoundBlaster)
|
||||||
|
4.2.4: FM/OPL3 instrument formats
|
||||||
|
5: Raw FM/OPL3 interface
|
||||||
|
6: SYNTH interface
|
||||||
|
6.1: Network layer
|
||||||
|
6.2: player for .MOD,.S3M etc. (???)
|
||||||
|
7: Instrument server interface
|
||||||
|
8: Instrument configuration routines for MIDI
|
||||||
|
9: raw MIDI interface
|
||||||
|
9.1: Network layer
|
||||||
|
10: sequenced MIDI interface
|
||||||
|
10.1: Network layer
|
||||||
|
10.2: player for MIDI files
|
||||||
34
doc/soundapi-1.html
Normal file
34
doc/soundapi-1.html
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API: Introduction</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
Previous
|
||||||
|
<A HREF="soundapi-2.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc1">Table of Contents</A>
|
||||||
|
<HR>
|
||||||
|
<H2><A NAME="s1">1. Introduction</A></H2>
|
||||||
|
|
||||||
|
<P>The Advanced Linux Sound Architecture comes with a kernel API & library API.
|
||||||
|
This document describes the library API and how it interfaces with the kernel
|
||||||
|
API. The kernal API will probably never be documented in standalone form.</P>
|
||||||
|
<P>Application programmers should use the library API rather than kernel API.
|
||||||
|
The Library offers 100% of the functionally of the kernel API, but add next
|
||||||
|
major improvements in usability, making the application code simpler and
|
||||||
|
better looking. In addition, some of the some fixes/compatibility code in,
|
||||||
|
may be placed in the library code instead of the kernel driver.</P>
|
||||||
|
<P>For a complete list of all variables and functions in the API you should look
|
||||||
|
at the following header files:
|
||||||
|
<OL>
|
||||||
|
<LI>/usr/include/sys/soundlib.h</LI>
|
||||||
|
<LI>/usr/include/linux/sound.h</LI>
|
||||||
|
<LI>/usr/include/linux/sounddetect.h</LI>
|
||||||
|
</OL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
Previous
|
||||||
|
<A HREF="soundapi-2.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc1">Table of Contents</A>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
44
doc/soundapi-2.html
Normal file
44
doc/soundapi-2.html
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API: Error Codes</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<A HREF="soundapi-1.html">Previous</A>
|
||||||
|
<A HREF="soundapi-3.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc2">Table of Contents</A>
|
||||||
|
<HR>
|
||||||
|
<H2><A NAME="s2">2. Error Codes</A></H2>
|
||||||
|
|
||||||
|
<P>All functions return int (or some sort of signed value). If this value
|
||||||
|
is negative it represents an error code. Codes up to SND_ERROR_BEGIN (500000)
|
||||||
|
represents standard system errors. Codes equal or greather than this value
|
||||||
|
represents sound library API errors. All error codes begin with the prefix
|
||||||
|
<I>SND_ERROR_</I>.</P>
|
||||||
|
|
||||||
|
<H2><A NAME="ss2.1">2.1 Error Codes in Detail</A></H2>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT><B>SND_ERROR_UNCOMPATIBLE_VERSION (500000)</B><DD><P>This error is caused if the driver uses an incompatible kernel API for this
|
||||||
|
interface and hence the library doesn't know how this API can be used.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
<H2><A NAME="ss2.2">2.2 Functions</A></H2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H3>const char *snd_strerror( int errnum ) </H3>
|
||||||
|
|
||||||
|
<P>This functions converts error code to a string. Its functionality is the same
|
||||||
|
as the <I>strerror</I> function from the standard C library, but this
|
||||||
|
function returns correct strings for sound error codes, too.</P>
|
||||||
|
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
<A HREF="soundapi-1.html">Previous</A>
|
||||||
|
<A HREF="soundapi-3.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc2">Table of Contents</A>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
159
doc/soundapi-3.html
Normal file
159
doc/soundapi-3.html
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API: Control Interface</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<A HREF="soundapi-2.html">Previous</A>
|
||||||
|
<A HREF="soundapi-4.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc3">Table of Contents</A>
|
||||||
|
<HR>
|
||||||
|
<H2><A NAME="s3">3. Control Interface</A></H2>
|
||||||
|
|
||||||
|
<P>The control interfaces gives application various information about the
|
||||||
|
currently installed sound driver in the system. The interface should be used
|
||||||
|
to detect if another sound interface is present for selected soundcard or,
|
||||||
|
for example, to create a list of devices (MIXER, PCM etc) from which
|
||||||
|
the user can select.</P>
|
||||||
|
|
||||||
|
<H2><A NAME="ss3.1">3.1 Low-Level Layer</A></H2>
|
||||||
|
|
||||||
|
<H3>int snd_cards( void ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the number of soundcards present in the system, if any. Otherwise
|
||||||
|
it returns a negative value, which maps to an error code. This function
|
||||||
|
will return 0 if no soundcards are detected.</P>
|
||||||
|
|
||||||
|
<H3>unsigned int snd_cards_mask( void ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the bitmap of soundcards present in the system, if any. Otherwise
|
||||||
|
it returns a negative value, which maps to an error code. This function
|
||||||
|
will return 0 if no soundcards are detected. First soundcard is represented
|
||||||
|
with bit 0.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_open( void **handle, int card ) </H3>
|
||||||
|
|
||||||
|
<P>Creates a new handle and opens communication with the kernel sound
|
||||||
|
control interface for soundcard number <I>card</I> (0-N). The function
|
||||||
|
also checks if protocol is compatible, so as to prevent the use of old
|
||||||
|
programs with a new kernel API. Function returns zero if successful,
|
||||||
|
otherwise an error code is returned.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_close( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Function frees all resources allocated with control handle and
|
||||||
|
closes the kernel sound control interface. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_file_descriptor( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Function returns file descriptor for the kernel sound control interface.
|
||||||
|
This function should be used in very special cases. Function returns
|
||||||
|
a negative error code if some error was encountered.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the info structure with data about the sound hardware referenced
|
||||||
|
by handle. Function returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_CTL_GCAPS_MIDI 0x0000001 /* driver has MIDI interface */
|
||||||
|
|
||||||
|
#define SND_CTL_LCAPS_SYNTH 0x0000001 /* soundcard has synthesizer */
|
||||||
|
#define SND_CTL_LCAPS_RAWFM 0x0000002 /* soundcard has RAW FM/OPL3 */
|
||||||
|
|
||||||
|
struct snd_ctl_hw_info {
|
||||||
|
unsigned int type; /* type of card - see SND_CARD_TYPE_XXXX */
|
||||||
|
unsigned int gcaps; /* see SND_CTL_GCAPS_XXXX */
|
||||||
|
unsigned int lcaps; /* see SND_CTL_LCAPS_XXXX */
|
||||||
|
unsigned int pcmdevs; /* count of PCM devices (0 to N) */
|
||||||
|
unsigned int mixerdevs; /* count of MIXER devices (0 to N) */
|
||||||
|
unsigned int mididevs; /* count of raw MIDI devices (0 to N) */
|
||||||
|
char id[8]; /* ID of card (user selectable) */
|
||||||
|
char name[80]; /* name/info text about soundcard */
|
||||||
|
unsigned char reserved[128]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about the PCM device. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code. Details about
|
||||||
|
the snd_pcm_info_t structure are in the <B>Digital Audio (PCM) Interface</B>
|
||||||
|
section. The argument <I>dev</I> selects the device number for the
|
||||||
|
soundcard referenced by *handle. Its range is 0 to N where N is
|
||||||
|
<I>struct snd_ctl_hw_info -> pcmdevs - 1</I>. This function will work if
|
||||||
|
the selected PCM device is busy, too. It should be used to collect
|
||||||
|
information about PCM devices without exclusive lock.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about the PCM device and playback direction.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
Details about the snd_pcm_playback_info_t structure are in the
|
||||||
|
<B>Digital Audio (PCM) Interface</B> section. The argument <I>dev</I>
|
||||||
|
selects the device number for the soundcard referenced by *handle. Its
|
||||||
|
range is 0 to N where N is <I>struct snd_ctl_hw_info -> pcmdevs - 1</I>.
|
||||||
|
This function will work if the selected PCM device is busy, too. It should
|
||||||
|
be used to collect information about PCM devices without exclusive lock.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about the PCM device and record direction.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
Details about the snd_pcm_record_info_t structure are in the
|
||||||
|
<B>Digital Audio (PCM) Interface</B> section. The argument <I>dev</I>
|
||||||
|
selects the device number for the soundcard referenced by *handle. Its
|
||||||
|
range is 0 to N where N is <I>struct snd_ctl_hw_info -> pcmdevs - 1</I>.
|
||||||
|
This function will work if the selected PCM device is busy, too. It should
|
||||||
|
be used to collect information about PCM devices without exclusive lock.</P>
|
||||||
|
|
||||||
|
<H3>int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about the mixer device. Returns zero
|
||||||
|
if successful, otherwise it returns an error code. Details about the
|
||||||
|
snd_mixer_info_t structure are in the <B>Mixer Interface</B> section.
|
||||||
|
The argument <I>dev</I> specifies the device number for the appropriate
|
||||||
|
soundcard. Its range is 0 to N where N found from
|
||||||
|
<I>struct snd_ctl_hw_info -> mixerdevs - 1</I>.
|
||||||
|
It should be used to collect information about mixer devices.</P>
|
||||||
|
|
||||||
|
|
||||||
|
<H2><A NAME="ss3.2">3.2 Examples</A></H2>
|
||||||
|
|
||||||
|
<P>The following example shows how all PCM devices can be detected for the first
|
||||||
|
soundcard (#0) in the system.</P>
|
||||||
|
<P>
|
||||||
|
<BLOCKQUOTE><CODE>
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
int card = 0, err;
|
||||||
|
void *handle;
|
||||||
|
stuct snd_ctl_hw_info info;
|
||||||
|
|
||||||
|
if ( (err = snd_ctl_open( &handle, card )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( (err = snd_ctl_hw_info( handle, &info )) < 0 ) {
|
||||||
|
fprintf( stderr, "hw info failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( "Installed PCM devices for card #i: %i\n", card + 1, info.pcmdevs );
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</CODE></BLOCKQUOTE>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
<A HREF="soundapi-2.html">Previous</A>
|
||||||
|
<A HREF="soundapi-4.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc3">Table of Contents</A>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
268
doc/soundapi-4.html
Normal file
268
doc/soundapi-4.html
Normal file
|
|
@ -0,0 +1,268 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API: Mixer Interface</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<A HREF="soundapi-3.html">Previous</A>
|
||||||
|
<A HREF="soundapi-5.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc4">Table of Contents</A>
|
||||||
|
<HR>
|
||||||
|
<H2><A NAME="s4">4. Mixer Interface</A></H2>
|
||||||
|
|
||||||
|
<P>The Mixer Interface allows applications to change the volume level of
|
||||||
|
a soundcard's input/output channels in both the linear range (0-100)
|
||||||
|
and in decibels. It also supports features like hardware mute, input
|
||||||
|
sound source, etc.</P>
|
||||||
|
|
||||||
|
<H2><A NAME="ss4.1">4.1 Low-Level Layer</A></H2>
|
||||||
|
|
||||||
|
<P>Mixer devices aren't opened exclusively. This allows applications to
|
||||||
|
open a device multiple times with one or more processes.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_open( void **handle, int card, int device ) </H3>
|
||||||
|
|
||||||
|
<P>Creates new handle and opens a connection to the kernel sound
|
||||||
|
mixer interface for soundcard number <I>card</I> (0-N) and mixer
|
||||||
|
device number <I>device</I>. Also checks if protocol is
|
||||||
|
compatible to prevent use of old programs with new kernel API. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_close( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Frees all resources allocated to the mixer handle and
|
||||||
|
closes its connection to the kernel sound mixer interface. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_file_descriptor( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the file descriptor for the connection to the kernel sound
|
||||||
|
mixer interface. This function should be used only in very
|
||||||
|
special cases. Function returns a negative error code if an
|
||||||
|
error was encountered. </P>
|
||||||
|
<P>The file descriptor should be used for the <I>select</I> synchronous
|
||||||
|
multiplexer function for deterimeing read direction. Applications should
|
||||||
|
call <I>snd_mixer_read</I> function if some data is waiting to be read.
|
||||||
|
It is recomended that you do this, since it leaves place for this function
|
||||||
|
to handle some new kernel API specifications.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_channels( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the count of mixer channels for appropriate mixer device, otherwise
|
||||||
|
the return value is negative, and signifies an error code. Never returns
|
||||||
|
zero.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_info( void *handle, snd_mixer_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with information about the mixer associated with
|
||||||
|
*handle. Returns zero if successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_MIXER_INFO_CAP_EXCL_RECORD 0x00000001
|
||||||
|
|
||||||
|
struct snd_mixer_info {
|
||||||
|
unsigned int type; /* type of soundcard - SND_CARD_TYPE_XXXX */
|
||||||
|
unsigned int channels; /* count of mixer devices */
|
||||||
|
unsigned int caps; /* some flags about this device (SND_MIXER_INFO_CAP_XXXX) */
|
||||||
|
unsigned char id[32]; /* ID of this mixer */
|
||||||
|
unsigned char name[80]; /* name of this device */
|
||||||
|
char reserved[ 32 ]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_channel( void *handle, const char *channel_id ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the channel number (index) associated with channel_id (channel name),
|
||||||
|
or returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_MIXER_ID_MASTER "Master"
|
||||||
|
#define SND_MIXER_ID_BASS "Bass"
|
||||||
|
#define SND_MIXER_ID_TREBLE "Treble"
|
||||||
|
#define SND_MIXER_ID_SYNTHESIZER "Synth"
|
||||||
|
#define SND_MIXER_ID_SYNTHESIZER1 "Synth 1"
|
||||||
|
#define SND_MIXER_ID_FM "FM"
|
||||||
|
#define SND_MIXER_ID_EFFECT "Effect"
|
||||||
|
#define SND_MIXER_ID_PCM "PCM"
|
||||||
|
#define SND_MIXER_ID_PCM1 "PCM 1"
|
||||||
|
#define SND_MIXER_ID_LINE "Line-In"
|
||||||
|
#define SND_MIXER_ID_MIC "MIC"
|
||||||
|
#define SND_MIXER_ID_CD "CD"
|
||||||
|
#define SND_MIXER_ID_GAIN "Record-Gain"
|
||||||
|
#define SND_MIXER_ID_IGAIN "In-Gain"
|
||||||
|
#define SND_MIXER_ID_OGAIN "Out-Gain"
|
||||||
|
#define SND_MIXER_ID_LOOPBACK "Loopback"
|
||||||
|
#define SND_MIXER_ID_SPEAKER "PC Speaker"
|
||||||
|
#define SND_MIXER_ID_AUXA "Aux A"
|
||||||
|
#define SND_MIXER_ID_AUXB "Aux B"
|
||||||
|
#define SND_MIXER_ID_AUXC "Aux C"
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_exact_mode( void *handle, int enable ) </H3>
|
||||||
|
|
||||||
|
<P>Turns on or off (by default) exact mode. This mode allows to application
|
||||||
|
set/get volume values in exact range which uses hardware. In non-exact
|
||||||
|
mode is range always from 0 to 100 and conversion to hardware range does
|
||||||
|
driver. Function returns zero if successful, otherwise it returns an error
|
||||||
|
code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure. The argument <I>channel</I> specifies channel
|
||||||
|
(0 to N) for which is the info requested. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_MIXER_CINFO_CAP_RECORD 0x00000001
|
||||||
|
#define SND_MIXER_CINFO_CAP_STEREO 0x00000002
|
||||||
|
#define SND_MIXER_CINFO_CAP_MUTE 0x00000004
|
||||||
|
#define SND_MIXER_CINFO_CAP_HWMUTE 0x00000008 /* channel supports hardware mute */
|
||||||
|
#define SND_MIXER_CINFO_CAP_DIGITAL 0x00000010 /* channel does digital (not analog) mixing */
|
||||||
|
#define SND_MIXER_CINOF_CAP_INPUT 0x00000020 /* input channel */
|
||||||
|
|
||||||
|
struct snd_mixer_channel_info {
|
||||||
|
unsigned int channel; /* channel # (filled by application) */
|
||||||
|
unsigned int parent; /* parent channel # or SND_MIXER_PARENT */
|
||||||
|
unsigned char name[12]; /* name of this device */
|
||||||
|
unsigned int caps; /* some flags about this device (SND_MIXER_CINFO_XXXX) */
|
||||||
|
int min; /* min. value when exact mode (or always 0) */
|
||||||
|
int max; /* max. value when exact mode (or always 100) */
|
||||||
|
int min_dB; /* minimum decibel value (*100) */
|
||||||
|
int max_dB; /* maximum decibel value (*100) */
|
||||||
|
int step_dB; /* step decibel value (*100) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *data structure. The argument <I>channel</I> specifies
|
||||||
|
the channel (0 to N) for which is data requested. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_MIXER_FLG_RECORD 0x00000001 /* channel record source flag */
|
||||||
|
#define SND_MIXER_FLG_MUTE_LEFT 0x00010000
|
||||||
|
#define SND_MIXER_FLG_MUTE_RIGHT 0x00020000
|
||||||
|
#define SND_MIXER_FLG_MUTE 0x00030000
|
||||||
|
#define SND_MIXER_FLG_DECIBEL 0x40000000
|
||||||
|
#define SND_MIXER_FLG_FORCE 0x80000000
|
||||||
|
|
||||||
|
struct snd_mixer_channel {
|
||||||
|
unsigned int channel; /* channel # (filled by application) */
|
||||||
|
unsigned int flags; /* some flags to read/write (SND_MIXER_FLG_XXXX) */
|
||||||
|
int left; /* min - max when exact mode (or 0 - 100) */
|
||||||
|
int right; /* min - max when exact mode (or 0 - 100) */
|
||||||
|
int left_dB; /* dB * 100 */
|
||||||
|
int right_dB; /* dB * 100 */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT><B>SND_MIXER_FLG_RECORD</B><DD><P>Record source flag.</P>
|
||||||
|
<DT><B>SND_MIXER_FLG_DECIBEL</B><DD><P>If this bit is set, driver set volume from dB variables <I>left_dB</I>
|
||||||
|
and <I>right_dB</I>.</P>
|
||||||
|
<DT><B>SND_MIXER_FLG_FORCE</B><DD><P>Force set - this bit shouldn't be used from user space. Reserved for
|
||||||
|
kernel.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data ) </H3>
|
||||||
|
|
||||||
|
<P>Writes the *data structure to kernel. The <I>channel</I> argument
|
||||||
|
specifies the channel (0 to N) for which is data is to be applied.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
This functions is the opposite of <I>snd_mixer_channel_read</I>.</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_special_read( void *handle, snd_mixer_special_t *special ) </H3>
|
||||||
|
|
||||||
|
<P>Not documented...</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_special_write( void *handle, snd_mixer_special_t *special ) </H3>
|
||||||
|
|
||||||
|
<P>Not documented...</P>
|
||||||
|
|
||||||
|
<H3>int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks ) </H3>
|
||||||
|
|
||||||
|
<P>This function reads and parses data from driver. Parsed actions are returned
|
||||||
|
back to the application using the <I>callbacks</I> structure. Applications
|
||||||
|
should not parse data from the driver in standard cases. This function
|
||||||
|
returns immediately after all data is read from driver. Does not
|
||||||
|
block process.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
typedef struct snd_mixer_callbacks {
|
||||||
|
void *private_data; /* should be used by application */
|
||||||
|
void (*channel_was_changed)( void *private_data, int channel );
|
||||||
|
void *reserved[15]; /* reserved for future use - must be NULL!!! */
|
||||||
|
} snd_mixer_callbacks_t;
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
<H2><A NAME="ss4.2">4.2 Examples</A></H2>
|
||||||
|
|
||||||
|
<P>The following example shows installed mixer channels for soundcard #0 and
|
||||||
|
mixer device #0 in the system, and also sets the master volume (if present)
|
||||||
|
to 50.</P>
|
||||||
|
<P>
|
||||||
|
<BLOCKQUOTE><CODE>
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
int card = 0, device = 0, err;
|
||||||
|
void *handle;
|
||||||
|
snd_mixer_info_t info;
|
||||||
|
snd_mixer_channel_t channel;
|
||||||
|
|
||||||
|
if ( (err = snd_mixer_open( &handle, card, device )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( (err = snd_mixer_info( handle, &info )) < 0 ) {
|
||||||
|
fprintf( stderr, "info failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( "Installed MIXER channels for card #i and device %i: %i\n",
|
||||||
|
card + 1, device, info.channels );
|
||||||
|
master = snd_mixer_channel( handle, SND_MIXER_ID_MASTER );
|
||||||
|
if ( master >= 0 ) {
|
||||||
|
if ( (err = snd_mixer_read( handle, master, &channel )) < 0 ) {
|
||||||
|
fprintf( stderr, "master read failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channel -> left = channel -> right = 50;
|
||||||
|
if ( (err = snd_mixer_write( handle, master, &channel )) < 0 ) {
|
||||||
|
fprintf( stderr, "master write failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</CODE></BLOCKQUOTE>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
<A HREF="soundapi-3.html">Previous</A>
|
||||||
|
<A HREF="soundapi-5.html">Next</A>
|
||||||
|
<A HREF="soundapi.html#toc4">Table of Contents</A>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
552
doc/soundapi-5.html
Normal file
552
doc/soundapi-5.html
Normal file
|
|
@ -0,0 +1,552 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API: Digital Audio (PCM) Interface</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<A HREF="soundapi-4.html">Previous</A>
|
||||||
|
Next
|
||||||
|
<A HREF="soundapi.html#toc5">Table of Contents</A>
|
||||||
|
<HR>
|
||||||
|
<H2><A NAME="s5">5. Digital Audio (PCM) Interface</A></H2>
|
||||||
|
|
||||||
|
<P>Digital audio is the most commonly used method of representing sound inside
|
||||||
|
a computer. In this method sound is stored as a sequence of samples taken
|
||||||
|
from the audio signal using constant time intervals. A sample represents
|
||||||
|
volume of the signal at the moment when it was measured. In uncompressed
|
||||||
|
digital audio each sample require one or more bytes of storage. The number of
|
||||||
|
bytes required depends on number of channels (mono, stereo) and sample
|
||||||
|
format (8 or 16 bits, mu-Law, etc.). The length of this interval determines
|
||||||
|
the sampling rate. Commonly used sampling rates are between 8 kHz (telephone
|
||||||
|
quality) and 48 kHz (DAT tapes).</P>
|
||||||
|
<P>The physical devices used in digital audio are called the ADC (Analog to
|
||||||
|
Digital Converter) and DAC (Digital to Analog Converter). A device containing
|
||||||
|
both ADC and DAC is commonly known as a codec. The codec device used in
|
||||||
|
a Sound Blaster cards is called a DSP which is somewhat misleading since DSP
|
||||||
|
also stands for Digital Signal Processor (the SB DSP chip is very limited
|
||||||
|
when compared to "true" DSP chips). </P>
|
||||||
|
<P>Sampling parameters affect the quality of sound which can be reproduced from
|
||||||
|
the recorded signal. The most fundamental parameter is sampling rate which
|
||||||
|
limits the highest frequency than can be stored. It is well known (Nyquist's
|
||||||
|
Sampling Theorem) that the highest frequency that can be stored in a sampled
|
||||||
|
signal is at most 1/2 of the sampling frequency. For example, a 8 kHz sampling
|
||||||
|
rate permits the recording of a signal in which the highest frequency is less
|
||||||
|
than 4 kHz. Higher frequency signals must be filtered out before feeding them
|
||||||
|
to DAC. </P>
|
||||||
|
<P>Sample encoding limits the dynamic range of recorded signal (difference between
|
||||||
|
the faintest and the loudest signal that can be recorded). In theory the
|
||||||
|
maximum dynamic range of signal is number_of_bits * 6 dB . This means that
|
||||||
|
8 bits sampling resolution gives dynamic range of 48 dB and 16 bit resolution
|
||||||
|
gives 96 dB. </P>
|
||||||
|
<P>Quality has price. The number of bytes required to store an audio sequence
|
||||||
|
depends on sampling rate, number of channels and sampling resolution. For
|
||||||
|
example just 8000 bytes of memory is required to store one second of sound
|
||||||
|
using 8 kHz/8 bits/mono but 48 kHz/16bit/stereo takes 192 kilobytes. A 64 kbps
|
||||||
|
ISDN channel is required to transfer a 8kHz/8bit/mono audio stream in real
|
||||||
|
time, and about 1.5 Mbps is required for DAT quality (48kHz/16bit/stereo).
|
||||||
|
On the other hand it is possible to store just 5.46 seconds of sound in
|
||||||
|
a megabyte of memory when using 48kHz/16bit/stereo sampling. With
|
||||||
|
8kHz/8bits/mono it is possible to store 131 seconds of sound using the same
|
||||||
|
amount of memory. It is possible to reduce memory and communication costs by
|
||||||
|
compressing the recorded signal but this is out of the scope of this document. </P>
|
||||||
|
|
||||||
|
<H2><A NAME="ss5.1">5.1 Low-Level Layer</A></H2>
|
||||||
|
|
||||||
|
<P>Audio devices are opened exclusively for a selected direction. This doesn't
|
||||||
|
allow open from more than one processes for the same audio device in the
|
||||||
|
same direction, but does allow one open call to each playback direction and
|
||||||
|
second open call to record direction independently. Audio devices return
|
||||||
|
EBUSY error to applications when other applications have already opened the
|
||||||
|
requested direction.</P>
|
||||||
|
<P>Low-Level layer supports these formats:
|
||||||
|
<BLOCKQUOTE><CODE>
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_PCM_SFMT_MU_LAW 0
|
||||||
|
#define SND_PCM_SFMT_A_LAW 1
|
||||||
|
#define SND_PCM_SFMT_IMA_ADPCM 2
|
||||||
|
#define SND_PCM_SFMT_U8 3
|
||||||
|
#define SND_PCM_SFMT_S16_LE 4
|
||||||
|
#define SND_PCM_SFMT_S16_BE 5
|
||||||
|
#define SND_PCM_SFMT_S8 6
|
||||||
|
#define SND_PCM_SFMT_U16_LE 7
|
||||||
|
#define SND_PCM_SFMT_U16_BE 8
|
||||||
|
#define SND_PCM_SFMT_MPEG 9
|
||||||
|
#define SND_PCM_SFMT_GSM 10
|
||||||
|
|
||||||
|
#define SND_PCM_FMT_MU_LAW (1 << SND_PCM_SFMT_MU_LAW)
|
||||||
|
#define SND_PCM_FMT_A_LAW (1 << SND_PCM_SFMT_A_LAW)
|
||||||
|
#define SND_PCM_FMT_IMA_ADPCM (1 << SND_PCM_SFMT_IMA_ADPCM)
|
||||||
|
#define SND_PCM_FMT_U8 (1 << SND_PCM_SFMT_U8)
|
||||||
|
#define SND_PCM_FMT_S16_LE (1 << SND_PCM_SFMT_S16_LE)
|
||||||
|
#define SND_PCM_FMT_S16_BE (1 << SND_PCM_SFMT_S16_BE)
|
||||||
|
#define SND_PCM_FMT_S8 (1 << SND_PCM_SFMT_S8)
|
||||||
|
#define SND_PCM_FMT_U16_LE (1 << SND_PCM_SFMT_U16_LE)
|
||||||
|
#define SND_PCM_FMT_U16_BE (1 << SND_PCM_SFMT_U16_BE)
|
||||||
|
#define SND_PCM_FMT_MPEG (1 << SND_PCM_SFMT_MPEG)
|
||||||
|
#define SND_PCM_FMT_GSM (1 << SND_PCM_SFMT_GSM)
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</CODE></BLOCKQUOTE>
|
||||||
|
|
||||||
|
Constants with prefix <B>SND_PCM_FMT_</B> are used in info structures
|
||||||
|
and constants with prefix <B>SND_PCM_SFMT_</B> are used in format structures.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_open( void **handle, int card, int device, int mode ) </H3>
|
||||||
|
|
||||||
|
<P>Creates a new handle and opens a connection to kernel sound
|
||||||
|
audio interface for soundcard number <I>card</I> (0-N) and audio
|
||||||
|
device number <I>device</I>. Function also checks if protocol is
|
||||||
|
compatible to prevent use of old programs with a new kernel API. Function
|
||||||
|
returns zero if successful,ful otherwise it returns an error code.
|
||||||
|
Error code -EBUSY is returned when some process ownes the selected direction.</P>
|
||||||
|
<P>Default format after opening is mono <I>mu-Law</I> at 8000Hz. This device
|
||||||
|
can be used directly for playback of standard .au (Sparc) files.</P>
|
||||||
|
<P>The following modes should be used for the <I>mode</I> argument:
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_PCM_OPEN_PLAYBACK (O_WRONLY)
|
||||||
|
#define SND_PCM_OPEN_RECORD (O_RDONLY)
|
||||||
|
#define SND_PCM_OPEN_DUPLEX (O_RDWR)
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_close( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Frees all resources allocated with audio handle and
|
||||||
|
closes the connection to the kernel sound audio interface. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_file_descriptor( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>Returns the file descriptor of the connection to the kernel sound
|
||||||
|
audio interface. Function returns an error code if an
|
||||||
|
error was encountered. </P>
|
||||||
|
<P>The file descriptor should be used for the <I>select</I> synchronous
|
||||||
|
multiplexer function for setting the read direction. Application should
|
||||||
|
call <I>snd_pcm_read</I> or <I>snd_pcm_write</I> functions if some
|
||||||
|
data is waiting for reading or a write can be performed. Calling this
|
||||||
|
function is highly recomended, as it leaves a place for the API to things
|
||||||
|
like data conversions, if needed.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_block_mode( void *handle, int enable ) </H3>
|
||||||
|
|
||||||
|
<P>Sets up block (default) or nonblock mode for a handle. Block mode suspends
|
||||||
|
execution of a program when <I>snd_pcm_read</I> or <I>snd_pcm_write</I>
|
||||||
|
is called for the time which is needed for the actual playback or record
|
||||||
|
over of the entire buffer. In nonblock mode, programs aren't suspended and
|
||||||
|
the above functions returns immediately with the count of bytes which were
|
||||||
|
read or written by the driver. When used in this way, don't try to use the
|
||||||
|
entire buffer after the call, but instead process the number of bytes
|
||||||
|
returned, and call the function again.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_info( void *handle, snd_pcm_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about the PCM device selected by
|
||||||
|
*handle. Function returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_PCM_INFO_CODEC 0x00000001
|
||||||
|
#define SND_PCM_INFO_DSP SND_PCM_INFO_CODEC
|
||||||
|
#define SND_PCM_INFO_MMAP 0x00000002 /* reserved */
|
||||||
|
#define SND_PCM_INFO_PLAYBACK 0x00000100
|
||||||
|
#define SND_PCM_INFO_RECORD 0x00000200
|
||||||
|
#define SND_PCM_INFO_DUPLEX 0x00000400
|
||||||
|
#define SND_PCM_INFO_DUPLEX_LIMIT 0x00000800 /* rate for playback & record are same */
|
||||||
|
|
||||||
|
struct snd_pcm_info {
|
||||||
|
unsigned int type; /* soundcard type */
|
||||||
|
unsigned int flags; /* see SND_PCM_INFO_XXXX */
|
||||||
|
unsigned char id[32]; /* ID of this PCM device */
|
||||||
|
unsigned char name[80]; /* name of this device */
|
||||||
|
unsigned char reserved[64]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>SND_PCM_INFO_MMAP</B><DD><P>This flag is reserved and should be never used. It remains for
|
||||||
|
compatibility with Open Sound System driver.</P>
|
||||||
|
<DT><B>SND_PCM_INFO_DUPLEX_LIMIT</B><DD><P>If this bit is set, rate must be same for playback and record direction.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure with data about PCM playback. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_PCM_PINFO_BATCH 0x00000001
|
||||||
|
#define SND_PCM_PINFO_8BITONLY 0x00000002
|
||||||
|
#define SND_PCM_PINFO_16BITONLY 0x00000004
|
||||||
|
|
||||||
|
struct snd_pcm_playback_info {
|
||||||
|
unsigned int flags; /* see SND_PCM_PINFO_XXXX */
|
||||||
|
unsigned int formats; /* supported formats */
|
||||||
|
unsigned int min_rate; /* min rate (in Hz) */
|
||||||
|
unsigned int max_rate; /* max rate (in Hz) */
|
||||||
|
unsigned int min_channels; /* min channels (probably always 1) */
|
||||||
|
unsigned int max_channels; /* max channels */
|
||||||
|
unsigned int buffer_size; /* playback buffer size */
|
||||||
|
unsigned int min_fragment_size; /* min fragment size in bytes */
|
||||||
|
unsigned int max_fragment_size; /* max fragment size in bytes */
|
||||||
|
unsigned int fragment_align; /* align fragment value */
|
||||||
|
unsigned char reserved[64]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>SND_PCM_PINFO_BATCH</B><DD><P>Driver implements double buffering with this device. This means that
|
||||||
|
the chip used for data processing has its own memory, and output should be
|
||||||
|
more delayed than if a traditional codec chip is used.</P>
|
||||||
|
<DT><B>SND_PCM_PINFO_8BITONLY</B><DD><P>If this bit is set, the driver uses 8-bit format for 16-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 16-bit duplex. If this bit is set
|
||||||
|
application or highter digital audio layer should do the conversion from
|
||||||
|
16-bit samples to 8-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.</P>
|
||||||
|
<DT><B>SND_PCM_PINFO_16BITONLY</B><DD><P>If this bit is set, driver uses 16-bit format for 8-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 8-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do conversion from
|
||||||
|
8-bit samples to 16-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *info structure. Returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
#define SND_PCM_RINFO_BATCH 0x00000001
|
||||||
|
#define SND_PCM_RINFO_8BITONLY 0x00000002
|
||||||
|
#define SND_PCM_RINFO_16BITONLY 0x00000004
|
||||||
|
|
||||||
|
struct snd_pcm_record_info {
|
||||||
|
unsigned int flags; /* see to SND_PCM_RINFO_XXXX */
|
||||||
|
unsigned int formats; /* supported formats */
|
||||||
|
unsigned int min_rate; /* min rate (in Hz) */
|
||||||
|
unsigned int max_rate; /* max rate (in Hz) */
|
||||||
|
unsigned int min_channels; /* min channels (probably always 1) */
|
||||||
|
unsigned int max_channels; /* max channels */
|
||||||
|
unsigned int buffer_size; /* record buffer size */
|
||||||
|
unsigned int min_fragment_size; /* min fragment size in bytes */
|
||||||
|
unsigned int max_fragment_size; /* max fragment size in bytes */
|
||||||
|
unsigned int fragment_align; /* align fragment value */
|
||||||
|
unsigned char reserved[64]; /* reserved for future... */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>SND_PCM_PINFO_BATCH</B><DD><P>Driver implements buffering for this device. This means that
|
||||||
|
the chip used for data processing has its own memory and output should be
|
||||||
|
more delayed than if a traditional codec chip is used.</P>
|
||||||
|
<DT><B>SND_PCM_PINFO_8BITONLY</B><DD><P>If this bit is set, the device uses 8-bit format for 16-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 16-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do conversion from
|
||||||
|
16-bit samples to 8-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.</P>
|
||||||
|
<DT><B>SND_PCM_PINFO_16BITONLY</B><DD><P>If this bit is set, the device uses a 16-bit format for 8-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 8-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do the conversion from
|
||||||
|
8-bit samples to 16-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format ) </H3>
|
||||||
|
|
||||||
|
<P>Sets up format, rate (in Hz) and number of channels for playback, in the
|
||||||
|
desired direction. Function returns zero if successful, otherwise it
|
||||||
|
returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_format {
|
||||||
|
unsigned int format; /* SND_PCM_SFMT_XXXX */
|
||||||
|
unsigned int rate; /* rate in Hz */
|
||||||
|
unsigned int channels; /* channels (voices) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_record_format( void *handle, snd_pcm_format_t *format ) </H3>
|
||||||
|
|
||||||
|
<P>Sets up format, rate (in Hz) and number of channels for used for recording
|
||||||
|
in the specified direction. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_format {
|
||||||
|
unsigned int format; /* SND_PCM_SFMT_XXXX */
|
||||||
|
unsigned int rate; /* rate in Hz */
|
||||||
|
unsigned int channels; /* channels (voices) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params ) </H3>
|
||||||
|
|
||||||
|
<P>Sets various parameters for playback direction. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_playback_params {
|
||||||
|
int fragment_size;
|
||||||
|
int fragments_max;
|
||||||
|
int fragments_room;
|
||||||
|
unsigned char reserved[16]; /* must be filled with zero */
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>fragment_size</B><DD><P>Requested size of fragment. This value should be aligned for current
|
||||||
|
format (for example to 4 if stereo 16-bit samples are used) or with the
|
||||||
|
<I>fragment_align</I> variable from <I>snd_pcm_playback_info_t</I>
|
||||||
|
structure. Its range can be from <I>min_fragment_size</I> to
|
||||||
|
<I>max_fragment_size</I>.</P>
|
||||||
|
<DT><B>fragments_max</B><DD><P>Maximum number of fragments in queue for wakeup. This number doesn't
|
||||||
|
counts partly used fragment. If current count of filled playback fragments
|
||||||
|
is greater than this value driver block application or return immediately
|
||||||
|
back if nonblock mode is active.</P>
|
||||||
|
<DT><B>fragments_room</B><DD><P>Minumum number of fragments writeable for wakeup. This value should be
|
||||||
|
in most cases 1 which means return back to application if at least
|
||||||
|
one fragment is free for playback. This value includes partly used fragments,
|
||||||
|
too.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_record_params( void *handle, snd_pcm_record_params_t *params ) </H3>
|
||||||
|
|
||||||
|
<P>Function sets various parameters for the recording direction. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_record_params {
|
||||||
|
int fragment_size;
|
||||||
|
int fragments_min;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>fragment_size</B><DD><P>Requested size of fragment. This value should be aligned for current
|
||||||
|
format (for example to 4 if stereo 16-bit samples are used) or set to the
|
||||||
|
<I>fragment_align</I> variable from <I>snd_pcm_playback_info_t</I>
|
||||||
|
structure. Its range can be from <I>min_fragment_size</I> to
|
||||||
|
<I>max_fragment_size</I>.</P>
|
||||||
|
<DT><B>fragments_min</B><DD><P>Minimum filled fragments for wakeup. Driver blocks the application (if
|
||||||
|
block mode is selected) until it isn't filled with number of fragments
|
||||||
|
specified with this value.</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_playback_status( void *handle, snd_pcm_playback_status_t *status ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *status structure. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_playback_status {
|
||||||
|
unsigned int rate;
|
||||||
|
int fragments;
|
||||||
|
int fragment_size;
|
||||||
|
int count;
|
||||||
|
int queue;
|
||||||
|
int underrun;
|
||||||
|
struct timeval time;
|
||||||
|
struct timeval stime;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>rate</B><DD><P>Real playback rate. This value reflects hardware limitations.</P>
|
||||||
|
<DT><B>fragments</B><DD><P>Currently allocated fragments by the driver for playback direction.</P>
|
||||||
|
<DT><B>fragment_size</B><DD><P>Current fragment size used by driver for the playback direction.</P>
|
||||||
|
<DT><B>count</B><DD><P>Count of bytes writeable without blocking.</P>
|
||||||
|
<DT><B>queue</B><DD><P>Count of bytes in queue. Note: <I>(fragments * fragment_size) - queue</I>
|
||||||
|
should not be equal to <I>count</I>.</P>
|
||||||
|
<DT><B>underrun</B><DD><P>This value tells the application the number of underruns since the ast call
|
||||||
|
of <I>snd_pcm_playback_status</I>.</P>
|
||||||
|
<DT><B>time</B><DD><P>Delay till played of the first sample from next write. This value should
|
||||||
|
be used for time synchronization. Returned value is in the same format as
|
||||||
|
returned from the standard C function <I>gettimeofday( &time, NULL )</I>.
|
||||||
|
This variable contains right value only if playback time mode is enabled
|
||||||
|
(look to <I>snd_pcm_playback_time</I> function).</P>
|
||||||
|
<DT><B>stime</B><DD><P>Time when playback was started.
|
||||||
|
This variable contains right value only if playback time mode is enabled
|
||||||
|
(look to <I>snd_pcm_playback_time</I> function).</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_record_status( void *handle, snd_pcm_record_status_t *status ) </H3>
|
||||||
|
|
||||||
|
<P>Fills the *status structure. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
struct snd_pcm_record_status {
|
||||||
|
unsigned int rate;
|
||||||
|
int fragments;
|
||||||
|
int fragment_size;
|
||||||
|
int count;
|
||||||
|
int free;
|
||||||
|
int overrun;
|
||||||
|
struct timeval time;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><B>rate</B><DD><P>Real record rate. This value reflects hardware limitations.</P>
|
||||||
|
<DT><B>fragments</B><DD><P>Currently allocated fragments by driver for the record direction.</P>
|
||||||
|
<DT><B>fragment_size</B><DD><P>Current fragment size used by driver for the record direction.</P>
|
||||||
|
<DT><B>count</B><DD><P>Count of bytes readable without blocking.</P>
|
||||||
|
<DT><B>free</B><DD><P>Count of bytes in buffer still free. Note: <I>(fragments * fragment_size) - free</I>
|
||||||
|
should not be equal to <I>count</I>.</P>
|
||||||
|
<DT><B>overrun</B><DD><P>This value tells application the count of overruns since the last call
|
||||||
|
to <I>snd_pcm_record_status</I>.</P>
|
||||||
|
<DT><B>time</B><DD><P>Lag since the next sample read was recorded. This value should be used for time
|
||||||
|
synchronization. Returned value is in the same format as returned by the
|
||||||
|
from standard C function <I>gettimeofday( &time, NULL )</I>. This
|
||||||
|
variable contains right value only if record time mode is enabled (look to
|
||||||
|
<I>snd_pcm_record_time</I> function).</P>
|
||||||
|
<DT><B>stime</B><DD><P>Time when record was started. This variable contains right value only if
|
||||||
|
record time mode is enabled (look to <I>snd_pcm_record_time</I> function).</P>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_drain_playback( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>This function drain playback buffers immediately. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code. </P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_flush_playback( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>This function flushes the playback buffers. It blocks the program while the
|
||||||
|
all the waiting samples in kernel playback buffers are processed. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_flush_record( void *handle ) </H3>
|
||||||
|
|
||||||
|
<P>This function flushes (destroyes) record buffers. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code. </P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_playback_time( void *handle, int enable ) </H3>
|
||||||
|
|
||||||
|
<P>This function enables or disables time mode for playback direction. Time mode
|
||||||
|
allows to application better time synchronization. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>int snd_pcm_record_time( void *handle, int enable ) </H3>
|
||||||
|
|
||||||
|
<P>This function enables or disables time mode for record direction. Time mode
|
||||||
|
allows to application better time synchronization. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.</P>
|
||||||
|
|
||||||
|
<H3>ssize_t snd_pcm_write( void *handle, const void *buffer, size_t size ) </H3>
|
||||||
|
|
||||||
|
<P>Writes samples to the device which must be in the proper format
|
||||||
|
specified by the <I>snd_pcm_playback_format</I> function. Function
|
||||||
|
returns zero or positive value if playback was successful (value represents
|
||||||
|
count of bytes which was successfuly written to device) or an
|
||||||
|
error value if error occured. Function should suspend process if
|
||||||
|
block mode is active.</P>
|
||||||
|
|
||||||
|
<H3>ssize_t snd_pcm_read( void *handle, void *buffer, size_t size ) </H3>
|
||||||
|
|
||||||
|
<P>Function reads samples from driver. Samples are in format specified
|
||||||
|
by <I>snd_pcm_record_format</I> function. Function returns zero
|
||||||
|
or positive value if record was success (value represents count of bytes
|
||||||
|
which was successfuly read from device) or negative error value if
|
||||||
|
error occured. Function should suspend process if block mode is active.</P>
|
||||||
|
|
||||||
|
|
||||||
|
<H2><A NAME="ss5.2">5.2 Examples</A></H2>
|
||||||
|
|
||||||
|
<P>The following example shows how to play the first 512kB from the
|
||||||
|
/tmp/test.au file with soundcard #0 and PCM device #0:</P>
|
||||||
|
<P>
|
||||||
|
<BLOCKQUOTE><CODE>
|
||||||
|
<HR>
|
||||||
|
<PRE>
|
||||||
|
int card = 0, device = 0, err, fd, count, size, idx;
|
||||||
|
void *handle;
|
||||||
|
snd_pcm_format_t format;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
buffer = (char *)malloc( 512 * 1024 );
|
||||||
|
if ( !buffer ) return;
|
||||||
|
if ( (err = snd_pcm_open( &handle, card, device, SND_PCM_OPEN_PLAYBACK )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
format.format = SND_PCM_SFMT_MU_LAW;
|
||||||
|
format.rate = 8000;
|
||||||
|
format.voices = 1;
|
||||||
|
if ( (err = snd_pcm_playback_format( handle, &format )) < 0 ) {
|
||||||
|
fprintf( stderr, "format setup failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fd = open( "/tmp/test.au" );
|
||||||
|
if ( fd < 0 ) {
|
||||||
|
perror( "open file" );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idx = 0;
|
||||||
|
count = read( fd, buffer, 512 * 1024 );
|
||||||
|
if ( count <= 0 ) {
|
||||||
|
perror( "read from file" );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
close( fd );
|
||||||
|
if ( !memcmp( buffer, ".snd", 4 ) ) {
|
||||||
|
idx = (buffer[4]<<24)|(buffer[5]<<16)|(buffer[6]<<8)|(buffer[7]);
|
||||||
|
if ( idx > 128 ) idx = 128;
|
||||||
|
if ( idx > count ) idx = count;
|
||||||
|
}
|
||||||
|
size = snd_pcm_write( handle, &buffer[ idx ], count - idx );
|
||||||
|
printf( "Bytes written %i from %i...\n", size, count - idx );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
free( buffer );
|
||||||
|
</PRE>
|
||||||
|
<HR>
|
||||||
|
</CODE></BLOCKQUOTE>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
<A HREF="soundapi-4.html">Previous</A>
|
||||||
|
Next
|
||||||
|
<A HREF="soundapi.html#toc5">Table of Contents</A>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
52
doc/soundapi.html
Normal file
52
doc/soundapi.html
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Advanced Linux Sound Architecture - Library API</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
Previous
|
||||||
|
<A HREF="soundapi-1.html">Next</A>
|
||||||
|
Table of Contents
|
||||||
|
<HR>
|
||||||
|
<H1>Advanced Linux Sound Architecture - Library API</H1>
|
||||||
|
|
||||||
|
<H2>Jaroslav Kysela <CODE><perex@jcu.cz></CODE> with assistance from Alan Robinson</H2>v0.0.3, 25 March 1998
|
||||||
|
<P><HR><EM>This document describes, in full detail, the Advanced Linux Sound Architecture library API.</EM><HR></P>
|
||||||
|
<P>
|
||||||
|
<H2><A NAME="toc1">1.</A> <A HREF="soundapi-1.html">Introduction</A></H2>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2><A NAME="toc2">2.</A> <A HREF="soundapi-2.html">Error Codes</A></H2>
|
||||||
|
<UL>
|
||||||
|
<LI><A HREF="soundapi-2.html#ss2.1">2.1 Error Codes in Detail</A>
|
||||||
|
<LI><A HREF="soundapi-2.html#ss2.2">2.2 Functions</A>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2><A NAME="toc3">3.</A> <A HREF="soundapi-3.html">Control Interface</A></H2>
|
||||||
|
<UL>
|
||||||
|
<LI><A HREF="soundapi-3.html#ss3.1">3.1 Low-Level Layer</A>
|
||||||
|
<LI><A HREF="soundapi-3.html#ss3.2">3.2 Examples</A>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2><A NAME="toc4">4.</A> <A HREF="soundapi-4.html">Mixer Interface</A></H2>
|
||||||
|
<UL>
|
||||||
|
<LI><A HREF="soundapi-4.html#ss4.1">4.1 Low-Level Layer</A>
|
||||||
|
<LI><A HREF="soundapi-4.html#ss4.2">4.2 Examples</A>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2><A NAME="toc5">5.</A> <A HREF="soundapi-5.html">Digital Audio (PCM) Interface</A></H2>
|
||||||
|
<UL>
|
||||||
|
<LI><A HREF="soundapi-5.html#ss5.1">5.1 Low-Level Layer</A>
|
||||||
|
<LI><A HREF="soundapi-5.html#ss5.2">5.2 Examples</A>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
Previous
|
||||||
|
<A HREF="soundapi-1.html">Next</A>
|
||||||
|
Table of Contents
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
956
doc/soundapi.sgml
Normal file
956
doc/soundapi.sgml
Normal file
|
|
@ -0,0 +1,956 @@
|
||||||
|
<!doctype linuxdoc system>
|
||||||
|
|
||||||
|
<!-- Advanced Linux Sound Architecture - Library API -->
|
||||||
|
|
||||||
|
<article>
|
||||||
|
|
||||||
|
<!-- Title information -->
|
||||||
|
|
||||||
|
<title>Advanced Linux Sound Architecture - Library API
|
||||||
|
<author>Jaroslav Kysela <tt><perex@jcu.cz></tt> with assistance from Alan Robinson
|
||||||
|
<date>v0.0.3, 25 March 1998
|
||||||
|
<abstract>
|
||||||
|
This document describes, in full detail, the Advanced Linux Sound
|
||||||
|
Architecture library API.
|
||||||
|
</abstract>
|
||||||
|
|
||||||
|
<!-- Table of contents -->
|
||||||
|
<toc>
|
||||||
|
|
||||||
|
<!-- Begin the document -->
|
||||||
|
|
||||||
|
<sect>Introduction
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Advanced Linux Sound Architecture comes with a kernel API & library API.
|
||||||
|
This document describes the library API and how it interfaces with the kernel
|
||||||
|
API. The kernal API will probably never be documented in standalone form.
|
||||||
|
<P>
|
||||||
|
Application programmers should use the library API rather than kernel API.
|
||||||
|
The Library offers 100% of the functionally of the kernel API, but add next
|
||||||
|
major improvements in usability, making the application code simpler and
|
||||||
|
better looking. In addition, some of the some fixes/compatibility code in,
|
||||||
|
may be placed in the library code instead of the kernel driver.
|
||||||
|
<p>
|
||||||
|
For a complete list of all variables and functions in the API you should look
|
||||||
|
at the following header files:
|
||||||
|
<enum>
|
||||||
|
<item>/usr/include/sys/soundlib.h
|
||||||
|
<item>/usr/include/linux/sound.h
|
||||||
|
<item>/usr/include/linux/sounddetect.h
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<sect>Error Codes
|
||||||
|
|
||||||
|
<p>
|
||||||
|
All functions return int (or some sort of signed value). If this value
|
||||||
|
is negative it represents an error code. Codes up to SND_ERROR_BEGIN (500000)
|
||||||
|
represents standard system errors. Codes equal or greather than this value
|
||||||
|
represents sound library API errors. All error codes begin with the prefix
|
||||||
|
<it>SND_ERROR_</it>.
|
||||||
|
|
||||||
|
<sect1>Error Codes in Detail
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<descrip>
|
||||||
|
<tag>SND_ERROR_UNCOMPATIBLE_VERSION (500000)</tag>
|
||||||
|
This error is caused if the driver uses an incompatible kernel API for this
|
||||||
|
interface and hence the library doesn't know how this API can be used.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect1>Functions
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<sect2>const char *snd_strerror( int errnum )
|
||||||
|
<p>
|
||||||
|
This functions converts error code to a string. Its functionality is the same
|
||||||
|
as the <it>strerror</it> function from the standard C library, but this
|
||||||
|
function returns correct strings for sound error codes, too.
|
||||||
|
|
||||||
|
<sect>Control Interface
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The control interfaces gives application various information about the
|
||||||
|
currently installed sound driver in the system. The interface should be used
|
||||||
|
to detect if another sound interface is present for selected soundcard or,
|
||||||
|
for example, to create a list of devices (MIXER, PCM etc) from which
|
||||||
|
the user can select.
|
||||||
|
|
||||||
|
<sect1>Low-Level Layer
|
||||||
|
|
||||||
|
<sect2>int snd_cards( void )
|
||||||
|
<p>
|
||||||
|
Returns the number of soundcards present in the system, if any. Otherwise
|
||||||
|
it returns a negative value, which maps to an error code. This function
|
||||||
|
will return 0 if no soundcards are detected.
|
||||||
|
|
||||||
|
<sect2>unsigned int snd_cards_mask( void )
|
||||||
|
<p>
|
||||||
|
Returns the bitmap of soundcards present in the system, if any. Otherwise
|
||||||
|
it returns a negative value, which maps to an error code. This function
|
||||||
|
will return 0 if no soundcards are detected. First soundcard is represented
|
||||||
|
with bit 0.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_open( void **handle, int card )
|
||||||
|
<p>
|
||||||
|
Creates a new handle and opens communication with the kernel sound
|
||||||
|
control interface for soundcard number <it>card</it> (0-N). The function
|
||||||
|
also checks if protocol is compatible, so as to prevent the use of old
|
||||||
|
programs with a new kernel API. Function returns zero if successful,
|
||||||
|
otherwise an error code is returned.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_close( void *handle )
|
||||||
|
<p>
|
||||||
|
Function frees all resources allocated with control handle and
|
||||||
|
closes the kernel sound control interface. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_file_descriptor( void *handle )
|
||||||
|
<p>
|
||||||
|
Function returns file descriptor for the kernel sound control interface.
|
||||||
|
This function should be used in very special cases. Function returns
|
||||||
|
a negative error code if some error was encountered.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info )
|
||||||
|
<p>
|
||||||
|
Fills the info structure with data about the sound hardware referenced
|
||||||
|
by handle. Function returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_CTL_GCAPS_MIDI 0x0000001 /* driver has MIDI interface */
|
||||||
|
|
||||||
|
#define SND_CTL_LCAPS_SYNTH 0x0000001 /* soundcard has synthesizer */
|
||||||
|
#define SND_CTL_LCAPS_RAWFM 0x0000002 /* soundcard has RAW FM/OPL3 */
|
||||||
|
|
||||||
|
struct snd_ctl_hw_info {
|
||||||
|
unsigned int type; /* type of card - see SND_CARD_TYPE_XXXX */
|
||||||
|
unsigned int gcaps; /* see SND_CTL_GCAPS_XXXX */
|
||||||
|
unsigned int lcaps; /* see SND_CTL_LCAPS_XXXX */
|
||||||
|
unsigned int pcmdevs; /* count of PCM devices (0 to N) */
|
||||||
|
unsigned int mixerdevs; /* count of MIXER devices (0 to N) */
|
||||||
|
unsigned int mididevs; /* count of raw MIDI devices (0 to N) */
|
||||||
|
char id[8]; /* ID of card (user selectable) */
|
||||||
|
char name[80]; /* name/info text about soundcard */
|
||||||
|
unsigned char reserved[128]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about the PCM device. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code. Details about
|
||||||
|
the snd_pcm_info_t structure are in the <bf>Digital Audio (PCM) Interface</bf>
|
||||||
|
section. The argument <it>dev</it> selects the device number for the
|
||||||
|
soundcard referenced by *handle. Its range is 0 to N where N is
|
||||||
|
<it>struct snd_ctl_hw_info -> pcmdevs - 1</it>. This function will work if
|
||||||
|
the selected PCM device is busy, too. It should be used to collect
|
||||||
|
information about PCM devices without exclusive lock.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about the PCM device and playback direction.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
Details about the snd_pcm_playback_info_t structure are in the
|
||||||
|
<bf>Digital Audio (PCM) Interface</bf> section. The argument <it>dev</it>
|
||||||
|
selects the device number for the soundcard referenced by *handle. Its
|
||||||
|
range is 0 to N where N is <it>struct snd_ctl_hw_info -> pcmdevs - 1</it>.
|
||||||
|
This function will work if the selected PCM device is busy, too. It should
|
||||||
|
be used to collect information about PCM devices without exclusive lock.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about the PCM device and record direction.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
Details about the snd_pcm_record_info_t structure are in the
|
||||||
|
<bf>Digital Audio (PCM) Interface</bf> section. The argument <it>dev</it>
|
||||||
|
selects the device number for the soundcard referenced by *handle. Its
|
||||||
|
range is 0 to N where N is <it>struct snd_ctl_hw_info -> pcmdevs - 1</it>.
|
||||||
|
This function will work if the selected PCM device is busy, too. It should
|
||||||
|
be used to collect information about PCM devices without exclusive lock.
|
||||||
|
|
||||||
|
<sect2>int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about the mixer device. Returns zero
|
||||||
|
if successful, otherwise it returns an error code. Details about the
|
||||||
|
snd_mixer_info_t structure are in the <bf>Mixer Interface</bf> section.
|
||||||
|
The argument <it>dev</it> specifies the device number for the appropriate
|
||||||
|
soundcard. Its range is 0 to N where N found from
|
||||||
|
<it>struct snd_ctl_hw_info -> mixerdevs - 1</it>.
|
||||||
|
It should be used to collect information about mixer devices.
|
||||||
|
|
||||||
|
<sect1>Examples
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The following example shows how all PCM devices can be detected for the first
|
||||||
|
soundcard (#0) in the system.
|
||||||
|
|
||||||
|
<tscreen><code>
|
||||||
|
int card = 0, err;
|
||||||
|
void *handle;
|
||||||
|
stuct snd_ctl_hw_info info;
|
||||||
|
|
||||||
|
if ( (err = snd_ctl_open( &ero;handle, card )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( (err = snd_ctl_hw_info( handle, &ero;info )) < 0 ) {
|
||||||
|
fprintf( stderr, "hw info failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( "Installed PCM devices for card #i: %i\n", card + 1, info.pcmdevs );
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
</code></tscreen>
|
||||||
|
|
||||||
|
<sect>Mixer Interface
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Mixer Interface allows applications to change the volume level of
|
||||||
|
a soundcard's input/output channels in both the linear range (0-100)
|
||||||
|
and in decibels. It also supports features like hardware mute, input
|
||||||
|
sound source, etc.
|
||||||
|
|
||||||
|
<sect1>Low-Level Layer
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Mixer devices aren't opened exclusively. This allows applications to
|
||||||
|
open a device multiple times with one or more processes.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_open( void **handle, int card, int device )
|
||||||
|
<p>
|
||||||
|
Creates new handle and opens a connection to the kernel sound
|
||||||
|
mixer interface for soundcard number <it>card</it> (0-N) and mixer
|
||||||
|
device number <it>device</it>. Also checks if protocol is
|
||||||
|
compatible to prevent use of old programs with new kernel API. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_close( void *handle )
|
||||||
|
<p>
|
||||||
|
Frees all resources allocated to the mixer handle and
|
||||||
|
closes its connection to the kernel sound mixer interface. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_file_descriptor( void *handle )
|
||||||
|
<p>
|
||||||
|
Returns the file descriptor for the connection to the kernel sound
|
||||||
|
mixer interface. This function should be used only in very
|
||||||
|
special cases. Function returns a negative error code if an
|
||||||
|
error was encountered.
|
||||||
|
<p>
|
||||||
|
The file descriptor should be used for the <it>select</it> synchronous
|
||||||
|
multiplexer function for deterimeing read direction. Applications should
|
||||||
|
call <it>snd_mixer_read</it> function if some data is waiting to be read.
|
||||||
|
It is recomended that you do this, since it leaves place for this function
|
||||||
|
to handle some new kernel API specifications.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_channels( void *handle )
|
||||||
|
<p>
|
||||||
|
Returns the count of mixer channels for appropriate mixer device, otherwise
|
||||||
|
the return value is negative, and signifies an error code. Never returns
|
||||||
|
zero.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_info( void *handle, snd_mixer_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with information about the mixer associated with
|
||||||
|
*handle. Returns zero if successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_MIXER_INFO_CAP_EXCL_RECORD 0x00000001
|
||||||
|
|
||||||
|
struct snd_mixer_info {
|
||||||
|
unsigned int type; /* type of soundcard - SND_CARD_TYPE_XXXX */
|
||||||
|
unsigned int channels; /* count of mixer devices */
|
||||||
|
unsigned int caps; /* some flags about this device (SND_MIXER_INFO_CAP_XXXX) */
|
||||||
|
unsigned char id[32]; /* ID of this mixer */
|
||||||
|
unsigned char name[80]; /* name of this device */
|
||||||
|
char reserved[ 32 ]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_channel( void *handle, const char *channel_id )
|
||||||
|
<p>
|
||||||
|
Returns the channel number (index) associated with channel_id (channel name),
|
||||||
|
or returns an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_MIXER_ID_MASTER "Master"
|
||||||
|
#define SND_MIXER_ID_BASS "Bass"
|
||||||
|
#define SND_MIXER_ID_TREBLE "Treble"
|
||||||
|
#define SND_MIXER_ID_SYNTHESIZER "Synth"
|
||||||
|
#define SND_MIXER_ID_SYNTHESIZER1 "Synth 1"
|
||||||
|
#define SND_MIXER_ID_FM "FM"
|
||||||
|
#define SND_MIXER_ID_EFFECT "Effect"
|
||||||
|
#define SND_MIXER_ID_PCM "PCM"
|
||||||
|
#define SND_MIXER_ID_PCM1 "PCM 1"
|
||||||
|
#define SND_MIXER_ID_LINE "Line-In"
|
||||||
|
#define SND_MIXER_ID_MIC "MIC"
|
||||||
|
#define SND_MIXER_ID_CD "CD"
|
||||||
|
#define SND_MIXER_ID_GAIN "Record-Gain"
|
||||||
|
#define SND_MIXER_ID_IGAIN "In-Gain"
|
||||||
|
#define SND_MIXER_ID_OGAIN "Out-Gain"
|
||||||
|
#define SND_MIXER_ID_LOOPBACK "Loopback"
|
||||||
|
#define SND_MIXER_ID_SPEAKER "PC Speaker"
|
||||||
|
#define SND_MIXER_ID_AUXA "Aux A"
|
||||||
|
#define SND_MIXER_ID_AUXB "Aux B"
|
||||||
|
#define SND_MIXER_ID_AUXC "Aux C"
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_exact_mode( void *handle, int enable )
|
||||||
|
<p>
|
||||||
|
Turns on or off (by default) exact mode. This mode allows to application
|
||||||
|
set/get volume values in exact range which uses hardware. In non-exact
|
||||||
|
mode is range always from 0 to 100 and conversion to hardware range does
|
||||||
|
driver. Function returns zero if successful, otherwise it returns an error
|
||||||
|
code.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure. The argument <it>channel</it> specifies channel
|
||||||
|
(0 to N) for which is the info requested. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_MIXER_CINFO_CAP_RECORD 0x00000001
|
||||||
|
#define SND_MIXER_CINFO_CAP_STEREO 0x00000002
|
||||||
|
#define SND_MIXER_CINFO_CAP_MUTE 0x00000004
|
||||||
|
#define SND_MIXER_CINFO_CAP_HWMUTE 0x00000008 /* channel supports hardware mute */
|
||||||
|
#define SND_MIXER_CINFO_CAP_DIGITAL 0x00000010 /* channel does digital (not analog) mixing */
|
||||||
|
#define SND_MIXER_CINOF_CAP_INPUT 0x00000020 /* input channel */
|
||||||
|
|
||||||
|
struct snd_mixer_channel_info {
|
||||||
|
unsigned int channel; /* channel # (filled by application) */
|
||||||
|
unsigned int parent; /* parent channel # or SND_MIXER_PARENT */
|
||||||
|
unsigned char name[12]; /* name of this device */
|
||||||
|
unsigned int caps; /* some flags about this device (SND_MIXER_CINFO_XXXX) */
|
||||||
|
int min; /* min. value when exact mode (or always 0) */
|
||||||
|
int max; /* max. value when exact mode (or always 100) */
|
||||||
|
int min_dB; /* minimum decibel value (*100) */
|
||||||
|
int max_dB; /* maximum decibel value (*100) */
|
||||||
|
int step_dB; /* step decibel value (*100) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data )
|
||||||
|
<p>
|
||||||
|
Fills the *data structure. The argument <it>channel</it> specifies
|
||||||
|
the channel (0 to N) for which is data requested. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_MIXER_FLG_RECORD 0x00000001 /* channel record source flag */
|
||||||
|
#define SND_MIXER_FLG_MUTE_LEFT 0x00010000
|
||||||
|
#define SND_MIXER_FLG_MUTE_RIGHT 0x00020000
|
||||||
|
#define SND_MIXER_FLG_MUTE 0x00030000
|
||||||
|
#define SND_MIXER_FLG_DECIBEL 0x40000000
|
||||||
|
#define SND_MIXER_FLG_FORCE 0x80000000
|
||||||
|
|
||||||
|
struct snd_mixer_channel {
|
||||||
|
unsigned int channel; /* channel # (filled by application) */
|
||||||
|
unsigned int flags; /* some flags to read/write (SND_MIXER_FLG_XXXX) */
|
||||||
|
int left; /* min - max when exact mode (or 0 - 100) */
|
||||||
|
int right; /* min - max when exact mode (or 0 - 100) */
|
||||||
|
int left_dB; /* dB * 100 */
|
||||||
|
int right_dB; /* dB * 100 */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<p>
|
||||||
|
<descrip>
|
||||||
|
<tag>SND_MIXER_FLG_RECORD</tag>
|
||||||
|
Record source flag.
|
||||||
|
<tag>SND_MIXER_FLG_DECIBEL</tag>
|
||||||
|
If this bit is set, driver set volume from dB variables <it>left_dB</it>
|
||||||
|
and <it>right_dB</it>.
|
||||||
|
<tag>SND_MIXER_FLG_FORCE</tag>
|
||||||
|
Force set - this bit shouldn't be used from user space. Reserved for
|
||||||
|
kernel.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data )
|
||||||
|
<p>
|
||||||
|
Writes the *data structure to kernel. The <it>channel</it> argument
|
||||||
|
specifies the channel (0 to N) for which is data is to be applied.
|
||||||
|
Function returns zero if successful, otherwise it returns an error code.
|
||||||
|
This functions is the opposite of <it>snd_mixer_channel_read</it>.
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_special_read( void *handle, snd_mixer_special_t *special )
|
||||||
|
<p>
|
||||||
|
Not documented...
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_special_write( void *handle, snd_mixer_special_t *special )
|
||||||
|
<p>
|
||||||
|
Not documented...
|
||||||
|
|
||||||
|
<sect2>int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks )
|
||||||
|
<p>
|
||||||
|
This function reads and parses data from driver. Parsed actions are returned
|
||||||
|
back to the application using the <it>callbacks</it> structure. Applications
|
||||||
|
should not parse data from the driver in standard cases. This function
|
||||||
|
returns immediately after all data is read from driver. Does not
|
||||||
|
block process.
|
||||||
|
<code>
|
||||||
|
typedef struct snd_mixer_callbacks {
|
||||||
|
void *private_data; /* should be used by application */
|
||||||
|
void (*channel_was_changed)( void *private_data, int channel );
|
||||||
|
void *reserved[15]; /* reserved for future use - must be NULL!!! */
|
||||||
|
} snd_mixer_callbacks_t;
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect1>Examples
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The following example shows installed mixer channels for soundcard #0 and
|
||||||
|
mixer device #0 in the system, and also sets the master volume (if present)
|
||||||
|
to 50.
|
||||||
|
|
||||||
|
<tscreen><code>
|
||||||
|
int card = 0, device = 0, err;
|
||||||
|
void *handle;
|
||||||
|
snd_mixer_info_t info;
|
||||||
|
snd_mixer_channel_t channel;
|
||||||
|
|
||||||
|
if ( (err = snd_mixer_open( &ero;handle, card, device )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( (err = snd_mixer_info( handle, &ero;info )) < 0 ) {
|
||||||
|
fprintf( stderr, "info failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( "Installed MIXER channels for card #i and device %i: %i\n",
|
||||||
|
card + 1, device, info.channels );
|
||||||
|
master = snd_mixer_channel( handle, SND_MIXER_ID_MASTER );
|
||||||
|
if ( master >= 0 ) {
|
||||||
|
if ( (err = snd_mixer_read( handle, master, &ero;channel )) < 0 ) {
|
||||||
|
fprintf( stderr, "master read failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channel -> left = channel -> right = 50;
|
||||||
|
if ( (err = snd_mixer_write( handle, master, &ero;channel )) < 0 ) {
|
||||||
|
fprintf( stderr, "master write failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
</code></tscreen>
|
||||||
|
|
||||||
|
<sect>Digital Audio (PCM) Interface
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Digital audio is the most commonly used method of representing sound inside
|
||||||
|
a computer. In this method sound is stored as a sequence of samples taken
|
||||||
|
from the audio signal using constant time intervals. A sample represents
|
||||||
|
volume of the signal at the moment when it was measured. In uncompressed
|
||||||
|
digital audio each sample require one or more bytes of storage. The number of
|
||||||
|
bytes required depends on number of channels (mono, stereo) and sample
|
||||||
|
format (8 or 16 bits, mu-Law, etc.). The length of this interval determines
|
||||||
|
the sampling rate. Commonly used sampling rates are between 8 kHz (telephone
|
||||||
|
quality) and 48 kHz (DAT tapes).
|
||||||
|
<p>
|
||||||
|
The physical devices used in digital audio are called the ADC (Analog to
|
||||||
|
Digital Converter) and DAC (Digital to Analog Converter). A device containing
|
||||||
|
both ADC and DAC is commonly known as a codec. The codec device used in
|
||||||
|
a Sound Blaster cards is called a DSP which is somewhat misleading since DSP
|
||||||
|
also stands for Digital Signal Processor (the SB DSP chip is very limited
|
||||||
|
when compared to "true" DSP chips).
|
||||||
|
<p>
|
||||||
|
Sampling parameters affect the quality of sound which can be reproduced from
|
||||||
|
the recorded signal. The most fundamental parameter is sampling rate which
|
||||||
|
limits the highest frequency than can be stored. It is well known (Nyquist's
|
||||||
|
Sampling Theorem) that the highest frequency that can be stored in a sampled
|
||||||
|
signal is at most 1/2 of the sampling frequency. For example, a 8 kHz sampling
|
||||||
|
rate permits the recording of a signal in which the highest frequency is less
|
||||||
|
than 4 kHz. Higher frequency signals must be filtered out before feeding them
|
||||||
|
to DAC.
|
||||||
|
<p>
|
||||||
|
Sample encoding limits the dynamic range of recorded signal (difference between
|
||||||
|
the faintest and the loudest signal that can be recorded). In theory the
|
||||||
|
maximum dynamic range of signal is number_of_bits * 6 dB . This means that
|
||||||
|
8 bits sampling resolution gives dynamic range of 48 dB and 16 bit resolution
|
||||||
|
gives 96 dB.
|
||||||
|
<p>
|
||||||
|
Quality has price. The number of bytes required to store an audio sequence
|
||||||
|
depends on sampling rate, number of channels and sampling resolution. For
|
||||||
|
example just 8000 bytes of memory is required to store one second of sound
|
||||||
|
using 8 kHz/8 bits/mono but 48 kHz/16bit/stereo takes 192 kilobytes. A 64 kbps
|
||||||
|
ISDN channel is required to transfer a 8kHz/8bit/mono audio stream in real
|
||||||
|
time, and about 1.5 Mbps is required for DAT quality (48kHz/16bit/stereo).
|
||||||
|
On the other hand it is possible to store just 5.46 seconds of sound in
|
||||||
|
a megabyte of memory when using 48kHz/16bit/stereo sampling. With
|
||||||
|
8kHz/8bits/mono it is possible to store 131 seconds of sound using the same
|
||||||
|
amount of memory. It is possible to reduce memory and communication costs by
|
||||||
|
compressing the recorded signal but this is out of the scope of this document.
|
||||||
|
|
||||||
|
<sect1>Low-Level Layer
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Audio devices are opened exclusively for a selected direction. This doesn't
|
||||||
|
allow open from more than one processes for the same audio device in the
|
||||||
|
same direction, but does allow one open call to each playback direction and
|
||||||
|
second open call to record direction independently. Audio devices return
|
||||||
|
EBUSY error to applications when other applications have already opened the
|
||||||
|
requested direction.
|
||||||
|
<p>
|
||||||
|
Low-Level layer supports these formats:
|
||||||
|
<tscreen><code>
|
||||||
|
#define SND_PCM_SFMT_MU_LAW 0
|
||||||
|
#define SND_PCM_SFMT_A_LAW 1
|
||||||
|
#define SND_PCM_SFMT_IMA_ADPCM 2
|
||||||
|
#define SND_PCM_SFMT_U8 3
|
||||||
|
#define SND_PCM_SFMT_S16_LE 4
|
||||||
|
#define SND_PCM_SFMT_S16_BE 5
|
||||||
|
#define SND_PCM_SFMT_S8 6
|
||||||
|
#define SND_PCM_SFMT_U16_LE 7
|
||||||
|
#define SND_PCM_SFMT_U16_BE 8
|
||||||
|
#define SND_PCM_SFMT_MPEG 9
|
||||||
|
#define SND_PCM_SFMT_GSM 10
|
||||||
|
|
||||||
|
#define SND_PCM_FMT_MU_LAW (1 << SND_PCM_SFMT_MU_LAW)
|
||||||
|
#define SND_PCM_FMT_A_LAW (1 << SND_PCM_SFMT_A_LAW)
|
||||||
|
#define SND_PCM_FMT_IMA_ADPCM (1 << SND_PCM_SFMT_IMA_ADPCM)
|
||||||
|
#define SND_PCM_FMT_U8 (1 << SND_PCM_SFMT_U8)
|
||||||
|
#define SND_PCM_FMT_S16_LE (1 << SND_PCM_SFMT_S16_LE)
|
||||||
|
#define SND_PCM_FMT_S16_BE (1 << SND_PCM_SFMT_S16_BE)
|
||||||
|
#define SND_PCM_FMT_S8 (1 << SND_PCM_SFMT_S8)
|
||||||
|
#define SND_PCM_FMT_U16_LE (1 << SND_PCM_SFMT_U16_LE)
|
||||||
|
#define SND_PCM_FMT_U16_BE (1 << SND_PCM_SFMT_U16_BE)
|
||||||
|
#define SND_PCM_FMT_MPEG (1 << SND_PCM_SFMT_MPEG)
|
||||||
|
#define SND_PCM_FMT_GSM (1 << SND_PCM_SFMT_GSM)
|
||||||
|
</code></tscreen>
|
||||||
|
Constants with prefix <bf>SND_PCM_FMT_</bf> are used in info structures
|
||||||
|
and constants with prefix <bf>SND_PCM_SFMT_</bf> are used in format structures.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_open( void **handle, int card, int device, int mode )
|
||||||
|
<p>
|
||||||
|
Creates a new handle and opens a connection to kernel sound
|
||||||
|
audio interface for soundcard number <it>card</it> (0-N) and audio
|
||||||
|
device number <it>device</it>. Function also checks if protocol is
|
||||||
|
compatible to prevent use of old programs with a new kernel API. Function
|
||||||
|
returns zero if successful,ful otherwise it returns an error code.
|
||||||
|
Error code -EBUSY is returned when some process ownes the selected direction.
|
||||||
|
<p>
|
||||||
|
Default format after opening is mono <it>mu-Law</it> at 8000Hz. This device
|
||||||
|
can be used directly for playback of standard .au (Sparc) files.
|
||||||
|
<p>
|
||||||
|
The following modes should be used for the <it>mode</it> argument:
|
||||||
|
<code>
|
||||||
|
#define SND_PCM_OPEN_PLAYBACK (O_WRONLY)
|
||||||
|
#define SND_PCM_OPEN_RECORD (O_RDONLY)
|
||||||
|
#define SND_PCM_OPEN_DUPLEX (O_RDWR)
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_close( void *handle )
|
||||||
|
<p>
|
||||||
|
Frees all resources allocated with audio handle and
|
||||||
|
closes the connection to the kernel sound audio interface. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_file_descriptor( void *handle )
|
||||||
|
<p>
|
||||||
|
Returns the file descriptor of the connection to the kernel sound
|
||||||
|
audio interface. Function returns an error code if an
|
||||||
|
error was encountered.
|
||||||
|
<p>
|
||||||
|
The file descriptor should be used for the <it>select</it> synchronous
|
||||||
|
multiplexer function for setting the read direction. Application should
|
||||||
|
call <it>snd_pcm_read</it> or <it>snd_pcm_write</it> functions if some
|
||||||
|
data is waiting for reading or a write can be performed. Calling this
|
||||||
|
function is highly recomended, as it leaves a place for the API to things
|
||||||
|
like data conversions, if needed.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_block_mode( void *handle, int enable )
|
||||||
|
<p>
|
||||||
|
Sets up block (default) or nonblock mode for a handle. Block mode suspends
|
||||||
|
execution of a program when <it>snd_pcm_read</it> or <it>snd_pcm_write</it>
|
||||||
|
is called for the time which is needed for the actual playback or record
|
||||||
|
over of the entire buffer. In nonblock mode, programs aren't suspended and
|
||||||
|
the above functions returns immediately with the count of bytes which were
|
||||||
|
read or written by the driver. When used in this way, don't try to use the
|
||||||
|
entire buffer after the call, but instead process the number of bytes
|
||||||
|
returned, and call the function again.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_info( void *handle, snd_pcm_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about the PCM device selected by
|
||||||
|
*handle. Function returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_PCM_INFO_CODEC 0x00000001
|
||||||
|
#define SND_PCM_INFO_DSP SND_PCM_INFO_CODEC
|
||||||
|
#define SND_PCM_INFO_MMAP 0x00000002 /* reserved */
|
||||||
|
#define SND_PCM_INFO_PLAYBACK 0x00000100
|
||||||
|
#define SND_PCM_INFO_RECORD 0x00000200
|
||||||
|
#define SND_PCM_INFO_DUPLEX 0x00000400
|
||||||
|
#define SND_PCM_INFO_DUPLEX_LIMIT 0x00000800 /* rate for playback & record are same */
|
||||||
|
|
||||||
|
struct snd_pcm_info {
|
||||||
|
unsigned int type; /* soundcard type */
|
||||||
|
unsigned int flags; /* see SND_PCM_INFO_XXXX */
|
||||||
|
unsigned char id[32]; /* ID of this PCM device */
|
||||||
|
unsigned char name[80]; /* name of this device */
|
||||||
|
unsigned char reserved[64]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>SND_PCM_INFO_MMAP</tag>
|
||||||
|
This flag is reserved and should be never used. It remains for
|
||||||
|
compatibility with Open Sound System driver.
|
||||||
|
<tag>SND_PCM_INFO_DUPLEX_LIMIT</tag>
|
||||||
|
If this bit is set, rate must be same for playback and record direction.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure with data about PCM playback. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_PCM_PINFO_BATCH 0x00000001
|
||||||
|
#define SND_PCM_PINFO_8BITONLY 0x00000002
|
||||||
|
#define SND_PCM_PINFO_16BITONLY 0x00000004
|
||||||
|
|
||||||
|
struct snd_pcm_playback_info {
|
||||||
|
unsigned int flags; /* see SND_PCM_PINFO_XXXX */
|
||||||
|
unsigned int formats; /* supported formats */
|
||||||
|
unsigned int min_rate; /* min rate (in Hz) */
|
||||||
|
unsigned int max_rate; /* max rate (in Hz) */
|
||||||
|
unsigned int min_channels; /* min channels (probably always 1) */
|
||||||
|
unsigned int max_channels; /* max channels */
|
||||||
|
unsigned int buffer_size; /* playback buffer size */
|
||||||
|
unsigned int min_fragment_size; /* min fragment size in bytes */
|
||||||
|
unsigned int max_fragment_size; /* max fragment size in bytes */
|
||||||
|
unsigned int fragment_align; /* align fragment value */
|
||||||
|
unsigned char reserved[64]; /* reserved for future use */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>SND_PCM_PINFO_BATCH</tag>
|
||||||
|
Driver implements double buffering with this device. This means that
|
||||||
|
the chip used for data processing has its own memory, and output should be
|
||||||
|
more delayed than if a traditional codec chip is used.
|
||||||
|
<tag>SND_PCM_PINFO_8BITONLY</tag>
|
||||||
|
If this bit is set, the driver uses 8-bit format for 16-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 16-bit duplex. If this bit is set
|
||||||
|
application or highter digital audio layer should do the conversion from
|
||||||
|
16-bit samples to 8-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.
|
||||||
|
<tag>SND_PCM_PINFO_16BITONLY</tag>
|
||||||
|
If this bit is set, driver uses 16-bit format for 8-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 8-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do conversion from
|
||||||
|
8-bit samples to 16-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info )
|
||||||
|
<p>
|
||||||
|
Fills the *info structure. Returns zero if successful, otherwise it returns
|
||||||
|
an error code.
|
||||||
|
<code>
|
||||||
|
#define SND_PCM_RINFO_BATCH 0x00000001
|
||||||
|
#define SND_PCM_RINFO_8BITONLY 0x00000002
|
||||||
|
#define SND_PCM_RINFO_16BITONLY 0x00000004
|
||||||
|
|
||||||
|
struct snd_pcm_record_info {
|
||||||
|
unsigned int flags; /* see to SND_PCM_RINFO_XXXX */
|
||||||
|
unsigned int formats; /* supported formats */
|
||||||
|
unsigned int min_rate; /* min rate (in Hz) */
|
||||||
|
unsigned int max_rate; /* max rate (in Hz) */
|
||||||
|
unsigned int min_channels; /* min channels (probably always 1) */
|
||||||
|
unsigned int max_channels; /* max channels */
|
||||||
|
unsigned int buffer_size; /* record buffer size */
|
||||||
|
unsigned int min_fragment_size; /* min fragment size in bytes */
|
||||||
|
unsigned int max_fragment_size; /* max fragment size in bytes */
|
||||||
|
unsigned int fragment_align; /* align fragment value */
|
||||||
|
unsigned char reserved[64]; /* reserved for future... */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>SND_PCM_PINFO_BATCH</tag>
|
||||||
|
Driver implements buffering for this device. This means that
|
||||||
|
the chip used for data processing has its own memory and output should be
|
||||||
|
more delayed than if a traditional codec chip is used.
|
||||||
|
<tag>SND_PCM_PINFO_8BITONLY</tag>
|
||||||
|
If this bit is set, the device uses 8-bit format for 16-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 16-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do conversion from
|
||||||
|
16-bit samples to 8-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.
|
||||||
|
<tag>SND_PCM_PINFO_16BITONLY</tag>
|
||||||
|
If this bit is set, the device uses a 16-bit format for 8-bit samples and
|
||||||
|
does software conversion. This bit is set on broken SoundBlaster 16/AWE
|
||||||
|
soundcards which can't do full 8-bit duplex. If this bit is set the
|
||||||
|
application or highter digital audio layer should do the conversion from
|
||||||
|
8-bit samples to 16-bit samples rather than making the driver to do it in
|
||||||
|
the kernel.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format )
|
||||||
|
<p>
|
||||||
|
Sets up format, rate (in Hz) and number of channels for playback, in the
|
||||||
|
desired direction. Function returns zero if successful, otherwise it
|
||||||
|
returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_format {
|
||||||
|
unsigned int format; /* SND_PCM_SFMT_XXXX */
|
||||||
|
unsigned int rate; /* rate in Hz */
|
||||||
|
unsigned int channels; /* channels (voices) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_record_format( void *handle, snd_pcm_format_t *format )
|
||||||
|
<p>
|
||||||
|
Sets up format, rate (in Hz) and number of channels for used for recording
|
||||||
|
in the specified direction. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_format {
|
||||||
|
unsigned int format; /* SND_PCM_SFMT_XXXX */
|
||||||
|
unsigned int rate; /* rate in Hz */
|
||||||
|
unsigned int channels; /* channels (voices) */
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params )
|
||||||
|
<p>
|
||||||
|
Sets various parameters for playback direction. Function returns zero if
|
||||||
|
successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_playback_params {
|
||||||
|
int fragment_size;
|
||||||
|
int fragments_max;
|
||||||
|
int fragments_room;
|
||||||
|
unsigned char reserved[16]; /* must be filled with zero */
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>fragment_size</tag>
|
||||||
|
Requested size of fragment. This value should be aligned for current
|
||||||
|
format (for example to 4 if stereo 16-bit samples are used) or with the
|
||||||
|
<it>fragment_align</it> variable from <it>snd_pcm_playback_info_t</it>
|
||||||
|
structure. Its range can be from <it>min_fragment_size</it> to
|
||||||
|
<it>max_fragment_size</it>.
|
||||||
|
<tag>fragments_max</tag>
|
||||||
|
Maximum number of fragments in queue for wakeup. This number doesn't
|
||||||
|
counts partly used fragment. If current count of filled playback fragments
|
||||||
|
is greater than this value driver block application or return immediately
|
||||||
|
back if nonblock mode is active.
|
||||||
|
<tag>fragments_room</tag>
|
||||||
|
Minumum number of fragments writeable for wakeup. This value should be
|
||||||
|
in most cases 1 which means return back to application if at least
|
||||||
|
one fragment is free for playback. This value includes partly used fragments,
|
||||||
|
too.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_record_params( void *handle, snd_pcm_record_params_t *params )
|
||||||
|
<p>
|
||||||
|
Function sets various parameters for the recording direction. Function returns
|
||||||
|
zero if successful, otherwise it returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_record_params {
|
||||||
|
int fragment_size;
|
||||||
|
int fragments_min;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>fragment_size</tag>
|
||||||
|
Requested size of fragment. This value should be aligned for current
|
||||||
|
format (for example to 4 if stereo 16-bit samples are used) or set to the
|
||||||
|
<it>fragment_align</it> variable from <it>snd_pcm_playback_info_t</it>
|
||||||
|
structure. Its range can be from <it>min_fragment_size</it> to
|
||||||
|
<it>max_fragment_size</it>.
|
||||||
|
<tag>fragments_min</tag>
|
||||||
|
Minimum filled fragments for wakeup. Driver blocks the application (if
|
||||||
|
block mode is selected) until it isn't filled with number of fragments
|
||||||
|
specified with this value.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_playback_status( void *handle, snd_pcm_playback_status_t *status )
|
||||||
|
<p>
|
||||||
|
Fills the *status structure. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_playback_status {
|
||||||
|
unsigned int rate;
|
||||||
|
int fragments;
|
||||||
|
int fragment_size;
|
||||||
|
int count;
|
||||||
|
int queue;
|
||||||
|
int underrun;
|
||||||
|
struct timeval time;
|
||||||
|
struct timeval stime;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>rate</tag>
|
||||||
|
Real playback rate. This value reflects hardware limitations.
|
||||||
|
<tag>fragments</tag>
|
||||||
|
Currently allocated fragments by the driver for playback direction.
|
||||||
|
<tag>fragment_size</tag>
|
||||||
|
Current fragment size used by driver for the playback direction.
|
||||||
|
<tag>count</tag>
|
||||||
|
Count of bytes writeable without blocking.
|
||||||
|
<tag>queue</tag>
|
||||||
|
Count of bytes in queue. Note: <it>(fragments * fragment_size) - queue</it>
|
||||||
|
should not be equal to <it>count</it>.
|
||||||
|
<tag>underrun</tag>
|
||||||
|
This value tells the application the number of underruns since the ast call
|
||||||
|
of <it>snd_pcm_playback_status</it>.
|
||||||
|
<tag>time</tag>
|
||||||
|
Delay till played of the first sample from next write. This value should
|
||||||
|
be used for time synchronization. Returned value is in the same format as
|
||||||
|
returned from the standard C function <it>gettimeofday( &ero;time, NULL )</it>.
|
||||||
|
This variable contains right value only if playback time mode is enabled
|
||||||
|
(look to <it>snd_pcm_playback_time</it> function).
|
||||||
|
<tag>stime</tag>
|
||||||
|
Time when playback was started.
|
||||||
|
This variable contains right value only if playback time mode is enabled
|
||||||
|
(look to <it>snd_pcm_playback_time</it> function).
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_record_status( void *handle, snd_pcm_record_status_t *status )
|
||||||
|
<p>
|
||||||
|
Fills the *status structure. Function returns zero if successful, otherwise
|
||||||
|
it returns an error code.
|
||||||
|
<code>
|
||||||
|
struct snd_pcm_record_status {
|
||||||
|
unsigned int rate;
|
||||||
|
int fragments;
|
||||||
|
int fragment_size;
|
||||||
|
int count;
|
||||||
|
int free;
|
||||||
|
int overrun;
|
||||||
|
struct timeval time;
|
||||||
|
unsigned char reserved[16];
|
||||||
|
};
|
||||||
|
</code>
|
||||||
|
<descrip>
|
||||||
|
<tag>rate</tag>
|
||||||
|
Real record rate. This value reflects hardware limitations.
|
||||||
|
<tag>fragments</tag>
|
||||||
|
Currently allocated fragments by driver for the record direction.
|
||||||
|
<tag>fragment_size</tag>
|
||||||
|
Current fragment size used by driver for the record direction.
|
||||||
|
<tag>count</tag>
|
||||||
|
Count of bytes readable without blocking.
|
||||||
|
<tag>free</tag>
|
||||||
|
Count of bytes in buffer still free. Note: <it>(fragments * fragment_size) - free</it>
|
||||||
|
should not be equal to <it>count</it>.
|
||||||
|
<tag>overrun</tag>
|
||||||
|
This value tells application the count of overruns since the last call
|
||||||
|
to <it>snd_pcm_record_status</it>.
|
||||||
|
<tag>time</tag>
|
||||||
|
Lag since the next sample read was recorded. This value should be used for time
|
||||||
|
synchronization. Returned value is in the same format as returned by the
|
||||||
|
from standard C function <it>gettimeofday( &ero;time, NULL )</it>. This
|
||||||
|
variable contains right value only if record time mode is enabled (look to
|
||||||
|
<it>snd_pcm_record_time</it> function).
|
||||||
|
<tag>stime</tag>
|
||||||
|
Time when record was started. This variable contains right value only if
|
||||||
|
record time mode is enabled (look to <it>snd_pcm_record_time</it> function).
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_drain_playback( void *handle )
|
||||||
|
<p>
|
||||||
|
This function drain playback buffers immediately. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_flush_playback( void *handle )
|
||||||
|
<p>
|
||||||
|
This function flushes the playback buffers. It blocks the program while the
|
||||||
|
all the waiting samples in kernel playback buffers are processed. Function
|
||||||
|
returns zero if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_flush_record( void *handle )
|
||||||
|
<p>
|
||||||
|
This function flushes (destroyes) record buffers. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_playback_time( void *handle, int enable )
|
||||||
|
<p>
|
||||||
|
This function enables or disables time mode for playback direction. Time mode
|
||||||
|
allows to application better time synchronization. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>int snd_pcm_record_time( void *handle, int enable )
|
||||||
|
<p>
|
||||||
|
This function enables or disables time mode for record direction. Time mode
|
||||||
|
allows to application better time synchronization. Function returns zero
|
||||||
|
if successful, otherwise it returns an error code.
|
||||||
|
|
||||||
|
<sect2>ssize_t snd_pcm_write( void *handle, const void *buffer, size_t size )
|
||||||
|
<p>
|
||||||
|
Writes samples to the device which must be in the proper format
|
||||||
|
specified by the <it>snd_pcm_playback_format</it> function. Function
|
||||||
|
returns zero or positive value if playback was successful (value represents
|
||||||
|
count of bytes which was successfuly written to device) or an
|
||||||
|
error value if error occured. Function should suspend process if
|
||||||
|
block mode is active.
|
||||||
|
|
||||||
|
<sect2>ssize_t snd_pcm_read( void *handle, void *buffer, size_t size )
|
||||||
|
<p>
|
||||||
|
Function reads samples from driver. Samples are in format specified
|
||||||
|
by <it>snd_pcm_record_format</it> function. Function returns zero
|
||||||
|
or positive value if record was success (value represents count of bytes
|
||||||
|
which was successfuly read from device) or negative error value if
|
||||||
|
error occured. Function should suspend process if block mode is active.
|
||||||
|
|
||||||
|
<sect1>Examples
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The following example shows how to play the first 512kB from the
|
||||||
|
/tmp/test.au file with soundcard #0 and PCM device #0:
|
||||||
|
|
||||||
|
<tscreen><code>
|
||||||
|
int card = 0, device = 0, err, fd, count, size, idx;
|
||||||
|
void *handle;
|
||||||
|
snd_pcm_format_t format;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
buffer = (char *)malloc( 512 * 1024 );
|
||||||
|
if ( !buffer ) return;
|
||||||
|
if ( (err = snd_pcm_open( &ero;handle, card, device, SND_PCM_OPEN_PLAYBACK )) < 0 ) {
|
||||||
|
fprintf( stderr, "open failed: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
format.format = SND_PCM_SFMT_MU_LAW;
|
||||||
|
format.rate = 8000;
|
||||||
|
format.voices = 1;
|
||||||
|
if ( (err = snd_pcm_playback_format( handle, &ero;format )) < 0 ) {
|
||||||
|
fprintf( stderr, "format setup failed: %s\n", snd_strerror( err ) );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fd = open( "/tmp/test.au" );
|
||||||
|
if ( fd < 0 ) {
|
||||||
|
perror( "open file" );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idx = 0;
|
||||||
|
count = read( fd, buffer, 512 * 1024 );
|
||||||
|
if ( count <= 0 ) {
|
||||||
|
perror( "read from file" );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
close( fd );
|
||||||
|
if ( !memcmp( buffer, ".snd", 4 ) ) {
|
||||||
|
idx = (buffer[4]<<24)|(buffer[5]<<16)|(buffer[6]<<8)|(buffer[7]);
|
||||||
|
if ( idx > 128 ) idx = 128;
|
||||||
|
if ( idx > count ) idx = count;
|
||||||
|
}
|
||||||
|
size = snd_pcm_write( handle, &ero;buffer[ idx ], count - idx );
|
||||||
|
printf( "Bytes written %i from %i...\n", size, count - idx );
|
||||||
|
snd_pcm_close( handle );
|
||||||
|
free( buffer );
|
||||||
|
</code></tscreen>
|
||||||
|
|
||||||
|
</article>
|
||||||
1230
doc/soundapi.txt
Normal file
1230
doc/soundapi.txt
Normal file
File diff suppressed because it is too large
Load diff
10
include/Makefile
Normal file
10
include/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../Makefile.conf
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.o *.orig *~
|
||||||
|
|
||||||
7
include/config.h
Normal file
7
include/config.h
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
/* include/config.h. Generated automatically by configure. */
|
||||||
|
/*
|
||||||
|
* Configuration header file for compilation of the ALSA driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SND_LIB_VERSION "0.0.9"
|
||||||
|
/* #undef WORDS_BIGENDIAN */
|
||||||
6
include/config.h.in
Normal file
6
include/config.h.in
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Configuration header file for compilation of the ALSA driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef SND_LIB_VERSION
|
||||||
|
#undef WORDS_BIGENDIAN
|
||||||
28
include/control.h
Normal file
28
include/control.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* control.h *
|
||||||
|
* Control Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_cards( void );
|
||||||
|
unsigned int snd_cards_mask( void );
|
||||||
|
int snd_card_name( const char *name );
|
||||||
|
|
||||||
|
int snd_ctl_open( void **handle, int card );
|
||||||
|
int snd_ctl_close( void *handle );
|
||||||
|
int snd_ctl_file_descriptor( void *handle );
|
||||||
|
int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info );
|
||||||
|
int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info );
|
||||||
|
int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info );
|
||||||
|
int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info );
|
||||||
|
int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
17
include/error.h
Normal file
17
include/error.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* error.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SND_ERROR_BEGIN 500000
|
||||||
|
#define SND_ERROR_UNCOMPATIBLE_VERSION (SND_ERROR_BEGIN+0)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *snd_strerror( int errnum );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
5
include/footer.h
Normal file
5
include/footer.h
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* __SOUNDLIB_H */
|
||||||
27
include/header.h
Normal file
27
include/header.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Application interface library for the ALSA driver
|
||||||
|
* Copyright (c) by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SOUNDLIB_H
|
||||||
|
#define __SOUNDLIB_H
|
||||||
|
|
||||||
|
#include <linux/sound.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
240
include/local.h
Normal file
240
include/local.h
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
/*
|
||||||
|
* Application interface library for the ALSA driver
|
||||||
|
* Copyright (c) 1994/98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
#include "../../../include/ultraconf.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define ASSERT( s ) assert( s )
|
||||||
|
|
||||||
|
void __snd_dprintf( char *, ... );
|
||||||
|
#define snd_dprintf( args... ) __ultra_dprintf( ##args )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ASSERT( s ) { ; }
|
||||||
|
|
||||||
|
#define snd_dprintf( fmt... ) /* nothing */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern inline int snd_p_rint( float x )
|
||||||
|
{
|
||||||
|
return (int)( x + (float)0.5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern inline void snd_put_byte( unsigned char *array, unsigned int idx, unsigned char b )
|
||||||
|
{
|
||||||
|
*(array + idx) = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned char snd_get_byte( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return *(array + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined( __i386__ )
|
||||||
|
|
||||||
|
extern inline void snd_put_le_word( unsigned char *array, unsigned int idx, unsigned short w )
|
||||||
|
{
|
||||||
|
*(unsigned short *)(array + idx) = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_le_word( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return *(unsigned short *)(array + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_le_dword( unsigned char *array, unsigned int idx, unsigned int dw )
|
||||||
|
{
|
||||||
|
*(unsigned int *)(array + idx) = dw;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_le_dword( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return *(unsigned int *)(array + idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
extern inline void snd_put_le_word( unsigned char *array, unsigned int idx, unsigned short w )
|
||||||
|
{
|
||||||
|
*(array + idx + 0) = (unsigned char)(w >> 0);
|
||||||
|
*(array + idx + 1) = (unsigned char)(w >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_le_word( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 0) << 0 ) |
|
||||||
|
( *(array + idx + 1) << 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_le_dword( unsigned char *array, unsigned int idx, unsigned int dw )
|
||||||
|
{
|
||||||
|
*(array + idx + 0) = (unsigned char)(dw >> 0);
|
||||||
|
*(array + idx + 1) = (unsigned char)(dw >> 8);
|
||||||
|
*(array + idx + 2) = (unsigned char)(dw >> 16);
|
||||||
|
*(array + idx + 3) = (unsigned char)(dw >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_le_dword( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 0) << 0 ) |
|
||||||
|
( *(array + idx + 1) << 8 ) |
|
||||||
|
( *(array + idx + 2) << 16 ) |
|
||||||
|
( *(array + idx + 3) << 24 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern inline void snd_put_le_word( unsigned char *array, unsigned int idx, unsigned short w )
|
||||||
|
{
|
||||||
|
*(array + idx + 0) = (unsigned char)(w >> 8);
|
||||||
|
*(array + idx + 1) = (unsigned char)(w >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_le_word( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 0) << 8 ) |
|
||||||
|
( *(array + idx + 1) << 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_le_dword( unsigned char *array, unsigned int idx, unsigned int dw )
|
||||||
|
{
|
||||||
|
*(array + idx + 0) = (unsigned char)(dw >> 24);
|
||||||
|
*(array + idx + 1) = (unsigned char)(dw >> 16);
|
||||||
|
*(array + idx + 2) = (unsigned char)(dw >> 8);
|
||||||
|
*(array + idx + 3) = (unsigned char)(dw >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_le_dword( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 0) << 24 ) |
|
||||||
|
( *(array + idx + 1) << 16 ) |
|
||||||
|
( *(array + idx + 2) << 8 ) |
|
||||||
|
( *(array + idx + 3) << 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern inline unsigned char snd_get_unsigned_byte( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_unsigned_byte( unsigned char *ptr, unsigned char val )
|
||||||
|
{
|
||||||
|
*ptr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned char snd_get_signed_byte( signed char *ptr )
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_signed_byte( signed char *ptr, signed char val )
|
||||||
|
{
|
||||||
|
*ptr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined( WORDS_BIGENDIAN ) || defined( __i386__ )
|
||||||
|
|
||||||
|
extern inline signed short snd_get_signed_le_word( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return *(signed short *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_signed_le_word( unsigned char *ptr, signed short val )
|
||||||
|
{
|
||||||
|
*(signed short *)ptr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_unsigned_le_word( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return *(unsigned short *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_unsigned_le_word( unsigned char *ptr, unsigned short val )
|
||||||
|
{
|
||||||
|
*(unsigned short *)ptr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_unsigned_le_dword( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return *(unsigned int *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_unsigned_le_dword( unsigned char *ptr, unsigned int val )
|
||||||
|
{
|
||||||
|
*(unsigned int *)ptr = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_signed_le_word( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return (signed short)( *ptr + ( *( ptr + 1 ) << 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_signed_le_word( unsigned char *ptr, signed short val )
|
||||||
|
{
|
||||||
|
*ptr = (unsigned char)val;
|
||||||
|
*(ptr + 1) = val >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_unsigned_le_word( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return (signed short)( *ptr + ( *( ptr + 1 ) << 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_unsigned_le_word( unsigned char *ptr, unsigned short val )
|
||||||
|
{
|
||||||
|
*ptr = (unsigned char)val;
|
||||||
|
*(ptr + 1) = val >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_unsigned_le_dword( unsigned char *ptr )
|
||||||
|
{
|
||||||
|
return (signed int)( *ptr + ( *( ptr + 1 ) << 8 ) +
|
||||||
|
( *( ptr + 2 ) << 8 ) + ( *( ptr + 3 ) << 8 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline void snd_put_unsigned_le_dword( unsigned char *ptr, unsigned int val )
|
||||||
|
{
|
||||||
|
*ptr = (unsigned char)val;
|
||||||
|
*(ptr + 1) = (unsigned char)val >> 8;
|
||||||
|
*(ptr + 2) = (unsigned char)val >> 16;
|
||||||
|
*(ptr + 3) = (unsigned char)val >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern inline unsigned short snd_get_be_word( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 1) << 0 ) |
|
||||||
|
( *(array + idx + 0) << 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern inline unsigned int snd_get_be_dword( unsigned char *array, unsigned int idx )
|
||||||
|
{
|
||||||
|
return ( *(array + idx + 3) << 0 ) |
|
||||||
|
( *(array + idx + 2) << 8 ) |
|
||||||
|
( *(array + idx + 1) << 16 ) |
|
||||||
|
( *(array + idx + 0) << 24 );
|
||||||
|
}
|
||||||
35
include/mixer.h
Normal file
35
include/mixer.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* mixer.h *
|
||||||
|
* Mixer Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct snd_mixer_callbacks {
|
||||||
|
void *private_data; /* should be used by application */
|
||||||
|
void (*channel_was_changed)( void *private_data, int channel );
|
||||||
|
void *reserved[15]; /* reserved for future use - must be NULL!!! */
|
||||||
|
} snd_mixer_callbacks_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_mixer_open( void **handle, int card, int device );
|
||||||
|
int snd_mixer_close( void *handle );
|
||||||
|
int snd_mixer_file_descriptor( void *handle );
|
||||||
|
int snd_mixer_channels( void *handle );
|
||||||
|
int snd_mixer_info( void *handle, snd_mixer_info_t *info );
|
||||||
|
int snd_mixer_exact_mode( void *handle, int enable );
|
||||||
|
int snd_mixer_channel( void *handle, const char *channel_id );
|
||||||
|
int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info );
|
||||||
|
int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data );
|
||||||
|
int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data );
|
||||||
|
int snd_mixer_special_read( void *handle, snd_mixer_special_t *special );
|
||||||
|
int snd_mixer_special_write( void *handle, snd_mixer_special_t *special );
|
||||||
|
int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
40
include/pcm.h
Normal file
40
include/pcm.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* pcm.h *
|
||||||
|
* Digital Audio Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define SND_PCM_OPEN_PLAYBACK (O_WRONLY)
|
||||||
|
#define SND_PCM_OPEN_RECORD (O_RDONLY)
|
||||||
|
#define SND_PCM_OPEN_DUPLEX (O_RDWR)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_pcm_open( void **handle, int card, int device, int mode );
|
||||||
|
int snd_pcm_close( void *handle );
|
||||||
|
int snd_pcm_file_descriptor( void *handle );
|
||||||
|
int snd_pcm_block_mode( void *handle, int enable );
|
||||||
|
int snd_pcm_info( void *handle, snd_pcm_info_t *info );
|
||||||
|
int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info );
|
||||||
|
int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info );
|
||||||
|
int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format );
|
||||||
|
int snd_pcm_record_format( void *handle, snd_pcm_format_t *format );
|
||||||
|
int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params );
|
||||||
|
int snd_pcm_record_params( void *handle, snd_pcm_record_params_t *params );
|
||||||
|
int snd_pcm_playback_status( void *handle, snd_pcm_playback_status_t *status );
|
||||||
|
int snd_pcm_record_status( void *handle, snd_pcm_record_status_t *status );
|
||||||
|
int snd_pcm_drain_playback( void *handle );
|
||||||
|
int snd_pcm_flush_playback( void *handle );
|
||||||
|
int snd_pcm_flush_record( void *handle );
|
||||||
|
int snd_pcm_playback_time( void *handle, int enable );
|
||||||
|
int snd_pcm_record_time( void *handle, int enable );
|
||||||
|
ssize_t snd_pcm_write( void *handle, const void *buffer, size_t size );
|
||||||
|
ssize_t snd_pcm_read( void *handle, void *buffer, size_t size );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
161
include/soundlib.h
Normal file
161
include/soundlib.h
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Application interface library for the ALSA driver
|
||||||
|
* Copyright (c) by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SOUNDLIB_H
|
||||||
|
#define __SOUNDLIB_H
|
||||||
|
|
||||||
|
#include <linux/sound.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* version.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SOUNDLIB_VERSION_MAJOR 0
|
||||||
|
#define SOUNDLIB_VERSION_MINOR 0
|
||||||
|
#define SOUNDLIB_VERSION_SUBMINOR 9
|
||||||
|
#define SOUNDLIB_VERSION ( ( LIBULTRA_VERSION_MAJOR << 16 ) | ( LIBULTRA_VERSION_MINOR << 8 ) | LIB_ULTRA_VERSION_SUBMINOR )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* error.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SND_ERROR_BEGIN 500000
|
||||||
|
#define SND_ERROR_UNCOMPATIBLE_VERSION (SND_ERROR_BEGIN+0)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *snd_strerror( int errnum );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* control.h *
|
||||||
|
* Control Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_cards( void );
|
||||||
|
unsigned int snd_cards_mask( void );
|
||||||
|
int snd_card_name( const char *name );
|
||||||
|
|
||||||
|
int snd_ctl_open( void **handle, int card );
|
||||||
|
int snd_ctl_close( void *handle );
|
||||||
|
int snd_ctl_file_descriptor( void *handle );
|
||||||
|
int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info );
|
||||||
|
int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info );
|
||||||
|
int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info );
|
||||||
|
int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info );
|
||||||
|
int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* mixer.h *
|
||||||
|
* Mixer Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct snd_mixer_callbacks {
|
||||||
|
void *private_data; /* should be used by application */
|
||||||
|
void (*channel_was_changed)( void *private_data, int channel );
|
||||||
|
void *reserved[15]; /* reserved for future use - must be NULL!!! */
|
||||||
|
} snd_mixer_callbacks_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_mixer_open( void **handle, int card, int device );
|
||||||
|
int snd_mixer_close( void *handle );
|
||||||
|
int snd_mixer_file_descriptor( void *handle );
|
||||||
|
int snd_mixer_channels( void *handle );
|
||||||
|
int snd_mixer_info( void *handle, snd_mixer_info_t *info );
|
||||||
|
int snd_mixer_exact_mode( void *handle, int enable );
|
||||||
|
int snd_mixer_channel( void *handle, const char *channel_id );
|
||||||
|
int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info );
|
||||||
|
int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data );
|
||||||
|
int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data );
|
||||||
|
int snd_mixer_special_read( void *handle, snd_mixer_special_t *special );
|
||||||
|
int snd_mixer_special_write( void *handle, snd_mixer_special_t *special );
|
||||||
|
int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* pcm.h *
|
||||||
|
* Digital Audio Interface *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define SND_PCM_OPEN_PLAYBACK (O_WRONLY)
|
||||||
|
#define SND_PCM_OPEN_RECORD (O_RDONLY)
|
||||||
|
#define SND_PCM_OPEN_DUPLEX (O_RDWR)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int snd_pcm_open( void **handle, int card, int device, int mode );
|
||||||
|
int snd_pcm_close( void *handle );
|
||||||
|
int snd_pcm_file_descriptor( void *handle );
|
||||||
|
int snd_pcm_block_mode( void *handle, int enable );
|
||||||
|
int snd_pcm_info( void *handle, snd_pcm_info_t *info );
|
||||||
|
int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info );
|
||||||
|
int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info );
|
||||||
|
int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format );
|
||||||
|
int snd_pcm_record_format( void *handle, snd_pcm_format_t *format );
|
||||||
|
int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params );
|
||||||
|
int snd_pcm_record_params( void *handle, snd_pcm_record_params_t *params );
|
||||||
|
int snd_pcm_playback_status( void *handle, snd_pcm_playback_status_t *status );
|
||||||
|
int snd_pcm_record_status( void *handle, snd_pcm_record_status_t *status );
|
||||||
|
int snd_pcm_drain_playback( void *handle );
|
||||||
|
int snd_pcm_flush_playback( void *handle );
|
||||||
|
int snd_pcm_flush_record( void *handle );
|
||||||
|
int snd_pcm_playback_time( void *handle, int enable );
|
||||||
|
int snd_pcm_record_time( void *handle, int enable );
|
||||||
|
ssize_t snd_pcm_write( void *handle, const void *buffer, size_t size );
|
||||||
|
ssize_t snd_pcm_read( void *handle, void *buffer, size_t size );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* __SOUNDLIB_H */
|
||||||
9
include/version.h
Normal file
9
include/version.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* version.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SOUNDLIB_VERSION_MAJOR 0
|
||||||
|
#define SOUNDLIB_VERSION_MINOR 0
|
||||||
|
#define SOUNDLIB_VERSION_SUBMINOR 9
|
||||||
|
#define SOUNDLIB_VERSION ( ( LIBULTRA_VERSION_MAJOR << 16 ) | ( LIBULTRA_VERSION_MINOR << 8 ) | LIB_ULTRA_VERSION_SUBMINOR )
|
||||||
|
|
||||||
9
include/version.h.in
Normal file
9
include/version.h.in
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* version.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SOUNDLIB_VERSION_MAJOR @SND_LIB_MAJOR@
|
||||||
|
#define SOUNDLIB_VERSION_MINOR @SND_LIB_MINOR@
|
||||||
|
#define SOUNDLIB_VERSION_SUBMINOR @SND_LIB_SUBMINOR@
|
||||||
|
#define SOUNDLIB_VERSION ( ( LIBULTRA_VERSION_MAJOR << 16 ) | ( LIBULTRA_VERSION_MINOR << 8 ) | LIB_ULTRA_VERSION_SUBMINOR )
|
||||||
|
|
||||||
250
install-sh
Normal file
250
install-sh
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
#! /bin/sh
|
||||||
|
#
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||||
|
#
|
||||||
|
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
# documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
# the above copyright notice appear in all copies and that both that
|
||||||
|
# copyright notice and this permission notice appear in supporting
|
||||||
|
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||||
|
# publicity pertaining to distribution of the software without specific,
|
||||||
|
# written prior permission. M.I.T. makes no representations about the
|
||||||
|
# suitability of this software for any purpose. It is provided "as is"
|
||||||
|
# without express or implied warranty.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
transformbasename=""
|
||||||
|
transform_arg=""
|
||||||
|
instcmd="$mvprog"
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=""
|
||||||
|
chgrpcmd=""
|
||||||
|
stripcmd=""
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=""
|
||||||
|
dst=""
|
||||||
|
dir_arg=""
|
||||||
|
|
||||||
|
while [ x"$1" != x ]; do
|
||||||
|
case $1 in
|
||||||
|
-c) instcmd="$cpprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd="$stripprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
*) if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
src=$1
|
||||||
|
else
|
||||||
|
# this colon is to work around a 386BSD /bin/sh bug
|
||||||
|
:
|
||||||
|
dst=$1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no input file specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]; then
|
||||||
|
dst=$src
|
||||||
|
src=""
|
||||||
|
|
||||||
|
if [ -d $dst ]; then
|
||||||
|
instcmd=:
|
||||||
|
else
|
||||||
|
instcmd=mkdir
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
|
||||||
|
if [ -f $src -o -d $src ]
|
||||||
|
then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
echo "install: $src does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dst" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no destination specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; if your system
|
||||||
|
# does not like double slashes in filenames, you may need to add some logic
|
||||||
|
|
||||||
|
if [ -d $dst ]
|
||||||
|
then
|
||||||
|
dst="$dst"/`basename $src`
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## this sed command emulates the dirname command
|
||||||
|
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if [ ! -d "$dstdir" ]; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-${defaultIFS}}"
|
||||||
|
|
||||||
|
oIFS="${IFS}"
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
IFS="${oIFS}"
|
||||||
|
|
||||||
|
pathcomp=''
|
||||||
|
|
||||||
|
while [ $# -ne 0 ] ; do
|
||||||
|
pathcomp="${pathcomp}${1}"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ ! -d "${pathcomp}" ] ;
|
||||||
|
then
|
||||||
|
$mkdirprog "${pathcomp}"
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
pathcomp="${pathcomp}/"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]
|
||||||
|
then
|
||||||
|
$doit $instcmd $dst &&
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
|
||||||
|
if [ x"$transformarg" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
dstfile=`basename $dst $transformbasename |
|
||||||
|
sed $transformarg`$transformbasename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't allow the sed command to completely eliminate the filename
|
||||||
|
|
||||||
|
if [ x"$dstfile" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make a temp file name in the proper directory.
|
||||||
|
|
||||||
|
dsttmp=$dstdir/#inst.$$#
|
||||||
|
|
||||||
|
# Move or copy the file name to the temp name
|
||||||
|
|
||||||
|
$doit $instcmd $src $dsttmp &&
|
||||||
|
|
||||||
|
trap "rm -f ${dsttmp}" 0 &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits
|
||||||
|
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
|
||||||
|
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||||
|
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||||
|
|
||||||
|
fi &&
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
||||||
74
src/Makefile
Normal file
74
src/Makefile
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../Makefile.conf
|
||||||
|
|
||||||
|
TARGET=../lib/libsound.a
|
||||||
|
STARGET=../lib/libsound.so
|
||||||
|
STARGETX=../lib/libsound.so.$(SND_LIB_VERSION)
|
||||||
|
STARGETO=../lib/libsound.so.$(SND_LIB_MAJOR)
|
||||||
|
TARGETS=$(TARGET) $(STARGET)
|
||||||
|
|
||||||
|
STATIC_LIBS= control/libcontrol.a \
|
||||||
|
mixer/libmixer.a \
|
||||||
|
pcm/libpcm.a
|
||||||
|
DYNAMIC_LIBS= control/libcontrol.Sa \
|
||||||
|
mixer/libmixer.Sa \
|
||||||
|
pcm/libpcm.Sa
|
||||||
|
|
||||||
|
OBJECTS=error.o
|
||||||
|
SOBJECTS=error.So
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .s .S .o .So .a .Sa
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -c -o $*.o $<
|
||||||
|
.c.So:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -fPIC -c -o $*.So $<
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
$(TARGET): .depend $(OBJECTS) $(STATIC_LIBS)
|
||||||
|
rm -f ../lib/libsound.a
|
||||||
|
$(LINKER) -r -o $(TARGET) $(STATIC_LIBS) $(OBJECTS)
|
||||||
|
|
||||||
|
$(STARGET): .depend $(SOBJECTS) $(DYNAMIC_LIBS)
|
||||||
|
rm -f ../lib/libsound*.so*
|
||||||
|
$(CC) -shared -Wl,-soname,libsound.so.$(SND_LIB_MAJOR) $(DYNAMIC_LIBS) $(SOBJECTS) -o $(STARGETX)
|
||||||
|
ln -s libsound.so.$(SND_LIB_VERSION) $(STARGET)
|
||||||
|
ln -s libsound.so.$(SND_LIB_VERSION) $(STARGETO)
|
||||||
|
|
||||||
|
control/libcontrol.a:
|
||||||
|
$(MAKE) -C control
|
||||||
|
control/libcontrol.sa:
|
||||||
|
$(MAKE) -C control
|
||||||
|
|
||||||
|
mixer/libmixer.a:
|
||||||
|
$(MAKE) -C mixer
|
||||||
|
mixer/libmixer.sa:
|
||||||
|
$(MAKE) -C mixer
|
||||||
|
|
||||||
|
pcm/libpcm.a:
|
||||||
|
$(MAKE) -C pcm
|
||||||
|
pcm/libpcm.sa:
|
||||||
|
$(MAKE) -C pcm
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C control clean
|
||||||
|
$(MAKE) -C pcm clean
|
||||||
|
$(MAKE) -C mixer clean
|
||||||
|
rm -f core .depend *.o *.So *.orig *~
|
||||||
|
rm -f ../lib/libsound.*
|
||||||
|
|
||||||
|
.depend:
|
||||||
|
$(CPP) $(COPTS) $(INCLUDE) -M *.c > .depend
|
||||||
|
|
||||||
|
#
|
||||||
|
# include a dependency file if one exists
|
||||||
|
#
|
||||||
|
ifeq (.depend,$(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
||||||
42
src/control/Makefile
Normal file
42
src/control/Makefile
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../../Makefile.conf
|
||||||
|
|
||||||
|
TARGET=libcontrol.a
|
||||||
|
STARGET=libcontrol.Sa
|
||||||
|
OBJECTS=cards.o control.o
|
||||||
|
SOBJECTS=cards.So control.So
|
||||||
|
TARGETS=$(TARGET) $(STARGET)
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .s .S .o .So .a .Sa
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -c -o $*.o $<
|
||||||
|
.c.So:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -fPIC -c -o $*.So $<
|
||||||
|
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
$(TARGET): .depend $(OBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(OBJECTS)
|
||||||
|
|
||||||
|
$(STARGET): .depend $(SOBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(SOBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.o *.So *.a *.Sa *.orig *~
|
||||||
|
|
||||||
|
.depend:
|
||||||
|
$(CPP) $(COPTS) $(INCLUDE) -M *.c > .depend
|
||||||
|
|
||||||
|
#
|
||||||
|
# include a dependency file if one exists
|
||||||
|
#
|
||||||
|
ifeq (.depend,$(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
||||||
94
src/control/cards.c
Normal file
94
src/control/cards.c
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Control Interface - main file
|
||||||
|
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "soundlib.h"
|
||||||
|
|
||||||
|
#define SND_FILE_CONTROL "/dev/sndcontrol%i"
|
||||||
|
|
||||||
|
int snd_cards( void )
|
||||||
|
{
|
||||||
|
int idx, count;
|
||||||
|
unsigned int mask;
|
||||||
|
|
||||||
|
mask = snd_cards_mask();
|
||||||
|
for ( idx = 0, count = 0; idx < SND_CARDS; idx++ ) {
|
||||||
|
if ( mask & (1 << idx) ) count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this routine uses very ugly method...
|
||||||
|
* need to do...
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int snd_cards_mask( void )
|
||||||
|
{
|
||||||
|
int fd, idx;
|
||||||
|
unsigned int mask;
|
||||||
|
char filename[32];
|
||||||
|
|
||||||
|
for ( idx = 0, mask = 0; idx < SND_CARDS; idx++ ) {
|
||||||
|
sprintf( filename, SND_FILE_CONTROL, idx );
|
||||||
|
if ( (fd = open( filename, O_RDWR )) < 0 ) continue;
|
||||||
|
close( fd );
|
||||||
|
mask |= 1 << idx;
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_card_name( const char *string )
|
||||||
|
{
|
||||||
|
int card, cards;
|
||||||
|
void *handle;
|
||||||
|
struct snd_ctl_hw_info info;
|
||||||
|
|
||||||
|
cards = snd_cards();
|
||||||
|
if ( cards <= 0 ) return -ENODEV;
|
||||||
|
if ( !string ) return -EINVAL;
|
||||||
|
if ( (isdigit( *string ) && *(string+1) == 0) ||
|
||||||
|
(isdigit( *string ) && isdigit( *(string+1) ) && *(string+2) == 0) ) {
|
||||||
|
sscanf( string, "%i", &card );
|
||||||
|
card--;
|
||||||
|
if ( card < 0 || card >= cards )
|
||||||
|
return -EINVAL;
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
for ( card = 0; card < cards; card++ ) {
|
||||||
|
if ( snd_ctl_open( &handle, card ) < 0 )
|
||||||
|
continue;
|
||||||
|
if ( snd_ctl_hw_info( handle, &info ) < 0 ) {
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
if ( !strcmp( info.id, string ) )
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
146
src/control/control.c
Normal file
146
src/control/control.c
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* Control Interface - main file
|
||||||
|
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "soundlib.h"
|
||||||
|
|
||||||
|
#define SND_FILE_CONTROL "/dev/sndcontrol%i"
|
||||||
|
#define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 )
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int card;
|
||||||
|
int fd;
|
||||||
|
} snd_ctl_t;
|
||||||
|
|
||||||
|
int snd_ctl_open( void **handle, int card )
|
||||||
|
{
|
||||||
|
int fd, ver;
|
||||||
|
char filename[32];
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
if ( card < 0 || card >= SND_CARDS ) return -EINVAL;
|
||||||
|
sprintf( filename, SND_FILE_CONTROL, card );
|
||||||
|
if ( (fd = open( filename, O_RDWR )) < 0 ) return -errno;
|
||||||
|
if ( ioctl( fd, SND_CTL_IOCTL_PVERSION, &ver ) < 0 ) {
|
||||||
|
close( fd );
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if ( ver > SND_CTL_VERSION_MAX ) return -SND_ERROR_UNCOMPATIBLE_VERSION;
|
||||||
|
ctl = (snd_ctl_t *)calloc( 1, sizeof( snd_ctl_t ) );
|
||||||
|
if ( ctl == NULL ) {
|
||||||
|
close( fd );
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
ctl -> card = card;
|
||||||
|
ctl -> fd = fd;
|
||||||
|
*handle = ctl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_close( void *handle )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
res = close( ctl -> fd ) < 0 ? -errno : 0;
|
||||||
|
free( ctl );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_file_descriptor( void *handle )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
return ctl -> fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_HW_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_DEVICE, &dev ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_DEVICE, &dev ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_PLAYBACK_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_DEVICE, &dev ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_PCM_RECORD_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info )
|
||||||
|
{
|
||||||
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
|
ctl = (snd_ctl_t *)handle;
|
||||||
|
if ( !ctl ) return -EINVAL;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_MIXER_DEVICE, &dev ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
if ( ioctl( ctl -> fd, SND_CTL_IOCTL_MIXER_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
src/error.c
Normal file
42
src/error.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Error Routines
|
||||||
|
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
* snd_strerror routine needs to be recoded for locale support
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "soundlib.h"
|
||||||
|
|
||||||
|
static const char *snd_error_codes[] = {
|
||||||
|
"Sound protocol isn't compatible"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *snd_strerror( int errnum )
|
||||||
|
{
|
||||||
|
if ( errnum < 0 ) errnum = -errnum;
|
||||||
|
if ( errnum < SND_ERROR_BEGIN )
|
||||||
|
return (const char *)strerror( errnum );
|
||||||
|
errnum -= SND_ERROR_BEGIN;
|
||||||
|
if ( errnum >= sizeof( snd_error_codes ) / sizeof( const char * ) )
|
||||||
|
return "Unknown error";
|
||||||
|
return snd_error_codes[ errnum ];
|
||||||
|
}
|
||||||
41
src/mixer/Makefile
Normal file
41
src/mixer/Makefile
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../../Makefile.conf
|
||||||
|
|
||||||
|
TARGET=libmixer.a
|
||||||
|
STARGET=libmixer.Sa
|
||||||
|
OBJECTS=mixer.o
|
||||||
|
SOBJECTS=mixer.So
|
||||||
|
TARGETS=$(TARGET) $(STARGET)
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .s .S .o .So .a .Sa
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -c -o $*.o $<
|
||||||
|
.c.So:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -fPIC -c -o $*.So $<
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
$(TARGET): .depend $(OBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(OBJECTS)
|
||||||
|
|
||||||
|
$(STARGET): .depend $(SOBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(SOBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.o *.So *.a *.Sa *.orig *~
|
||||||
|
|
||||||
|
.depend:
|
||||||
|
$(CPP) $(COPTS) $(INCLUDE) -M *.c > .depend
|
||||||
|
|
||||||
|
#
|
||||||
|
# include a dependency file if one exists
|
||||||
|
#
|
||||||
|
ifeq (.depend,$(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
||||||
224
src/mixer/mixer.c
Normal file
224
src/mixer/mixer.c
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* Mixer Interface - main file
|
||||||
|
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "soundlib.h"
|
||||||
|
|
||||||
|
#define SND_FILE_MIXER "/dev/sndmixer%i%i"
|
||||||
|
#define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 )
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int card;
|
||||||
|
int device;
|
||||||
|
int fd;
|
||||||
|
} snd_mixer_t;
|
||||||
|
|
||||||
|
int snd_mixer_open( void **handle, int card, int device )
|
||||||
|
{
|
||||||
|
int fd, ver;
|
||||||
|
char filename[32];
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
if ( card < 0 || card >= SND_CARDS ) return -EINVAL;
|
||||||
|
sprintf( filename, SND_FILE_MIXER, card, device );
|
||||||
|
if ( (fd = open( filename, O_RDWR )) < 0 ) return -errno;
|
||||||
|
if ( ioctl( fd, SND_MIXER_IOCTL_PVERSION, &ver ) < 0 ) {
|
||||||
|
close( fd );
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if ( ver > SND_CTL_VERSION_MAX ) return -SND_ERROR_UNCOMPATIBLE_VERSION;
|
||||||
|
mixer = (snd_mixer_t *)calloc( 1, sizeof( snd_mixer_t ) );
|
||||||
|
if ( mixer == NULL ) {
|
||||||
|
close( fd );
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
mixer -> card = card;
|
||||||
|
mixer -> device = device;
|
||||||
|
mixer -> fd = fd;
|
||||||
|
*handle = mixer;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_close( void *handle )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
res = close( mixer -> fd ) < 0 ? -errno : 0;
|
||||||
|
free( mixer );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_file_descriptor( void *handle )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
return mixer -> fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_channels( void *handle )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_CHANNELS, &result ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_info( void *handle, snd_mixer_info_t *info )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_exact_mode( void *handle, int enable )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_EXACT, &enable ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_channel( void *handle, const char *channel_id )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
snd_mixer_channel_info_t info;
|
||||||
|
int idx, channels, err;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
/* bellow implementation isn't optimized for speed */
|
||||||
|
/* info about channels should be cached in the snd_mixer_t structure */
|
||||||
|
if ( (channels = snd_mixer_channels( handle )) < 0 )
|
||||||
|
return channels;
|
||||||
|
for ( idx = 0; idx < channels; idx++ ) {
|
||||||
|
if ( (err = snd_mixer_channel_info( handle, idx, &info )) < 0 )
|
||||||
|
return err;
|
||||||
|
if ( !strncmp( channel_id, info.name, sizeof( info.name ) ) )
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_channel_info( void *handle, int channel, snd_mixer_channel_info_t *info )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
info -> channel = channel;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_CHANNEL_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_channel_read( void *handle, int channel, snd_mixer_channel_t *data )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
data -> channel = channel;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_CHANNEL_READ, data ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_channel_write( void *handle, int channel, snd_mixer_channel_t *data )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
data -> channel = channel;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_CHANNEL_WRITE, data ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_special_read( void *handle, snd_mixer_special_t *special )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_SPECIAL_READ, special ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_special_write( void *handle, snd_mixer_special_t *special )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
if ( ioctl( mixer -> fd, SND_MIXER_IOCTL_SPECIAL_WRITE, special ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_mixer_read( void *handle, snd_mixer_callbacks_t *callbacks )
|
||||||
|
{
|
||||||
|
snd_mixer_t *mixer;
|
||||||
|
int idx, result, count;
|
||||||
|
unsigned int cmd, tmp;
|
||||||
|
unsigned char buffer[ 64 ];
|
||||||
|
|
||||||
|
mixer = (snd_mixer_t *)handle;
|
||||||
|
if ( !mixer ) return -EINVAL;
|
||||||
|
count = 0;
|
||||||
|
while ( (result = read( mixer -> fd, &buffer, sizeof( buffer ))) > 0 ) {
|
||||||
|
if ( result & 7 ) return -EIO;
|
||||||
|
if ( !callbacks ) continue;
|
||||||
|
for ( idx = 0; idx < result; idx += 8 ) {
|
||||||
|
cmd = *(unsigned int *)&buffer[ idx ];
|
||||||
|
tmp = *(unsigned int *)&buffer[ idx + 4 ];
|
||||||
|
if ( cmd == 0 && callbacks -> channel_was_changed ) {
|
||||||
|
callbacks -> channel_was_changed( callbacks -> private_data, (int)tmp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count += result >> 3; /* return only number of changes */
|
||||||
|
}
|
||||||
|
return result >= 0 ? count : -errno;
|
||||||
|
}
|
||||||
40
src/pcm/Makefile
Normal file
40
src/pcm/Makefile
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../../Makefile.conf
|
||||||
|
|
||||||
|
TARGET=libpcm.a
|
||||||
|
STARGET=libpcm.Sa
|
||||||
|
OBJECTS=pcm.o
|
||||||
|
SOBJECTS=pcm.So
|
||||||
|
TARGETS=$(TARGET) $(STARGET)
|
||||||
|
|
||||||
|
.SUFFIXES: .c .s .S .o .So .a .Sa
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -c -o $*.o $<
|
||||||
|
.c.So:
|
||||||
|
$(CC) $(COPTS) $(INCLUDE) -fPIC -c -o $*.So $<
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
$(TARGET): .depend $(OBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(OBJECTS)
|
||||||
|
|
||||||
|
$(STARGET): .depend $(SOBJECTS)
|
||||||
|
$(LINKER) -r -o $@ $(SOBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.o *.So *.a *.Sa *.orig *~
|
||||||
|
|
||||||
|
.depend:
|
||||||
|
$(CPP) $(COPTS) $(INCLUDE) -M *.c > .depend
|
||||||
|
|
||||||
|
#
|
||||||
|
# include a dependency file if one exists
|
||||||
|
#
|
||||||
|
ifeq (.depend,$(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
||||||
265
src/pcm/pcm.c
Normal file
265
src/pcm/pcm.c
Normal file
|
|
@ -0,0 +1,265 @@
|
||||||
|
/*
|
||||||
|
* PCM Interface - main file
|
||||||
|
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "soundlib.h"
|
||||||
|
|
||||||
|
#define SND_FILE_PCM "/dev/sndpcm%i%i"
|
||||||
|
#define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 )
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int card;
|
||||||
|
int device;
|
||||||
|
int fd;
|
||||||
|
} snd_pcm_t;
|
||||||
|
|
||||||
|
int snd_pcm_open( void **handle, int card, int device, int mode )
|
||||||
|
{
|
||||||
|
int fd, ver;
|
||||||
|
char filename[32];
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
if ( card < 0 || card >= SND_CARDS ) return -EINVAL;
|
||||||
|
sprintf( filename, SND_FILE_PCM, card, device );
|
||||||
|
if ( (fd = open( filename, mode )) < 0 ) return -errno;
|
||||||
|
if ( ioctl( fd, SND_PCM_IOCTL_PVERSION, &ver ) < 0 ) {
|
||||||
|
close( fd );
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if ( ver > SND_CTL_VERSION_MAX ) return -SND_ERROR_UNCOMPATIBLE_VERSION;
|
||||||
|
pcm = (snd_pcm_t *)calloc( 1, sizeof( snd_pcm_t ) );
|
||||||
|
if ( pcm == NULL ) {
|
||||||
|
close( fd );
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
pcm -> card = card;
|
||||||
|
pcm -> device = device;
|
||||||
|
pcm -> fd = fd;
|
||||||
|
*handle = pcm;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_close( void *handle )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
res = close( pcm -> fd ) < 0 ? -errno : 0;
|
||||||
|
free( pcm );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_file_descriptor( void *handle )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
return pcm -> fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_block_mode( void *handle, int enable )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
long flags;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( fcntl( pcm -> fd, F_GETFL, &flags ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
if ( enable )
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
else
|
||||||
|
flags &= ~O_NONBLOCK;
|
||||||
|
if ( fcntl( pcm -> fd, F_SETFL, &flags ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_info( void *handle, snd_pcm_info_t *info )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PLAYBACK_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RECORD_INFO, info ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PLAYBACK_FORMAT, format ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_record_format( void *handle, snd_pcm_format_t *format )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RECORD_FORMAT, format ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PLAYBACK_PARAMS, params ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_record_params( void *handle, snd_pcm_record_params_t *params )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RECORD_PARAMS, params ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_playback_status( void *handle, snd_pcm_playback_status_t *status )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PLAYBACK_STATUS, status ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_record_status( void *handle, snd_pcm_record_status_t *status )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RECORD_STATUS, status ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_drain_playback( void *handle )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_DRAIN_PLAYBACK ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_flush_playback( void *handle )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_FLUSH_PLAYBACK ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_flush_record( void *handle )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_FLUSH_RECORD ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_playback_time( void *handle, int enable )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PLAYBACK_TIME, &enable ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_record_time( void *handle, int enable )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RECORD_TIME, &enable ) < 0 )
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t snd_pcm_write( void *handle, const void *buffer, size_t size )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
ssize_t result;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
result = write( pcm -> fd, buffer, size );
|
||||||
|
if ( result < 0 ) return -errno;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t snd_pcm_read( void *handle, void *buffer, size_t size )
|
||||||
|
{
|
||||||
|
snd_pcm_t *pcm;
|
||||||
|
ssize_t result;
|
||||||
|
|
||||||
|
pcm = (snd_pcm_t *)handle;
|
||||||
|
if ( !pcm ) return -EINVAL;
|
||||||
|
result = read( pcm -> fd, buffer, size );
|
||||||
|
if ( result < 0 ) return -errno;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
15
test/Makefile
Normal file
15
test/Makefile
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -static -O2 -g -Wall -pipe
|
||||||
|
TARGETS = control mixer
|
||||||
|
LIB = -L../lib -lsound
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
control: control.c
|
||||||
|
$(CC) $(CFLAGS) $(LIB) -o control control.c
|
||||||
|
|
||||||
|
mixer: mixer.c
|
||||||
|
$(CC) $(CFLAGS) $(LIB) -o mixer mixer.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(TARGETS) *~
|
||||||
67
test/control.c
Normal file
67
test/control.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../include/soundlib.h"
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
int idx, idx1, cards, err;
|
||||||
|
void *handle;
|
||||||
|
struct snd_ctl_hw_info info;
|
||||||
|
snd_pcm_info_t pcminfo;
|
||||||
|
snd_mixer_info_t mixerinfo;
|
||||||
|
char str[128];
|
||||||
|
|
||||||
|
cards = snd_cards();
|
||||||
|
printf( "Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "" );
|
||||||
|
if ( cards <= 0 ) {
|
||||||
|
printf( "Giving up...\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( idx = 0; idx < cards; idx++ ) {
|
||||||
|
if ( (err = snd_ctl_open( &handle, idx )) < 0 ) {
|
||||||
|
printf( "Open error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( (err = snd_ctl_hw_info( handle, &info )) < 0 ) {
|
||||||
|
printf( "HW info error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf( "Soundcard #%i:\n", idx + 1 );
|
||||||
|
printf( " type - %i\n", info.type );
|
||||||
|
printf( " gcaps - 0x%x\n", info.gcaps );
|
||||||
|
printf( " lcaps - 0x%x\n", info.lcaps );
|
||||||
|
printf( " pcm devs - 0x%x\n", info.pcmdevs );
|
||||||
|
printf( " mixer devs - 0x%x\n", info.mixerdevs );
|
||||||
|
printf( " midi devs - 0x%x\n", info.mididevs );
|
||||||
|
memset( str, 0, sizeof( str ) );
|
||||||
|
strncpy( str, info.id, sizeof( info.id ) );
|
||||||
|
printf( " id - '%s'\n", str );
|
||||||
|
printf( " abbreviation - '%s'\n", info.abbreviation );
|
||||||
|
printf( " name - '%s'\n", info.name );
|
||||||
|
printf( " longname - '%s'\n", info.longname );
|
||||||
|
for ( idx1 = 0; idx1 < info.pcmdevs; idx1++ ) {
|
||||||
|
printf( "PCM info, device #%i:\n", idx1 );
|
||||||
|
if ( (err = snd_ctl_pcm_info( handle, idx1, &pcminfo )) < 0 ) {
|
||||||
|
printf( " PCM info error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf( " type - %i\n", pcminfo.type );
|
||||||
|
printf( " flags - 0x%x\n", pcminfo.flags );
|
||||||
|
printf( " id - '%s'\n", pcminfo.id );
|
||||||
|
printf( " name - '%s'\n", pcminfo.name );
|
||||||
|
}
|
||||||
|
for ( idx1 = 0; idx1 < info.mixerdevs; idx1++ ) {
|
||||||
|
printf( "MIXER info, device #%i:\n", idx1 );
|
||||||
|
if ( (err = snd_ctl_mixer_info( handle, idx1, &mixerinfo )) < 0 ) {
|
||||||
|
printf( " MIXER info error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf( " type - %i\n", mixerinfo.type );
|
||||||
|
printf( " channels - %i\n", mixerinfo.channels );
|
||||||
|
printf( " caps - 0x%x\n", mixerinfo.caps );
|
||||||
|
printf( " id - '%s'\n", mixerinfo.id );
|
||||||
|
printf( " name - '%s'\n", mixerinfo.name );
|
||||||
|
}
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
60
test/mixer.c
Normal file
60
test/mixer.c
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../include/soundlib.h"
|
||||||
|
|
||||||
|
static void mixer_test( int card, int device )
|
||||||
|
{
|
||||||
|
int err, channels;
|
||||||
|
void *handle;
|
||||||
|
snd_mixer_info_t info;
|
||||||
|
|
||||||
|
if ( (err = snd_mixer_open( &handle, card, device)) < 0 ) {
|
||||||
|
printf( "Mixer open error: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( "Mixer %i/%i open ok...\n", card, device );
|
||||||
|
channels = snd_mixer_channels( handle );
|
||||||
|
if ( channels < 0 ) {
|
||||||
|
printf( "Mixer channels error: %s\n", snd_strerror( channels ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( " Mixer have %i channel%s.\n", channels, channels > 1 ? "s" : "" );
|
||||||
|
if ( (err = snd_mixer_info( handle, &info )) < 0 ) {
|
||||||
|
printf( "Mixer info error: %s\n", snd_strerror( err ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf( " Info:\n" );
|
||||||
|
printf( " type - %i\n", info.type );
|
||||||
|
printf( " channels - %i\n", info.channels );
|
||||||
|
printf( " caps - 0x%x\n", info.caps );
|
||||||
|
printf( " id - '%s'\n", info.id );
|
||||||
|
printf( " name - '%s'\n", info.name );
|
||||||
|
snd_mixer_close( handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
int idx, idx1, cards, err;
|
||||||
|
void *handle;
|
||||||
|
struct snd_ctl_hw_info info;
|
||||||
|
|
||||||
|
cards = snd_cards();
|
||||||
|
printf( "Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "" );
|
||||||
|
if ( cards <= 0 ) {
|
||||||
|
printf( "Giving up...\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( idx = 0; idx < cards; idx++ ) {
|
||||||
|
if ( (err = snd_ctl_open( &handle, idx )) < 0 ) {
|
||||||
|
printf( "Open error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( (err = snd_ctl_hw_info( handle, &info )) < 0 ) {
|
||||||
|
printf( "HW info error: %s\n", snd_strerror( err ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for ( idx1 = 0; idx1 < info.mixerdevs; idx1++ )
|
||||||
|
mixer_test( idx, idx1 );
|
||||||
|
snd_ctl_close( handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
10
utils/Makefile
Normal file
10
utils/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#
|
||||||
|
# Makefile for ALSA library
|
||||||
|
# Copyright (c) 1994-98 by Jaroslav Kysela <perex@jcu.cz>
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../Makefile.conf
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core .depend *.o *.orig *~
|
||||||
|
|
||||||
77
utils/alsa-lib.spec
Normal file
77
utils/alsa-lib.spec
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
%define ver 0.0.9
|
||||||
|
%define rel 1
|
||||||
|
%define prefix /
|
||||||
|
|
||||||
|
Summary: Advanced Linux Sound Architecture (ALSA) - Library
|
||||||
|
Name: alsa-lib
|
||||||
|
Version: %ver
|
||||||
|
Release: %rel
|
||||||
|
Copyright: GPL
|
||||||
|
Group: System/Libraries
|
||||||
|
Source: ftp://alsa.jcu.cz/pub/lib/alsa-lib-%{ver}.tar.gz
|
||||||
|
BuildRoot: /tmp/alsa-lib-%{ver}
|
||||||
|
Packager: Helge Jensen <slog@slog.dk>
|
||||||
|
URL: http://alsa.jcu.cz
|
||||||
|
Docdir: %{prefix}/usr/doc
|
||||||
|
|
||||||
|
%description
|
||||||
|
|
||||||
|
Advanced Linux Sound Architecture (ALSA) - Library
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
|
||||||
|
* general
|
||||||
|
- modularized architecture with support for 2.0 and latest 2.1 kernels
|
||||||
|
- support for versioned and exported symbols
|
||||||
|
- full proc filesystem support - /proc/sound
|
||||||
|
* ISA soundcards
|
||||||
|
- support for 128k ISA DMA buffer
|
||||||
|
* mixer
|
||||||
|
- new enhanced API for applications
|
||||||
|
- support for unlimited number of channels
|
||||||
|
- volume can be set in three ways (percentual (0-100), exact and decibel)
|
||||||
|
- support for mute (and hardware mute if hardware supports it)
|
||||||
|
- support for mixer events
|
||||||
|
- this allows two or more applications to be synchronized
|
||||||
|
* digital audio (PCM)
|
||||||
|
- new enhanced API for applications
|
||||||
|
- full real duplex support
|
||||||
|
- full duplex support for SoundBlaster 16/AWE soundcards
|
||||||
|
- digital audio data for playback and record should be read back using
|
||||||
|
proc filesystem
|
||||||
|
* OSS/Lite compatibility
|
||||||
|
- full mixer compatibity
|
||||||
|
- full PCM (/dev/dsp) compatibility
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
|
||||||
|
* Mon May 28 1998 Helge Jensen <slog@slog.dk>
|
||||||
|
|
||||||
|
- Made SPEC file
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -n alsa-lib
|
||||||
|
%build
|
||||||
|
|
||||||
|
./configure --prefix=/usr
|
||||||
|
make
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/include/sys
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/lib
|
||||||
|
|
||||||
|
make prefix="$RPM_BUILD_ROOT/usr" install
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-, root, root)
|
||||||
|
|
||||||
|
%doc doc/*.html
|
||||||
|
%doc doc/*.sgml
|
||||||
|
%doc doc/*.txt
|
||||||
|
|
||||||
|
%{prefix}/usr/include/sys/soundlib.h
|
||||||
|
%{prefix}/usr/lib/lib*
|
||||||
78
utils/alsa-lib.spec.in
Normal file
78
utils/alsa-lib.spec.in
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
%define ver @SND_LIB_VERSION@
|
||||||
|
%define rel 1
|
||||||
|
%define prefix /
|
||||||
|
|
||||||
|
Summary: Advanced Linux Sound Architecture (ALSA) - Library
|
||||||
|
Name: alsa-lib
|
||||||
|
Version: %ver
|
||||||
|
Release: %rel
|
||||||
|
Copyright: GPL
|
||||||
|
Group: System/Libraries
|
||||||
|
Source: ftp://alsa.jcu.cz/pub/lib/alsa-lib-%{ver}.tar.gz
|
||||||
|
BuildRoot: /tmp/alsa-lib-%{ver}
|
||||||
|
Packager: Helge Jensen <slog@slog.dk>
|
||||||
|
URL: http://alsa.jcu.cz
|
||||||
|
Docdir: %{prefix}/usr/doc
|
||||||
|
Requires: alsa-driver
|
||||||
|
|
||||||
|
%description
|
||||||
|
|
||||||
|
Advanced Linux Sound Architecture (ALSA) - Library
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
|
||||||
|
* general
|
||||||
|
- modularized architecture with support for 2.0 and latest 2.1 kernels
|
||||||
|
- support for versioned and exported symbols
|
||||||
|
- full proc filesystem support - /proc/sound
|
||||||
|
* ISA soundcards
|
||||||
|
- support for 128k ISA DMA buffer
|
||||||
|
* mixer
|
||||||
|
- new enhanced API for applications
|
||||||
|
- support for unlimited number of channels
|
||||||
|
- volume can be set in three ways (percentual (0-100), exact and decibel)
|
||||||
|
- support for mute (and hardware mute if hardware supports it)
|
||||||
|
- support for mixer events
|
||||||
|
- this allows two or more applications to be synchronized
|
||||||
|
* digital audio (PCM)
|
||||||
|
- new enhanced API for applications
|
||||||
|
- full real duplex support
|
||||||
|
- full duplex support for SoundBlaster 16/AWE soundcards
|
||||||
|
- digital audio data for playback and record should be read back using
|
||||||
|
proc filesystem
|
||||||
|
* OSS/Lite compatibility
|
||||||
|
- full mixer compatibity
|
||||||
|
- full PCM (/dev/dsp) compatibility
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
|
||||||
|
* Mon May 28 1998 Helge Jensen <slog@slog.dk>
|
||||||
|
|
||||||
|
- Made SPEC file
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -n alsa-lib
|
||||||
|
%build
|
||||||
|
|
||||||
|
./configure --prefix=/usr
|
||||||
|
make
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/include/sys
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/lib
|
||||||
|
|
||||||
|
make prefix="$RPM_BUILD_ROOT/usr" install
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-, root, root)
|
||||||
|
|
||||||
|
%doc doc/*.html
|
||||||
|
%doc doc/*.sgml
|
||||||
|
%doc doc/*.txt
|
||||||
|
|
||||||
|
%{prefix}/usr/include/sys/soundlib.h
|
||||||
|
%{prefix}/usr/lib/lib*
|
||||||
35
utils/buildrpm
Normal file
35
utils/buildrpm
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source=.
|
||||||
|
version=`cat $source/../version`
|
||||||
|
package=$source/../../alsa-lib-$version.tar.gz
|
||||||
|
|
||||||
|
if [ ! -r $package ]; then
|
||||||
|
echo "Error: wrong package: $package"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
make -C .. pack
|
||||||
|
|
||||||
|
cp -fv $package /usr/src/redhat/SOURCES
|
||||||
|
|
||||||
|
if [ ! -r $source/buildrpm ]; then
|
||||||
|
echo "Error: invalid directory: $source"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d /usr/src/redhat ]; then
|
||||||
|
echo "Error: /usr/src/redhat directory not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -r $source/alsa-lib.spec ]; then
|
||||||
|
cd $source/..
|
||||||
|
./configure
|
||||||
|
cd utils
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -fv $source/alsa-lib.spec /usr/src/redhat/SPECS
|
||||||
|
cd /usr/src/redhat/SPECS
|
||||||
|
rpm -ba alsa-lib.spec
|
||||||
|
cd /usr/src/redhat
|
||||||
1
version
Normal file
1
version
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
0.0.9
|
||||||
Loading…
Add table
Add a link
Reference in a new issue