Priority: optional
Maintainer: Guillaume Pellerin <yomguy@altern.org>
Uploaders: Paul Brossier <piem@debian.org>
-Build-Depends: debhelper (>= 5.0.0), docbook-to-man, python (>= 2.4), cdbs (>= 0.4.42), python-setuptools (>= 0.6b3), python-support (>= 0.3), python-dev (>= 2.4)
-Standards-Version: 3.7.3
+Build-Depends: debhelper (>= 5.0.0), docbook-to-man, python (>= 2.4), cdbs (>= 0.4.42), python-setuptools (>= 0.6b3), python-support (>= 0.3), python-all-dev (>= 2.3.5-11)
+Standards-Version: 3.8.0
Package: telemeta
Architecture: any
-Depends: ${python:Depends}, python-xml, python-mutagen, python-django (>= 0.96.2), python-imaging (>= 1.1.6), sox, vorbis-tools, flac, normalize-audio, python-mysqldb, mysql-server, octave2.9, python-tk, libgd2-xpm, libsndfile1 (>= 1.0.17), python-numpy, python-ctypes (>= 1.0.1), python-audiolab (>= 0.7)
+Depends: ${python:Depends}, python-xml, python-mutagen, python-django (>= 0.96.1), python-imaging (>= 1.1.6), sox, vorbis-tools, flac, normalize-audio, python-mysqldb, mysql-server, octave2.9, python-tk, libgd2-xpm, libsndfile1 (>= 1.0.17), python-numpy, python-ctypes (>= 1.0.1), python-audiolab (>= 0.7)
Recommends: lame, vamp-examples
Suggests: ecasound, festival, par2
Description: web frontend to backup, transcode and tag any audio content with metadata
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/python-distutils.mk
-DEB_PYTHON_SETUP_CMD = setup.py
-DEB_COMPRESS_EXCLUDE := .pyc
+DEB_PYTHON_SETUP_CMD := setup.py
+DEB_COMPRESS_EXCLUDE := .pyc /.svn
+DEB_STRIP_EXCLUDE := .pyc /.svn
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- 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 Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-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 and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-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 other code 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.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- 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, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser 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.
-\f
- 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.
-\f
- 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.
-\f
- 6. As an exception to the Sections above, you may also combine 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) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) 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.
-
- d) 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.
-
- e) 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 materials to be 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.
-\f
- 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 with
-this License.
-\f
- 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 Lesser 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.
-\f
- 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
-\f
- 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 Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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!
-
-
+++ /dev/null
-audiolab (0.7) Sun, 09 Sep 2007 20:10:27 +0900
-
- * More robust wrapping of libsndfile: sf_file are objects pointers,
- the destructor checks that the handle already exists, and NULL
- pointers are better detected.
- * Add preliminary alsa version (not enabled yet).
- * Opening non existing files now throws meaningful exception.
-
-audiolab (0.7dev) Tue, 17 Jul 2007 12:03:41 +0900
-
- * Rename pyaudiolab to audiolab.
-
-pyaudiolab (0.7dev) Fri, 25 May 2007 16:00:24 +0900
-
- * Add the possibility to open an audio file from file descriptor
-
-pyaudiolab (0.7dev) Thu, 24 May 2007 13:34:11 +0900
-
- * Support for read and write seek
- * Set correct location of pysndfile.py in setup.py, so that it is
- correctly removed during setup.
-
-pyaudiolab (0.7dev) Tue, 22 May 2007 10:50:53 +0900
-
- * Relicense under the LGPL
- * Add data files with distutils instead of setuptools because of
- setuptools bug with sdist targets
-
-pyaudiolab (0.7dev) Mon, 21 May 2007 11:09:32 +0900
-
- * Convert the layout to scikits convention + setuptools
-
-pyaudiolab (0.6.7) Mon, 19 Mar 2007 15:19:10 +0900
-
- * Add some meta-data for setup.py
-
-pyaudiolab (0.6.7) Mon, 12 Mar 2007 15:48:12 +0900
-
- * Mainly Bug fixes for win32 and libsndfile without FLAC support.
- * Add a site.cfg.win32 + instructions in the doc to show how to use with
- win32.
- * Replace all remove functions in tests for temp files (Does not work
- under win32)
- * If FLAC is not supported, set flacread and flacwrite functions to None
- and catch exceptions related to unavailable FLAC support to avoid tests
- failing.
- * Replace non FLAC tests using FLAC files to WAV files.
-
-pyaudiolab (0.6.6dev) Mon, 05 Feb 2007 20:37:49 +0900
-
- * Add reader/writer factory to matlab-like API.
- * Generate au/wav/aiff/sdif/flac read/write functions
- with Matlab-like behaviour.
- * disable seek support for FLAC files by default, because of problems
- when using sf_seek(offset, SEEK_SET) with some FLAC versions.
-
-pyaudiolab (0.6.6dev) Mon, 05 Feb 2007 12:06:10 +0900
-
- * Change system to detect sndfile shared library file (based on
- sys.plaform instead of so_ext which does not seem to work on darwin at
- least).
-
-pyaudiolab (0.6.5) Fri, 02 Feb 2007 14:53:01 +0900
-
- * bump to 0.6.5
- * Add mechanism to automatic release+upload
- * release 0.6.5
-
-pyaudiolab (0.6.5dev) Fri, 02 Feb 2007 14:53:01 +0900
-
- * Put a proper LICENSE in COPYING.txt, and note in the README.txt
- that pyaudiolab depends on LGPL package
-
-pyaudiolab (0.6.5dev) Thu, 01 Feb 2007 15:06:51 +0900
-
- * Add int and short support for reading/writing
- * fix write and read such as float arguments for number of frames is
- possible + test.
- * Whenever a long long is expected by libsndfile, check that the number
- given by user is valid.
- * Give more meaningful error messages when bad parameters are given for
- opening a file for writing.
- * Give more meaningful error messages when trying to read a file opened
- only for writing.
- * Add examples scripts into doc/examples. Run them in test.sh
-
-pyaudiolab (0.6.1) Wed, 31 Jan 2007 16:03:02 +0900
-
- * Bump to 0.6.1
- * Change the name to pyaudiolab to avoid clashes with existing pyaudio
- toolboxes.
-
-pyaudio (0.6) Wed, 31 Jan 2007 14:32:41 +0900
-
- * Bump to 0.6.
- * Add support for seeking.
- * Add sync to sndfile to force flushing OS IO buffers to file without need
- to close.
- * read takes dtype argument instead of read_*_float, read_*_double.
- * wavread, wavwrite are working and similar to matlab's ones.
-
-pyaudio (0.5) Tue, 30 Jan 2007 14:40:36 +0900
-
- * Bump to 0.5
- * More explicit import error when used with bad ctypes
- * Add matlab-like functions wavread, wavwrite, aiffread, aiffwrite
- * Add API to have useful strings from format in sndfile class
-
-pyaudio (0.4) Mon, 06 Nov 2006 12:56:55 +0900
-
- * Bump to 0.4
- * replace c_longlong with c_int64; if ctypes does not support 64 bits
- integer, it will result in an import error instead of having c_longlong
- silently converted to 32 bits integer, which would result in difficult
- to trace bugs
- * add support for raw files (which requires a format, even for reading)
-
-pyaudio (0.3.1) Mon, 06 Nov 2006 12:56:55 +0900
-
- * Bump to 0.3.1
- * Check that samplerate and number of channels are int. If not,
- warn the user about potential unsafe conversion.
- * Move functions used to parse enum in header files into
- a other module, for easier sharing with other packages.
-
-pyaudio (0.3) Tue, 31 Oct 2006 21:38:46 +0900
-
- * Bump to 0.3
- * Added a class format, which can be used to open
- file for writing. The class hides all internal representation
- used by libsndfile, for a much saner API.
- * Various Bug fixes
-
-pyaudio (0.2) Mon, 30 Oct 2006 17:45:14 +0900
-
- * Bump to 0.2
- * Added a sndfile_info in setup.py for an automatic detection
- of sndfile under the installed system
- * mode is now a simple string in sndfile class ctor
+++ /dev/null
-ABOUT SEEK AND FLAC SUPPORT:
-
- audiolab supports flac, because libsndfile does. Unfortunately, some FLAC
-libraries seem buggy (at least the one with ubuntu Dapper is) with respect to
-their seek implementation. That's why by default, seeking in flac support is
-NOT enabled. If you want to test whether you FLAC library has the problem,
-compile the file badflac.c in the misc directory, eg on Linux:
-
-gcc -W -Wall badflac.c -lsndfile -o badflac
-
-and try running ./badflac ./badflac.flac. If the program looks locked up, this
-means you should NOT enable flac support. If it works OK, then you can enable
-seek support in audiolab by commenting the following lines in
-pysndfile.py.in (take care to modify the pysndfile.py.in, and not the
-pysndfile.py file), in sndfile.__init__ (around line 500):
-
-if self.get_file_format() == 'flac':
- def SeekNotEnabled(self, *args):
- raise FlacUnsupported("seek not supported on Flac by default, because"\
- "\n some version of FLAC libraries are buggy. Read FLAC_SUPPORT.txt")
- self.seek = SeekNotEnabled
-
-Then install the package.
-
-The pre releases version 1.0.18pre7 of libsndfile is known to work, libsndfile
-1.0.17 and 1.0.16 known NOT to work (those version rely on an installed FLAC
-library, whether starting from 1.0.18, libsndfile will include the FLAC library
-instead of using an externally supplied one).
+++ /dev/null
-Suported platforms:
--------------------
-
-audiolab has been successfully run and tested on the following platforms:
-
- - windows
- - mac OS X (intel and ppc)
- - linux (intel and ppc).
-
-This may work on other platforms: in particular, I expect the package to work
-on most recent Unices.
-
-Requirements
-------------
-
-To run correctly, audiolab requires the following softwares:
-
- - python (> 2.3): http://www.python.org
- - setuptools:
- http://peak.telecommunity.com/DevCenter/setuptools#installing-setuptools
- - ctypes (included in python starting from version 2.5)
- - numpy: http://www.scipy.org/Numpy
- - libsndfile: http://www.mega-nerd.com/libsndfile/
-
-On Ubuntu, you can ensure to get the necessary packages by doing apt-get
-install python python-setuptools libsndfile-dev python-numpy
-
-Installing
-----------
-
-Installing is easy: once in the audiolab directory, simply do: python setup.py
-install. If the installation failed because libsndfile was not found, check
-that you have correctly installed libsndfile, including its headers
-(sndfile.h). On windows, as there is no standard for 3rd party libraries and
-header location, you can put them wherever you want, as long as the
-corresponding directories are in site.cfg (see site.cfg.win32 for an example).
+++ /dev/null
-include scikits/audiolab/pysndfile.py.in
-include site.cfg
-include site.cfg.win32
-include COPYING.txt
-include FLAC_SUPPORT.txt
-include header_parser.py
-include generate_const.py
+++ /dev/null
-# Last Change: Tue Jul 17 11:00 AM 2007 J
-#
-# This makefile is used to do all the "tricky things" before a release,
-# including updating the doc, installing and testing the package, uploading the
-# release to the website, etc...
-#
-# TODO: not fake dependencies....
-
-PKG_VER = $(shell cat scikits/audiolab/info.py | grep __version__ | tr -s " " | cut -f 3 -d" " \
- | cut -f 2 -d\')
-
-BASEPATH = $(PWD)
-DATAPATH = $(PWD)/scikits/audiolab/test_data/
-DOCPATH = $(PWD)/scikits/audiolab/docs/
-EXAMPATH = $(DOCPATH)/examples
-
-SCIPYPATH = $(HOME)/local/lib/python2.5/site-packages
-TMPPATH = $(CURDIR)/../tmp
-
-PYTHONCMD = PYTHONPATH=$(TMPPATH)/lib/python2.5/site-packages:$(SCIPYPATH) python -c
-PYTHONRUN = PYTHONPATH=$(TMPPATH)/lib/python2.5/site-packages:$(SCIPYPATH) python
-
-RELEASELOC = $(WWWHOMEDIR)/archives/audiolab/releases
-
-do_release: clean src examples tests
-
-release: do_release upload_release
-
-upload_release: dist/audiolab-$(PKG_VER).tar.gz \
- dist/audiolab-$(PKG_VER).tar.bz2 \
- dist/audiolab-$(PKG_VER).zip
- @echo "Uploading version $(PKG_VER) ..."
- @read n
- rcp dist/audiolab-$(PKG_VER).tar.gz $(RELEASELOC)
- rcp dist/audiolab-$(PKG_VER).tar.bz2 $(RELEASELOC)
- rcp dist/audiolab-$(PKG_VER).zip $(RELEASELOC)
-
-src: build_src
-
-build_src: dist/audiolab-$(PKG_VER).tar.gz \
- dist/audiolab-$(PKG_VER).tar.bz2 \
- dist/audiolab-$(PKG_VER).zip
-
-dist/audiolab-$(PKG_VER).tar.gz: doc
- python setup.py sdist --format=gztar
-
-dist/audiolab-$(PKG_VER).zip: doc
- python setup.py sdist --format=zip
-
-dist/audiolab-$(PKG_VER).tar.bz2: doc
- python setup.py sdist --format=bztar
-
-#=======================================================
-# Code related to building audiolab in a tmp directory
-#=======================================================
-# Install the package in a tmp directory
-$(TMPPATH): build_test
-
-build_test:
- $(PYTHONRUN) setup.py install --prefix=$(TMPPATH)
-
-# Clean the tmp dir
-clean_before_run:
- rm -rf $(TMPPATH)
-
-#===========================
-# Code related to examples
-#===========================
-examples: run_examples
-
-# Run examples in docs/examples
-run_examples: $(TMPPATH)
- #for i in $(BASEPATH)/docs/examples/*.py; do\
- # echo "========== runing example $$i ==========";\
- # $(PYTHONRUN) $$i; \
- #done;
- # Why when using the above loop, Make does not stop when one script fails ?
- @echo "---------- runing example quick1.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/quick1.py
- @echo "---------- runing example usage1.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/usage1.py
- @echo "---------- runing example usage2.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/usage2.py
- @echo "---------- runing example format1.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/format1.py
- @echo "---------- runing example format2.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/format2.py
- @echo "---------- runing example write1.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/write1.py
- @echo "---------- runing example matlab1.py ----------";
- cd $(DATAPATH) && $(PYTHONRUN) $(EXAMPATH)/matlab1.py
-
-#=====================
-# Code related to test
-#=====================
-tests: run_tests examples
- @echo "=================================="
- @echo " RELEASE $(PKG_VER) IS OK !"
- @echo "=================================="
-
-# Run all tests
-run_tests: $(TMPPATH)
- @echo "=============== running test ============"
- cd .. && $(PYTHONCMD) "import scikits.audiolab as audiolab; print audiolab; audiolab.test()"
- @echo "=============== Done ============"
-
-#=====================
-# Code related to doc
-#=====================
-doc:
- cd $(DOCPATH) && $(MAKE)
-
-clean: clean_before_run
- cd $(DOCPATH) && $(MAKE) clean
+++ /dev/null
-audiolab: a small toolbox to read, write and play audio to and from
-numpy arrays.
-
-audiolab provides two API:
- - one similar to matlab: this gives you wavread/wavwrite/auread/auwrite
- functions similar to matlab's ones.
- - a more complete API, which can be used to read, write to many audio files
- (including wav, aiff, flac, au, IRCAM, htk, etc...), with IO capabilities
- not available to matlab (seek, append data, etc...)
-
-It is a thin wrapper around libsndfile from Erik Castro Lopo.
-
-See the docs directory for more details
-
-LICENSE:
-
-audiolab itself is licensed under the LGPL license
-(see COPYING.txt in main source directory)
-
-audiolab depends on libsndfile to work; libsndfile is licensed under LGPL.
-
-See http://www.mega-nerd.com/libsndfile/ for details.
+++ /dev/null
-.. vim:syntax=rest
-
-Things to do before a release
------------------------------
- - better error reporting (support error logging of sndfile ?): the
- exceptions launched are pretty random...
- - add inout argument in read method to avoid recreating a buffer.
- - more tests
- - add an audio player for at least linux/windows/mac os x (0.8-0.9) -> This
- will be done in a different branch
-
-Pending issues
---------------
- - There is no check for supported format, the way get_supported_format is
- implemented now it totally broken. Instead of using values from the
- header, should use sf_command
- - removing most warning from pylint
- - handling in audiolab when first is not 0 (now, we have seek :))
-
-Maybe ?
--------
- - change array layout convention to numpy's ones (eg row major, not column
- major), and add an axis argument. -> this is a bit tricky, actually, as
- sndfile only supports interleaved data, where F order actually make sense.
- Not sure what to do
- - ogg vorbis support ? libsndfile does not support ogg (yet). Maybe use the
- reference lib, but this may be a bit complicated to support both library
- at the same time.
+++ /dev/null
-#! /bin/sh
-# Last Change: Fri May 25 10:00 AM 2007 J
-EPYDOCOPTS="--latex -v --no-private --exclude test_*"
-PYTHONPATH=/home/david/local/lib/python2.5/site-packages/ /home/david/local/bin/epydoc $EPYDOCOPTS scikits/pyaudiolab/
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Thu May 24 02:00 PM 2007 J
-
-# David Cournapeau 2006
-
-# TODO:
-# args with the header file to extract info from
-
-from header_parser import get_dict, put_dict_file
-
-def generate_enum_dicts(header = '/usr/include/sndfile.h'):
- # Open the file and get the content, without trailing '\n'
- hdct = [i.split('\n')[0] for i in open(header, 'r').readlines()]
-
- # Get sf boolean
- sf_bool = {}
- nameregex = '(SF_FALSE)'
- sf = get_dict(hdct, nameregex)
- sf_bool['SF_FALSE'] = sf['SF_FALSE']
- nameregex = '(SF_TRUE)'
- sf = get_dict(hdct, nameregex)
- sf_bool['SF_TRUE'] = sf['SF_TRUE']
-
- # Get mode constants
- nameregex = '(SFM_[\S]*)'
- sfm = get_dict(hdct, nameregex)
-
- # Get format constants
- nameregex = '(SF_FORMAT_[\S]*)'
- sf_format = get_dict(hdct, nameregex)
-
- # Get endianness
- nameregex = '(SF_ENDIAN_[\S]*)'
- sf_endian = get_dict(hdct, nameregex)
-
- # Get command constants
- nameregex = '(SFC_[\S]*)'
- sf_command = get_dict(hdct, nameregex)
-
- # Get (public) errors
- nameregex = '(SF_ERR_[\S]*)'
- sf_errors = get_dict(hdct, nameregex)
-
- # Replace dict:
- repdict = {
- '%SFM%' : put_dict_file(sfm, 'SFM'),
- '%SF_BOOL%' : put_dict_file(sf_bool, 'SF_BOOL'),
- '%SF_FORMAT%' : put_dict_file(sf_format, 'SF_FORMAT'),
- '%SF_ENDIAN%' : put_dict_file(sf_endian, 'SF_ENDIAN'),
- '%SF_COMMAND%' : put_dict_file(sf_command, 'SF_COMMAND'),
- '%SF_ERR%' : put_dict_file(sf_errors, 'SF_ERRORS')
- }
-
- return repdict
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Thu Nov 02 12:00 PM 2006 J
-
-# Small module to parse header files, and other tools to use libraries with ctype
-# David Cournapeau 2006
-
-import re
-
-def get_dict(content, nameregex, valueregex = '([ABCDEF\dx]*)'):
- """Read the content of a header file, parse for a regex nameregex,
- and get the corresponding value (HEX values 0x by default)
-
- This is useful to parse enumerations in header files"""
- sf_dict = {}
- regex = re.compile(nameregex + '[\s]*= ' + valueregex)
- for i in content:
- m = regex.search(i)
- if m:
- sf_dict[m.group(1)] = m.group(2)
- return sf_dict
-
-def put_dict_file(dict, name):
- items = dict.items()
- string = name + ' = {\n\t' + '\'' + items[0][0] + '\'\t: ' + items[0][1]
- for i in range(1, len(items)):
- #print "Putting key %s, value %s" % (items[i][0], items[i][1])
- string += ',\n\t\'' + items[i][0] + '\'\t: ' + items[i][1]
- string += '\n}'
- return string
-
-# Functions used to substitute values in File.
-# Kind of like config.h and autotools
-import re
-def do_subst_in_file(sourcefile, targetfile, dict):
- """Replace all instances of the keys of dict with their values.
- For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
- then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
- """
- #print "sourcefile is %s, target is %s" % (sourcefile, targetfile)
- f = open(sourcefile, 'rb')
- contents = f.read()
- f.close()
-
- for (k,v) in dict.items():
- contents = re.sub(k, v, contents)
-
- f = open(targetfile, 'wb')
- f.write(contents)
- f.close()
-
+++ /dev/null
-Metadata-Version: 1.0
-Name: scikits.audiolab
-Version: 0.8dev.dev
-Summary: A python module to make noise from numpy arrays
-Home-page: http://www.ar.media.kyoto-u.ac.jp/members/david/softwares/audiolab
-Author: David Cournapeau
-Author-email: david@ar.media.kyoto-u.ac.jp
-License: LGPL
-Download-URL: http://www.ar.media.kyoto-u.ac.jp/members/david/softwares/audiolab
-Description: audiolab is a small python package to import data from audio
- files to numpy arrays and export data from numpy arrays to audio files. It uses
- libsndfile from Erik Castro de Lopo for the underlying IO, which supports many
- different audio formats: http://www.mega-nerd.com/libsndfile/
-
- For now, the python api for audio IO should be stable; a matlab-like API is
- also available for quick read/write (ala wavread, wavwrite, etc...). For 1.0
- release, I hope to add support for simple read/write to soundcard, to be able
- to record and listen to data in numpy arrays.
-
- 2006-2007, David Cournapeau
-
- LICENSE: audiolab is licensed under the LGPL, as is libsndfile itself. See
- COPYING.txt for details.
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Environment :: Console
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: Science/Research
-Classifier: License :: OSI Approved :: LGPL License
-Classifier: Topic :: Multimedia :: Sound/Audio
-Classifier: Topic :: Scientific/Engineering
+++ /dev/null
-COPYING.txt
-Changelog
-FLAC_SUPPORT.txt
-INSTALL.txt
-MANIFEST.in
-Makefile
-README.txt
-TODO
-generate.sh
-generate_const.py
-header_parser.py
-setup.cfg
-setup.py
-site.cfg.win32
-site.cfg_noflac
-tester.py
-scikits/__init__.py
-scikits.audiolab.egg-info/PKG-INFO
-scikits.audiolab.egg-info/SOURCES.txt
-scikits.audiolab.egg-info/dependency_links.txt
-scikits.audiolab.egg-info/namespace_packages.txt
-scikits.audiolab.egg-info/requires.txt
-scikits.audiolab.egg-info/top_level.txt
-scikits.audiolab.egg-info/zip-safe
-scikits/audiolab/__init__.py
-scikits/audiolab/info.py
-scikits/audiolab/matapi.py
-scikits/audiolab/pyaudioio.py
-scikits/audiolab/pysndfile.py
-scikits/audiolab/pysndfile.py.in
-scikits/audiolab/docs/Makefile
-scikits/audiolab/docs/audiolab1.png
-scikits/audiolab/docs/base.tex
-scikits/audiolab/docs/index.txt
-scikits/audiolab/docs/user.tex
-scikits/audiolab/docs/examples/format1.py
-scikits/audiolab/docs/examples/format2.py
-scikits/audiolab/docs/examples/matlab1.py
-scikits/audiolab/docs/examples/quick1.py
-scikits/audiolab/docs/examples/usage1.py
-scikits/audiolab/docs/examples/usage2.py
-scikits/audiolab/docs/examples/write1.py
-scikits/audiolab/misc/Makefile
-scikits/audiolab/misc/Sconstruct
-scikits/audiolab/misc/badflac.c
-scikits/audiolab/misc/badflac.flac
-scikits/audiolab/misc/winfdopen.c
-scikits/audiolab/soundio/SConstruct
-scikits/audiolab/soundio/_alsa.pyx
-scikits/audiolab/soundio/alsa.py
-scikits/audiolab/soundio/alsa_ctypes.py
-scikits/audiolab/soundio/setup.py
-scikits/audiolab/soundio/simple.c
-scikits/audiolab/soundio/simple2.c
-scikits/audiolab/test_data/original.aif
-scikits/audiolab/test_data/test.aiff
-scikits/audiolab/test_data/test.au
-scikits/audiolab/test_data/test.flac
-scikits/audiolab/test_data/test.raw
-scikits/audiolab/test_data/test.sdif
-scikits/audiolab/test_data/test.wav
-scikits/audiolab/tests/__init__.py
-scikits/audiolab/tests/test_matapi.py
-scikits/audiolab/tests/test_pysndfile.py
-scikits/audiolab/tests/testcommon.py
\ No newline at end of file
+++ /dev/null
-numpy
\ No newline at end of file
+++ /dev/null
-__import__('pkg_resources').declare_namespace(__name__)
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Mon Sep 10 07:00 PM 2007 J
-"""
-audiolab: a small toolbox to read, write and play audio to and from
-numpy arrays.
-
-audiolab provides two API:
- - one similar to matlab: this gives you wavread, wavwrite functions really
- similar to matlab's functions.
- - a more complete API, which can be used to read, write to many audio file
- (including wav, aiff, flac, au, IRCAM, htk, etc...), with IO capabilities
- not available to matlab (seek, append data, etc...)
-
-It is a thin wrapper around libsndfile from Erik Castro Lopo.
-
-Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-
-LICENSE: audiolab is licensed under the LGPL, as is libsndfile itself. See
-COPYING.txt for details. """
-
-from info import VERSION
-__version__ = VERSION
-
-from pysndfile import formatinfo, sndfile
-from pysndfile import supported_format, supported_endianness, \
- supported_encoding
-#from scikits.audiolab.matapi import wavread, aiffread, flacread, auread, \
-# sdifread, wavwrite, aiffwrite, flacwrite, auwrite, sdifwrite
-from matapi import *
-
-__all__ = filter(lambda s:not s.startswith('_'),dir())
-
-from numpy.testing import NumpyTest
-def test():
- return NumpyTest().test()
+++ /dev/null
-py2tex = PYTHONPATH=/home/david/local/lib/python2.5/site-packages pygmentize -l python -f tex
-rst2tex = PYTHONPATH=/home/david/local/lib/python2.5/site-packages rst2newlatex.py \
- --stylesheet-path base.tex --user-stylesheet user.tex
-
-pytexfiles = audiolab.tex quick1.tex \
- usage1.tex \
- usage2.tex \
- format1.tex \
- format2.tex \
- write1.tex \
- matlab1.tex
-
-SOURCEPATH = $(PWD)
-
-EXTTOCLEAN=.chk .dvi .log .aux .bbl .blg .blig .ilg .toc .lof .lot .idx .ind .out .bak .ps .pdf .bm
-
-audiolab.pdf: $(pytexfiles)
- pdflatex $<
- pdflatex $<
- pdflatex $<
-
-audiolab.tex: index.txt
- $(rst2tex) $< > $@
-
-quick1.tex: examples/quick1.py
- $(py2tex) $< > $@
-
-usage1.tex: examples/usage1.py
- $(py2tex) $< > $@
-
-usage2.tex: examples/usage2.py
- $(py2tex) $< > $@
-
-format1.tex: examples/format1.py
- $(py2tex) $< > $@
-
-format2.tex: examples/format2.py
- $(py2tex) $< > $@
-
-write1.tex: examples/write1.py
- $(py2tex) $< > $@
-
-matlab1.tex: examples/matlab1.py
- $(py2tex) $< > $@
-
-clean:
- for i in $(pytexfiles); do \
- rm -f `echo $$i`; \
- done;
- for i in $(SOURCEPATH); do \
- for j in $(EXTTOCLEAN); do \
- rm -f `echo $$i/*$$j`; \
- done; \
- done;
+++ /dev/null
-% System stylesheet for the new LaTeX writer, newlatex2e.
-
-% Major parts of the rendering are done in this stylesheet and not in the
-% Python module.
-
-% For development notes, see notes.txt.
-
-% User documentation (in the stylesheet for now; that may change though):
-
-% Naming conventions:
-% All uppercase letters in macro names have a specific meaning.
-% \D...: All macros introduced by the Docutils LaTeX writer start with "D".
-% \DS<name>: Setup function (called at the bottom of this stylesheet).
-% \DN<nodename>{<contents>}: Handler for Docutils document tree node `node`; called by
-% the Python module.
-% \DEV<name>: External variable, set by the Python module.
-% \DEC<name>: External command. It is called by the Python module and must be
-% defined in this stylesheet.
-% \DN<nodename>A<attribute>{<number>}{<attribute>}{<value>}{<nodename>}{<contents>}:
-% Attribute handler for `attribute` set on nodes of type `nodename`.
-% See below for a discussion of attribute handlers.
-% \DA<attribute>{<number>}{<attribute>}{<value>}{<nodename>}{<contents>}:
-% Attribute handler for all `attribute`. Called only when no specific
-% \DN<nodename>A<attribute> handler is defined.
-% \DN<nodename>C<class>{<contents>}:
-% Handler for `class`, when set on nodes of type `nodename`.
-% \DC<class>{<contents>}:
-% Handler for `class`. Called only when no specific \DN<nodename>C<class>
-% handler is defined.
-% \D<name>: Generic variable or function.
-
-% Attribute handlers:
-% TODO
-
-% ---------------------------------------------------------------------------
-
-% Having to intersperse code with \makeatletter-\makeatother pairs is very
-% annoying, so we call \makeatletter at the top and \makeatother at the
-% bottom. Just be aware that you cannot use "@" as a text character inside
-% this stylesheet.
-\makeatletter
-
-% Print-mode (as opposed to online mode e.g. with Adobe Reader).
-% This causes for example blue hyperlinks.
-\providecommand{\Dprinting}{false}
-
-% \DSearly is called right after \documentclass.
-\providecommand{\DSearly}{}
-% \DSlate is called at the end of the stylesheet (right before the document
-% tree).
-\providecommand{\DSlate}{}
-
-% Use the KOMA script article class.
-\providecommand{\Ddocumentclass}{scrartcl}
-\providecommand{\Ddocumentoptions}{a4paper}
-\providecommand{\DSdocumentclass}{
- \documentclass[\Ddocumentoptions]{\Ddocumentclass} }
-
-% Todo: This should be movable to the bottom, but it isn't as long as
-% we use \usepackage commands at the top level of this stylesheet
-% (which we shouldn't).
-\DSdocumentclass
-
-\providecommand{\DSpackages}{
- % Load miscellaneous packages.
- % Note 1: Many of the packages loaded here are used throughout this stylesheet.
- % If one of these packages does not work on your system or in your scenario,
- % please let us know, so we can consider making the package optional.
- % Note 2: It would appear cleaner to load packages where they are used.
- % However, since using a wrong package loading order can lead to *very*
- % subtle bugs, we centralize the loading of most packages here.
- \DSfontencoding % load font encoding packages
- \DSlanguage % load babel
- % Using \ifthenelse conditionals.
- \usepackage{ifthen} % before hyperref (really!)
- % There is not support for *not* using hyperref because it's used in many
- % places. If this is a problem (e.g. because hyperref doesn't work on your
- % system), please let us know.
- \usepackage[colorlinks=false,pdfborder={0 0 0}]{hyperref}
- % Get color, e.g. for links and system messages.
- \usepackage{color}
- % Get \textnhtt macro (non-hyphenating type writer).
- \usepackage{hyphenat}
- % For sidebars.
- \usepackage{picins}
- % We use longtable to create tables.
- \usepackage{longtable}
- % Images.
- \usepackage{graphicx}
- % These packages might be useful (some just add magic pixie dust), so
- % evaluate them:
- %\usepackage{fixmath}
- %\usepackage{amsmath}
- % Add some missing symbols like \textonehalf.
- \usepackage{textcomp}
-}
-
-\providecommand{\DSfontencoding}{
- % Set up font encoding. Called by \DSpackages.
- % AE is a T1 emulation. It provides mostly the same characters and
- % features as T1-encoded fonts but doesn't use bitmap fonts (which are
- % unsuitable for online reading and subtle for printers).
- \usepackage{ae}
- % Provide the characters not contained in AE from EC bitmap fonts.
- \usepackage{aecompl}
- % Guillemets ("<<", ">>") in AE.
- \usepackage{aeguill}
-}
-
-\providecommand{\DSsymbols}{%
- % Fix up symbols.
- % The Euro symbol in Computer Modern looks, um, funny. Let's get a
- % proper Euro symbol.
- \usepackage{eurosym}%
- \renewcommand{\texteuro}{\euro}%
-}
-
-% Taken from
-% <http://groups.google.de/groups?selm=1i0n5tgtplti420e1omp4pctlv19jpuhbb%404ax.com>
-% and modified. Used with permission.
-\providecommand{\Dprovidelength}[2]{%
- \begingroup%
- \escapechar\m@ne%
- \xdef\@gtempa{{\string#1}}%
- \endgroup%
- \expandafter\@ifundefined\@gtempa%
- {\newlength{#1}\setlength{#1}{#2}}%
- {}%
-}
-
-\providecommand{\Dprovidecounter}[2]{%
- % Like \newcounter except that it doesn't crash if the counter
- % already exists.
- \@ifundefined{c@#1}{\newcounter{#1}\setcounter{#1}{#2}}{}
-}
-
-\Dprovidelength{\Dboxparindent}{\parindent}
-
-\providecommand{\Dmakebox}[1]{%
- % Make a centered, frameless box. Useful e.g. for block quotes.
- % Do not use minipages here, but create pseudo-lists to allow
- % page-breaking. (Don't use KOMA-script's addmargin environment
- % because it messes up bullet lists.)
- \Dmakelistenvironment{}{}{%
- \setlength{\parskip}{0pt}%
- \setlength{\parindent}{\Dboxparindent}%
- \item{#1}%
- }%
-}
-
-\providecommand{\Dmakefbox}[1]{%
- % Make a centered, framed box. Useful e.g. for admonitions.
- \vspace{0.4\baselineskip}%
- \begin{center}%
- \fbox{%
- \begin{minipage}[t]{0.9\linewidth}%
- \setlength{\parindent}{\Dboxparindent}%
- #1%
- \end{minipage}%
- }%
- \end{center}%
- \vspace{0.4\baselineskip}%
-}
-
-% We do not currently recognize the difference between an end-sentence and a
-% mid-sentence period (". " vs. ". " in plain text). So \frenchspacing is
-% appropriate.
-\providecommand{\DSfrenchspacing}{\frenchspacing}
-
-
-\Dprovidelength{\Dblocklevelvspace}{%
- % Space between block-level elements other than paragraphs.
- 0.7\baselineskip plus 0.3\baselineskip minus 0.2\baselineskip%
-}
-\providecommand{\DECauxiliaryspace}{%
- \ifthenelse{\equal{\Dneedvspace}{true}}{\vspace{\Dblocklevelvspace}}{}%
- \par\noindent%
-}
-\providecommand{\DECparagraphspace}{\par}
-\providecommand{\Dneedvspace}{true}
-
-\providecommand{\DSlanguage}{%
- % Set up babel.
- \usepackage[\DEVlanguagebabel]{babel}
-}
-
-\providecommand{\Difdefined}[3]{\@ifundefined{#1}{#3}{#2}}
-
-% Handler for 'classes' attribute (called for each class attribute).
-\providecommand{\DAclasses}[5]{%
- % Dispatch to \DN<nodename>C<class>.
- \Difdefined{DN#4C#3}{%
- % Pass only contents, nothing else!
- \csname DN#4C#3\endcsname{#5}%
- }{%
- % Otherwise, dispatch to \DC<class>.
- \Difdefined{DC#3}{%
- \csname DC#3\endcsname{#5}%
- }{%
- #5%
- }%
- }%
-}
-
-\providecommand{\DECattr}[5]{%
- % Global attribute dispatcher, called inside the document tree.
- % Parameters:
- % 1. Attribute number.
- % 2. Attribute name.
- % 3. Attribute value.
- % 4. Node name.
- % 5. Node contents.
- \Difdefined{DN#4A#2}{%
- % Dispatch to \DN<nodename>A<attribute>.
- \csname DN#4A#2\endcsname{#1}{#2}{#3}{#4}{#5}%
- }{\Difdefined{DA#2}{%
- % Otherwise dispatch to \DA<attribute>.
- \csname DA#2\endcsname{#1}{#2}{#3}{#4}{#5}%
- }{%
- % Otherwise simply run the contents without calling a handler.
- #5%
- }}%
-}
-
-% ---------- Link handling ----------
-% Targets and references.
-
-\providecommand{\Draisedlink}[1]{%
- % Anchors are placed on the base line by default. This is a bad thing for
- % inline context, so we raise the anchor (normally by \baselineskip).
- \Hy@raisedlink{#1}%
-}
-
-% References.
-% We're assuming here that the "refid" and "refuri" attributes occur
-% only in inline context (in TextElements).
-\providecommand{\DArefid}[5]{%
- \ifthenelse{\equal{#4}{reference}}{%
- \Dexplicitreference{\##3}{#5}%
- }{%
- % If this is not a target node (targets with refids are
- % uninteresting and should be silently dropped).
- \ifthenelse{\not\equal{#4}{target}}{%
- % If this is a footnote reference, call special macro.
- \ifthenelse{\equal{#4}{footnotereference}}{%
- \Dimplicitfootnotereference{\##3}{#5}%
- }{%
- \ifthenelse{\equal{#4}{citationreference}}{%
- \Dimplicitcitationreference{\##3}{#5}%
- }{%
- \Dimplicitreference{\##3}{#5}%
- }%
- }%
- }{}%
- }%
-}
-\providecommand{\DArefuri}[5]{%
- \ifthenelse{\equal{#4}{target}}{%
- % The node name is 'target', so this is a hyperlink target, like this:
- % .. _mytarget: URI
- % Hyperlink targets are ignored because they are invisible.
- }{%
- % If a non-target node has a refuri attribute, it must be an explicit URI
- % reference (i.e. node name is 'reference').
- \Durireference{#3}{#5}%
- }%
-}
-% Targets.
-\providecommand{\DAids}[5]{%
- \label{#3}%
- \ifthenelse{\equal{#4}{footnotereference}}{%
- {%
- \renewcommand{\HyperRaiseLinkDefault}{%
- % Dirty hack to make backrefs to footnote references work.
- % For some reason, \baselineskip is 0pt in fn references.
- 0.5\Doriginalbaselineskip%
- }%
- \Draisedlink{\hypertarget{#3}{}}#5%
- }%
- }{%
- \Draisedlink{\hypertarget{#3}{}}#5%
- }%
-}
-\providecommand{\Dimplicitreference}[2]{%
- % Create implicit reference to ID. Implicit references occur
- % e.g. in TOC-backlinks of section titles. Parameters:
- % 1. Target.
- % 2. Link text.
- \href{#1}{#2}%
-}
-\providecommand{\Dimplicitfootnotereference}[2]{%
- % Ditto, but for the special case of footnotes.
- % We want them to be rendered like explicit references.
- \Dexplicitreference{#1}{#2}%
-}
-\providecommand{\Dimplicitcitationreference}[2]{%
- % Ditto for citation references.
- \Dimplicitfootnotereference{#1}{#2}%
-}
-\providecommand{\Dcolorexplicitreference}{%
- \ifthenelse{\equal{\Dprinting}{true}}{\color{black}}{\color{blue}}%
-}
-\providecommand{\Dexplicitreference}[2]{%
- % Create explicit reference to ID, e.g. created with "foo_".
- % Parameters:
- % 1. Target.
- % 2. Link text.
- \href{#1}{{\Dcolorexplicitreference#2}}%
-}
-\providecommand{\Dcolorurireference}{\Dcolorexplicitreference}
-\providecommand{\Durireference}[2]{%
- % Create reference to URI. Parameters:
- % 1. Target.
- % 2. Link text.
- \href{#1}{{\Dcolorurireference#2}}%
-}
-
-\Dprovidecounter{Dpdfbookmarkid}{0}%
-\providecommand{\Dpdfbookmark}[1]{%
- % Temporarily decrement Desctionlevel counter.
- \addtocounter{Dsectionlevel}{-1}%
- %\typeout{\arabic{Dsectionlevel}}%
- %\typeout{#1}%
- %\typeout{docutils\roman{Dpdfbookmarkid}}%
- %\typeout{}%
- \pdfbookmark[\arabic{Dsectionlevel}]{#1}{docutils\arabic{Dpdfbookmarkid}}%
- \addtocounter{Dsectionlevel}{1}%
- \addtocounter{Dpdfbookmarkid}{1}%
-}
-% ---------- End of Link Handling ----------
-
-\providecommand{\DNparagraph}[1]{%
- \ifthenelse{\equal{\DEVparagraphindented}{true}}{\indent}{\noindent}%
- #1%
-}
-\providecommand{\Dformatboxtitle}[1]{{\Large\textbf{#1}}}
-\providecommand{\Dformatboxsubtitle}[1]{{\large\textbf{#1}}}
-\providecommand{\Dtopictitle}[1]{%
- \Difinsidetoc{\vspace{1em}\par}{}%
- \noindent\Dformatboxtitle{#1}%
- \ifthenelse{\equal{\DEVhassubtitle}{false}}{\vspace{1em}}{\vspace{0.5em}}%
- \par%
-}
-\providecommand{\Dadmonitiontitle}[1]{%
- \Dtopictitle{#1}%
-}
-\providecommand{\Dtopicsubtitle}[1]{%
- \noindent\Dformatboxsubtitle{#1}%
- \vspace{1em}%
- \par%
-}
-\providecommand{\Dsidebartitle}[1]{\Dtopictitle{#1}}
-\providecommand{\Dsidebarsubtitle}[1]{\Dtopicsubtitle{#1}}
-\providecommand{\Ddocumenttitle}[1]{%
- \begin{center}{\Huge#1}\end{center}%
- \ifthenelse{\equal{\DEVhassubtitle}{true}}{\vspace{0.1cm}}{\vspace{1cm}}%
-}
-\providecommand{\Ddocumentsubtitle}[1]{%
- \begin{center}{\huge#1}\end{center}%
- \vspace{1cm}%
-}
-% Can be overwritten by user stylesheet.
-\providecommand{\Dformatsectiontitle}[1]{#1}
-\providecommand{\Dformatsectionsubtitle}[1]{\Dformatsectiontitle{#1}}
-\providecommand{\Dbookmarksectiontitle}[1]{%
- % Return text suitable for use in \section*, \subsection*, etc.,
- % containing a PDF bookmark. Parameter: The title (as node tree).
- \Draisedlink{\Dpdfbookmark{\DEVtitleastext}}%
- #1%
-}
-\providecommand{\Dsectiontitlehook}[1]{#1}
-\providecommand{\Dsectiontitle}[1]{%
- \Dsectiontitlehook{%
- \Ddispatchsectiontitle{\Dbookmarksectiontitle{\Dformatsectiontitle{#1}}}%
- }%
-}
-\providecommand{\Ddispatchsectiontitle}[1]{%
- \@ifundefined{Dsectiontitle\roman{Dsectionlevel}}{%
- \Ddeepsectiontitle{#1}%
- }{%
- \csname Dsectiontitle\roman{Dsectionlevel}\endcsname{#1}%
- }%
-}
-\providecommand{\Ddispatchsectionsubtitle}[1]{%
- \Ddispatchsectiontitle{#1}%
-}
-\providecommand{\Dsectiontitlei}[1]{\section*{#1}}
-\providecommand{\Dsectiontitleii}[1]{\subsection*{#1}}
-\providecommand{\Ddeepsectiontitle}[1]{%
- % Anything below \subsubsection (like \paragraph or \subparagraph)
- % is useless because it uses the same font. The only way to
- % (visually) distinguish such deeply nested sections is to use
- % section numbering.
- \subsubsection*{#1}%
-}
-\providecommand{\Dsectionsubtitlehook}[1]{#1}
-\Dprovidelength{\Dsectionsubtitleraisedistance}{0.7em}
-\providecommand{\Dsectionsubtitlescaling}{0.85}
-\providecommand{\Dsectionsubtitle}[1]{%
- \Dsectionsubtitlehook{%
- % Move the subtitle nearer to the title.
- \vspace{-\Dsectionsubtitleraisedistance}%
- % Don't create a PDF bookmark.
- \Ddispatchsectionsubtitle{%
- \Dformatsectionsubtitle{\scalebox{\Dsectionsubtitlescaling}{#1}}%
- }%
- }%
-}
-\providecommand{\DNtitle}[1]{%
- % Dispatch to \D<parent>title.
- \csname D\DEVparent title\endcsname{#1}%
-}
-\providecommand{\DNsubtitle}[1]{%
- % Dispatch to \D<parent>subtitle.
- \csname D\DEVparent subtitle\endcsname{#1}%
-}
-
-\providecommand{\DNliteralblock}[1]{%
- \Dmakelistenvironment{}{%
- \ifthenelse{\equal{\Dinsidetabular}{true}}{%
- \setlength{\leftmargin}{0pt}%
- }{}%
- \setlength{\rightmargin}{0pt}%
- }{%
- \raggedright\item\noindent\nohyphens{\textnhtt{#1\Dfinalstrut}}%
- }%
-}
-\providecommand{\DNdoctestblock}[1]{\DNliteralblock{#1}}
-\providecommand{\DNliteral}[1]{\textnhtt{#1}}
-\providecommand{\DNemphasis}[1]{\emph{#1}}
-\providecommand{\DNstrong}[1]{\textbf{#1}}
-\providecommand{\DECvisitdocument}{\begin{document}\noindent}
-\providecommand{\DECdepartdocument}{\end{document}}
-\providecommand{\DNtopic}[1]{%
- \ifthenelse{\equal{\DEVcurrentNtopicAcontents}{1}}{%
- \addtocounter{Dtoclevel}{1}%
- \par\noindent%
- #1%
- \addtocounter{Dtoclevel}{-1}%
- }{%
- \par\noindent%
- \Dmakebox{#1}%
- }%
-}
-\providecommand{\DNadmonition}[1]{%
- \DNtopic{#1}%
-}
-\providecommand{\Dformatrubric}[1]{\textbf{#1}}
-\Dprovidelength{\Dprerubricspace}{0.3em}
-\providecommand{\DNrubric}[1]{%
- \vspace{\Dprerubricspace}\par\noindent\Dformatrubric{#1}\par%
-}
-
-\providecommand{\Dbullet}{}
-\providecommand{\DECsetbullet}[1]{\renewcommand{\Dbullet}{#1}}
-\providecommand{\DNbulletlist}[1]{%
- \Difinsidetoc{%
- \Dtocbulletlist{#1}%
- }{%
- \Dmakelistenvironment{\Dbullet}{}{#1}%
- }%
-}
-% Todo: So what on earth is @pnumwidth?
-\renewcommand{\@pnumwidth}{2.2em}
-\providecommand{\DNlistitem}[1]{%
- \Difinsidetoc{%
- \ifthenelse{\equal{\theDtoclevel}{1}\and\equal{\Dlocaltoc}{false}}{%
- {%
- \par\addvspace{1em}\noindent%
- \sectfont%
- #1\hfill\pageref{\DEVcurrentNlistitemAtocrefid}%
- }%
- }{%
- \@dottedtocline{0}{\Dtocindent}{0em}{#1}{%
- \pageref{\DEVcurrentNlistitemAtocrefid}%
- }%
- }%
- }{%
- \item{#1}%
- }%
-}
-\providecommand{\DNenumeratedlist}[1]{#1}
-\Dprovidecounter{Dsectionlevel}{0}
-\providecommand{\Dvisitsectionhook}{}
-\providecommand{\Ddepartsectionhook}{}
-\providecommand{\DECvisitsection}{%
- \addtocounter{Dsectionlevel}{1}%
- \Dvisitsectionhook%
-}
-\providecommand{\DECdepartsection}{%
- \Ddepartsectionhook%
- \addtocounter{Dsectionlevel}{-1}%
-}
-
-% Using \_ will cause hyphenation after _ even in \textnhtt-typewriter
-% because the hyphenat package redefines \_. So we use
-% \textunderscore here.
-\providecommand{\DECtextunderscore}{\textunderscore}
-
-\providecommand{\Dtextinlineliteralfirstspace}{{ }}
-\providecommand{\Dtextinlineliteralsecondspace}{{~}}
-
-\Dprovidelength{\Dlistspacing}{0.8\baselineskip}
-
-\providecommand{\Dsetlistrightmargin}{%
- \ifthenelse{\lengthtest{\linewidth>12em}}{%
- % Equal margins.
- \setlength{\rightmargin}{\leftmargin}%
- }{%
- % If the line is narrower than 10em, we don't remove any further
- % space from the right.
- \setlength{\rightmargin}{0pt}%
- }%
-}
-\providecommand{\Dresetlistdepth}{false}
-\Dprovidelength{\Doriginallabelsep}{\labelsep}
-\providecommand{\Dmakelistenvironment}[3]{%
- % Make list environment with support for unlimited nesting and with
- % reasonable default lengths. Parameters:
- % 1. Label (same as in list environment).
- % 2. Spacing (same as in list environment).
- % 3. List contents (contents of list environment).
- \ifthenelse{\equal{\Dinsidetabular}{true}}{%
- % Unfortunately, vertical spacing doesn't work correctly when
- % using lists inside tabular environments, so we use a minipage.
- \begin{minipage}[t]{\linewidth}%
- }{}%
- {%
- \renewcommand{\Dneedvspace}{false}%
- % \parsep0.5\baselineskip
- \renewcommand{\Dresetlistdepth}{false}%
- \ifnum \@listdepth>5%
- \protect\renewcommand{\Dresetlistdepth}{true}%
- \@listdepth=5%
- \fi%
- \begin{list}{%
- #1%
- }{%
- \setlength{\itemsep}{0pt}%
- \setlength{\partopsep}{0pt}%
- \setlength{\topsep}{0pt}%
- % List should take 90% of total width.
- \setlength{\leftmargin}{0.05\linewidth}%
- \ifthenelse{\lengthtest{\leftmargin<1.8em}}{%
- \setlength{\leftmargin}{1.8em}%
- }{}%
- \setlength{\labelsep}{\Doriginallabelsep}%
- \Dsetlistrightmargin%
- #2%
- }{%
- #3%
- }%
- \end{list}%
- \ifthenelse{\equal{\Dresetlistdepth}{true}}{\@listdepth=5}{}%
- }%
- \ifthenelse{\equal{\Dinsidetabular}{true}}{\end{minipage}}{}%
-}
-\providecommand{\Dfinalstrut}{\@finalstrut\@arstrutbox}
-\providecommand{\DAlastitem}[5]{#5\Dfinalstrut}
-
-\Dprovidelength{\Ditemsep}{0pt}
-\providecommand{\DECmakeenumeratedlist}[6]{%
- % Make enumerated list.
- % Parameters:
- % - prefix
- % - type (\arabic, \roman, ...)
- % - suffix
- % - suggested counter name
- % - start number - 1
- % - list contents
- \newcounter{#4}%
- \Dmakelistenvironment{#1#2{#4}#3}{%
- % Use as much space as needed for the label.
- \setlength{\labelwidth}{10em}%
- % Reserve enough space so that the label doesn't go beyond the
- % left margin of preceding paragraphs. Like that:
- %
- % A paragraph.
- %
- % 1. First item.
- \setlength{\leftmargin}{2.5em}%
- \Dsetlistrightmargin%
- \setlength{\itemsep}{\Ditemsep}%
- % Use counter recommended by Python module.
- \usecounter{#4}%
- % Set start value.
- \addtocounter{#4}{#5}%
- }{%
- % The list contents.
- #6%
- }%
-}
-
-
-% Single quote in literal mode. \textquotesingle from package
-% textcomp has wrong width when using package ae, so we use a normal
-% single curly quote here.
-\providecommand{\DECtextliteralsinglequote}{'}
-
-
-% "Tabular lists" are field lists and options lists (not definition
-% lists because there the term always appears on its own line). We'll
-% use the terminology of field lists now ("field", "field name",
-% "field body"), but the same is also analogously applicable to option
-% lists.
-%
-% We want these lists to be breakable across pages. We cannot
-% automatically get the narrowest possible size for the left column
-% (i.e. the field names or option groups) because tabularx does not
-% support multi-page tables, ltxtable needs to have the table in an
-% external file and we don't want to clutter the user's directories
-% with auxiliary files created by the filecontents environment, and
-% ltablex is not included in teTeX.
-%
-% Thus we set a fixed length for the left column and use list
-% environments. This also has the nice side effect that breaking is
-% now possible anywhere, not just between fields.
-%
-% Note that we are creating a distinct list environment for each
-% field. There is no macro for a whole tabular list!
-\Dprovidelength{\Dtabularlistfieldnamewidth}{6em}
-\Dprovidelength{\Dtabularlistfieldnamesep}{0.5em}
-\providecommand{\Dinsidetabular}{false}
-\providecommand{\Dsavefieldname}{}
-\providecommand{\Dsavefieldbody}{}
-\Dprovidelength{\Dusedfieldnamewidth}{0pt}
-\Dprovidelength{\Drealfieldnamewidth}{0pt}
-\providecommand{\Dtabularlistfieldname}[1]{\renewcommand{\Dsavefieldname}{#1}}
-\providecommand{\Dtabularlistfieldbody}[1]{\renewcommand{\Dsavefieldbody}{#1}}
-\Dprovidelength{\Dparskiptemp}{0pt}
-\providecommand{\Dtabularlistfield}[1]{%
- {%
- % This only saves field name and field body in \Dsavefieldname and
- % \Dsavefieldbody, resp. It does not insert any text into the
- % document.
- #1%
- % Recalculate the real field name width everytime we encounter a
- % tabular list field because it may have been changed using a
- % "raw" node.
- \setlength{\Drealfieldnamewidth}{\Dtabularlistfieldnamewidth}%
- \addtolength{\Drealfieldnamewidth}{\Dtabularlistfieldnamesep}%
- \Dmakelistenvironment{%
- \makebox[\Drealfieldnamewidth][l]{\Dsavefieldname}%
- }{%
- \setlength{\labelwidth}{\Drealfieldnamewidth}%
- \setlength{\leftmargin}{\Drealfieldnamewidth}%
- \setlength{\rightmargin}{0pt}%
- \setlength{\labelsep}{0pt}%
- }{%
- \item%
- \settowidth{\Dusedfieldnamewidth}{\Dsavefieldname}%
- \setlength{\Dparskiptemp}{\parskip}%
- \ifthenelse{%
- \lengthtest{\Dusedfieldnamewidth>\Dtabularlistfieldnamewidth}%
- }{%
- \mbox{}\par%
- \setlength{\parskip}{0pt}%
- }{}%
- \Dsavefieldbody%
- \setlength{\parskip}{\Dparskiptemp}%
- %XXX Why did we need this?
- %\@finalstrut\@arstrutbox%
- }%
- \par%
- }%
-}
-
-\providecommand{\Dformatfieldname}[1]{\textbf{#1:}}
-\providecommand{\DNfieldlist}[1]{#1}
-\providecommand{\DNfield}[1]{\Dtabularlistfield{#1}}
-\providecommand{\DNfieldname}[1]{%
- \Dtabularlistfieldname{%
- \Dformatfieldname{#1}%
- }%
-}
-\providecommand{\DNfieldbody}[1]{\Dtabularlistfieldbody{#1}}
-
-\providecommand{\Dformatoptiongroup}[1]{%
- % Format option group, e.g. "-f file, --input file".
- \texttt{#1}%
-}
-\providecommand{\Dformatoption}[1]{%
- % Format option, e.g. "-f file".
- % Put into mbox to avoid line-breaking at spaces.
- \mbox{#1}%
-}
-\providecommand{\Dformatoptionstring}[1]{%
- % Format option string, e.g. "-f".
- #1%
-}
-\providecommand{\Dformatoptionargument}[1]{%
- % Format option argument, e.g. "file".
- \textsl{#1}%
-}
-\providecommand{\Dformatoptiondescription}[1]{%
- % Format option description, e.g.
- % "\DNparagraph{Read input data from file.}"
- #1%
-}
-\providecommand{\DNoptionlist}[1]{#1}
-\providecommand{\Doptiongroupjoiner}{,{ }}
-\providecommand{\Disfirstoption}{%
- % Auxiliary macro indicating if a given option is the first child
- % of its option group (if it's not, it has to preceded by
- % \Doptiongroupjoiner).
- false%
-}
-\providecommand{\DNoptionlistitem}[1]{%
- \Dtabularlistfield{#1}%
-}
-\providecommand{\DNoptiongroup}[1]{%
- \renewcommand{\Disfirstoption}{true}%
- \Dtabularlistfieldname{\Dformatoptiongroup{#1}}%
-}
-\providecommand{\DNoption}[1]{%
- % If this is not the first option in this option group, add a
- % joiner.
- \ifthenelse{\equal{\Disfirstoption}{true}}{%
- \renewcommand{\Disfirstoption}{false}%
- }{%
- \Doptiongroupjoiner%
- }%
- \Dformatoption{#1}%
-}
-\providecommand{\DNoptionstring}[1]{\Dformatoptionstring{#1}}
-\providecommand{\DNoptionargument}[1]{{ }\Dformatoptionargument{#1}}
-\providecommand{\DNdescription}[1]{%
- \Dtabularlistfieldbody{\Dformatoptiondescription{#1}}%
-}
-
-\providecommand{\DNdefinitionlist}[1]{%
- \begin{description}%
- \parskip0pt%
- #1%
- \end{description}%
-}
-\providecommand{\DNdefinitionlistitem}[1]{%
- % LaTeX expects the label in square brackets; we provide an empty
- % label.
- \item[]#1%
-}
-\providecommand{\Dformatterm}[1]{#1}
-\providecommand{\DNterm}[1]{\hspace{-5pt}\Dformatterm{#1}}
-% I'm still not sure what's the best rendering for classifiers. The
-% colon syntax is used by reStructuredText, so it's at least WYSIWYG.
-% Use slanted text because italic would cause too much emphasis.
-\providecommand{\Dformatclassifier}[1]{\textsl{#1}}
-\providecommand{\DNclassifier}[1]{~:~\Dformatclassifier{#1}}
-\providecommand{\Dformatdefinition}[1]{#1}
-\providecommand{\DNdefinition}[1]{\par\Dformatdefinition{#1}}
-
-\providecommand{\Dlineblockindentation}{2.5em}
-\providecommand{\DNlineblock}[1]{%
- \Dmakelistenvironment{}{%
- \ifthenelse{\equal{\DEVparent}{lineblock}}{%
- % Parent is a line block, so indent.
- \setlength{\leftmargin}{\Dlineblockindentation}%
- }{%
- % At top level; don't indent.
- \setlength{\leftmargin}{0pt}%
- }%
- \setlength{\rightmargin}{0pt}%
- \setlength{\parsep}{0pt}%
- }{%
- #1%
- }%
-}
-\providecommand{\DNline}[1]{\item#1}
-
-\providecommand{\DNtransition}{%
- \raisebox{0.25em}{\parbox{\linewidth}{\hspace*{\fill}\hrulefill\hrulefill\hspace*{\fill}}}%
-}
-
-\providecommand{\Dformatblockquote}[1]{%
- % Format contents of block quote.
- % This occurs in block-level context, so we cannot use \textsl.
- {\slshape#1}%
-}
-\providecommand{\Dformatattribution}[1]{---\textup{#1}}
-\providecommand{\DNblockquote}[1]{%
- \Dmakebox{%
- \Dformatblockquote{#1}
- }%
-}
-\providecommand{\DNattribution}[1]{%
- \par%
- \begin{flushright}\Dformatattribution{#1}\end{flushright}%
-}
-
-
-% Sidebars:
-% Vertical and horizontal margins.
-\Dprovidelength{\Dsidebarvmargin}{0.5em}
-\Dprovidelength{\Dsidebarhmargin}{1em}
-% Padding (space between contents and frame).
-\Dprovidelength{\Dsidebarpadding}{1em}
-% Frame width.
-\Dprovidelength{\Dsidebarframewidth}{2\fboxrule}
-% Position ("l" or "r").
-\providecommand{\Dsidebarposition}{r}
-% Width.
-\Dprovidelength{\Dsidebarwidth}{0.45\linewidth}
-\providecommand{\DNsidebar}[1]{
- \parpic[\Dsidebarposition]{%
- \begin{minipage}[t]{\Dsidebarwidth}%
- % Doing this with nested minipages is ugly, but I haven't found
- % another way to place vertical space before and after the fbox.
- \vspace{\Dsidebarvmargin}%
- {%
- \setlength{\fboxrule}{\Dsidebarframewidth}%
- \setlength{\fboxsep}{\Dsidebarpadding}%
- \fbox{%
- \begin{minipage}[t]{\linewidth}%
- \setlength{\parindent}{\Dboxparindent}%
- #1%
- \end{minipage}%
- }%
- }%
- \vspace{\Dsidebarvmargin}%
- \end{minipage}%
- }%
-}
-
-
-% Citations and footnotes.
-\providecommand{\Dformatfootnote}[1]{%
- % Format footnote.
- {%
- \footnotesize#1%
- % \par is necessary for LaTeX to adjust baselineskip to the
- % changed font size.
- \par%
- }%
-}
-\providecommand{\Dformatcitation}[1]{\Dformatfootnote{#1}}
-\Dprovidelength{\Doriginalbaselineskip}{0pt}
-\providecommand{\DNfootnotereference}[1]{%
- {%
- % \baselineskip is 0pt in \textsuperscript, so we save it here.
- \setlength{\Doriginalbaselineskip}{\baselineskip}%
- \textsuperscript{#1}%
- }%
-}
-\providecommand{\DNcitationreference}[1]{{[}#1{]}}
-\Dprovidelength{\Dfootnotesep}{3.5pt}
-\providecommand{\Dsetfootnotespacing}{%
- % Spacing commands executed at the beginning of footnotes.
- \setlength{\parindent}{0pt}%
- \hspace{1em}%
-}
-\providecommand{\DNfootnote}[1]{%
- % See ltfloat.dtx for details.
- {%
- \insert\footins{%
- % BUG: This is too small if the user adds
- % \onehalfspacing or \doublespace.
- \vspace{\Dfootnotesep}%
- \Dsetfootnotespacing%
- \Dformatfootnote{#1}%
- }%
- }%
-}
-\providecommand{\DNcitation}[1]{\DNfootnote{#1}}
-\providecommand{\Dformatfootnotelabel}[1]{%
- % Keep \footnotesize in footnote labels (\textsuperscript would
- % reduce the font size even more).
- \textsuperscript{\footnotesize#1{ }}%
-}
-\providecommand{\Dformatcitationlabel}[1]{{[}#1{]}{ }}
-\providecommand{\Dformatmultiplebackrefs}[1]{%
- % If in printing mode, do not write out multiple backrefs.
- \ifthenelse{\equal{\Dprinting}{true}}{}{\textsl{#1}}%
-}
-\providecommand{\Dthislabel}{}
-\providecommand{\DNlabel}[1]{%
- % Footnote or citatation label.
- \renewcommand{\Dthislabel}{#1}%
- \ifthenelse{\not\equal{\DEVsinglebackref}{}}{%
- \let\Doriginallabel=\Dthislabel%
- \def\Dthislabel{%
- \Dsinglefootnotebacklink{\DEVsinglebackref}{\Doriginallabel}%
- }%
- }{}%
- \ifthenelse{\equal{\DEVparent}{footnote}}{%
- % Footnote label.
- \Dformatfootnotelabel{\Dthislabel}%
- }{%
- \ifthenelse{\equal{\DEVparent}{citation}}{%
- % Citation label.
- \Dformatcitationlabel{\Dthislabel}%
- }{}%
- }%
- % If there are multiple backrefs, add them now.
- \Dformatmultiplebackrefs{\DEVmultiplebackrefs}%
-}
-\providecommand{\Dsinglefootnotebacklink}[2]{%
- % Create normal backlink of a footnote label. Parameters:
- % 1. ID.
- % 2. Link text.
- % Treat like a footnote reference.
- \Dimplicitfootnotereference{\##1}{#2}%
-}
-\providecommand{\DECmultifootnotebacklink}[2]{%
- % Create generated backlink, as in (1, 2). Parameters:
- % 1. ID.
- % 2. Link text.
- % Treat like a footnote reference.
- \Dimplicitfootnotereference{\##1}{#2}%
-}
-\providecommand{\Dsinglecitationbacklink}[2]{\Dsinglefootnotebacklink{#1}{#2}}
-\providecommand{\DECmulticitationbacklink}[2]{\DECmultifootnotebacklink{#1}{#2}}
-
-
-\providecommand{\DECmaketable}[2]{%
- % Make table. Parameters:
- % 1. Table spec (like "|p|p|").
- % 2. Table contents.
- {%
- \ifthenelse{\equal{\Dinsidetabular}{true}}{%
- % Inside longtable; we cannot have nested longtables.
- \begin{tabular}{#1}%
- \hline%
- #2%
- \end{tabular}%
- }{%
- \renewcommand{\Dinsidetabular}{true}%
- \begin{longtable}{#1}%
- \hline%
- #2%
- \end{longtable}%
- }%
- }%
-}
-\providecommand{\DNthead}[1]{%
- #1%
- \endhead%
-}
-\providecommand{\DNrow}[1]{%
- #1\tabularnewline%
- \hline%
-}
-\providecommand{\Dinsidemulticolumn}{false}
-\providecommand{\Dcompensatingmulticol}[3]{%
- \multicolumn{#1}{#2}{%
- {%
- \renewcommand{\Dinsidemulticolumn}{true}%
- % Compensate for weird missing vertical space at top of paragraph.
- \raisebox{-2.5pt}{#3}%
- }%
- }%
-}
-\providecommand{\DECcolspan}[2]{%
- % Take care of the morecols attribute (but incremented by 1).
- &%
- \Dcompensatingmulticol{#1}{l|}{#2}%
-}
-\providecommand{\DECcolspanleft}[2]{%
- % Like \Dmorecols, but called for the leftmost entries in a table
- % row.
- \Dcompensatingmulticol{#1}{|l|}{#2}%
-}
-\providecommand{\DECsubsequententry}[1]{%
- %
-}
-\providecommand{\DNentry}[1]{%
- % The following sequence adds minimal vertical space above the top
- % lines of the first cell paragraph, so that vertical space is
- % balanced at the top and bottom of table cells.
- \ifthenelse{\equal{\Dinsidemulticolumn}{false}}{%
- \vspace{-1em}\vspace{-\parskip}\par%
- }{}%
- #1%
- % No need to add an ampersand ("&"); that's done by \DECsubsequententry.
-}
-\providecommand{\DAtableheaderentry}[5]{\Dformattableheaderentry{#5}}
-\providecommand{\Dformattableheaderentry}[1]{{\bfseries#1}}
-
-
-\providecommand{\DNsystemmessage}[1]{%
- {%
- \ifthenelse{\equal{\Dprinting}{false}}{\color{red}}{}%
- \bfseries%
- #1%
- }%
-}
-
-
-\providecommand{\Dinsidehalign}{false}
-\newsavebox{\Dalignedimagebox}
-\Dprovidelength{\Dalignedimagewidth}{0pt}
-\providecommand{\Dhalign}[2]{%
- % Horizontally align the contents to the left or right so that the
- % text flows around it.
- % Parameters:
- % 1. l or r
- % 2. Contents.
- \renewcommand{\Dinsidehalign}{true}%
- % For some obscure reason \parpic consumes some vertical space.
- \vspace{-3pt}%
- % Now we do something *really* ugly, but this enables us to wrap the
- % image in a minipage while still allowing tight frames when
- % class=border (see \DNimageCborder).
- \sbox{\Dalignedimagebox}{#2}%
- \settowidth{\Dalignedimagewidth}{\usebox{\Dalignedimagebox}}%
- \parpic[#1]{%
- \begin{minipage}[b]{\Dalignedimagewidth}%
- % Compensate for previously added space, but not entirely.
- \vspace*{2.0pt}%
- \vspace*{\Dfloatimagetopmargin}%
- \usebox{\Dalignedimagebox}%
- \vspace*{1.5pt}%
- \vspace*{\Dfloatimagebottommargin}%
- \end{minipage}%
- }%
- \renewcommand{\Dinsidehalign}{false}%
-}
-
-
-% Maximum width of an image.
-\providecommand{\Dimagemaxwidth}{\linewidth}
-\providecommand{\Dfloatimagemaxwidth}{0.5\linewidth}
-% Auxiliary variable.
-\Dprovidelength{\Dcurrentimagewidth}{0pt}
-\providecommand{\DNimageAalign}[5]{%
- \ifthenelse{\equal{#3}{left}}{%
- \Dhalign{l}{#5}%
- }{%
- \ifthenelse{\equal{#3}{right}}{%
- \Dhalign{r}{#5}%
- }{%
- \ifthenelse{\equal{#3}{center}}{%
- % Text floating around centered figures is a bad idea. Thus
- % we use a center environment. Note that no extra space is
- % added by the writer, so the space added by the center
- % environment is fine.
- \begin{center}#5\end{center}%
- }{%
- #5%
- }%
- }%
- }%
-}
-% Base path for images.
-\providecommand{\Dimagebase}{}
-% Auxiliary command. Current image path.
-\providecommand{\Dimagepath}{}
-\providecommand{\DNimageAuri}[5]{%
- % Insert image. We treat the URI like a path here.
- \renewcommand{\Dimagepath}{\Dimagebase#3}%
- \Difdefined{DcurrentNimageAwidth}{%
- \Dwidthimage{\DEVcurrentNimageAwidth}{\Dimagepath}%
- }{%
- \Dsimpleimage{\Dimagepath}%
- }%
-}
-\Dprovidelength{\Dfloatimagevmargin}{0pt}
-\providecommand{\Dfloatimagetopmargin}{\Dfloatimagevmargin}
-\providecommand{\Dfloatimagebottommargin}{\Dfloatimagevmargin}
-\providecommand{\Dwidthimage}[2]{%
- % Image with specified width.
- % Parameters:
- % 1. Image width.
- % 2. Image path.
- % Need to make bottom-alignment dependent on align attribute (add
- % functional test first). Need to observe height attribute.
- %\begin{minipage}[b]{#1}%
- \includegraphics[width=#1,height=\textheight,keepaspectratio]{#2}%
- %\end{minipage}%
-}
-\providecommand{\Dcurrentimagemaxwidth}{}
-\providecommand{\Dsimpleimage}[1]{%
- % Insert image, without much parametrization.
- \settowidth{\Dcurrentimagewidth}{\includegraphics{#1}}%
- \ifthenelse{\equal{\Dinsidehalign}{true}}{%
- \renewcommand{\Dcurrentimagemaxwidth}{\Dfloatimagemaxwidth}%
- }{%
- \renewcommand{\Dcurrentimagemaxwidth}{\Dimagemaxwidth}%
- }%
- \ifthenelse{\lengthtest{\Dcurrentimagewidth>\Dcurrentimagemaxwidth}}{%
- \Dwidthimage{\Dcurrentimagemaxwidth}{#1}%
- }{%
- \Dwidthimage{\Dcurrentimagewidth}{#1}%
- }%
-}
-\providecommand{\Dwidthimage}[2]{%
- % Image with specified width.
- % Parameters:
- % 1. Image width.
- % 2. Image path.
- \Dwidthimage{#1}{#2}%
-}
-
-% Figures.
-\providecommand{\DNfigureAalign}[5]{%
- % Hack to make it work Right Now.
- %\def\DEVcurrentNimageAwidth{\DEVcurrentNfigureAwidth}%
- %
- %\def\DEVcurrentNimageAwidth{\linewidth}%
- \DNimageAalign{#1}{#2}{#3}{#4}{%
- \begin{minipage}[b]{0.4\linewidth}#5\end{minipage}}%
- %\let\DEVcurrentNimageAwidth=\relax%
- %
- %\let\DEVcurrentNimageAwidth=\relax%
-}
-\providecommand{\DNcaption}[1]{\par\noindent{\slshape#1}}
-\providecommand{\DNlegend}[1]{\DECauxiliaryspace#1}
-
-\providecommand{\DCborder}[1]{\fbox{#1}}
-% No padding between image and border.
-\providecommand{\DNimageCborder}[1]{\frame{#1}}
-
-
-% Need to replace with language-specific stuff. Maybe look at
-% csquotes.sty and ask the author for permission to use parts of it.
-\providecommand{\DECtextleftdblquote}{``}
-\providecommand{\DECtextrightdblquote}{''}
-
-% Table of contents:
-\Dprovidelength{\Dtocininitialsectnumwidth}{2.4em}
-\Dprovidelength{\Dtocadditionalsectnumwidth}{0.7em}
-% Level inside a table of contents. While this is at -1, we are not
-% inside a TOC.
-\Dprovidecounter{Dtoclevel}{-1}%
-\providecommand{\Dlocaltoc}{false}%
-\providecommand{\DNtopicClocal}[1]{%
- \renewcommand{\Dlocaltoc}{true}%
- \addtolength{\Dtocsectnumwidth}{2\Dtocadditionalsectnumwidth}%
- \addtolength{\Dtocindent}{-2\Dtocadditionalsectnumwidth}%
- #1%
- \addtolength{\Dtocindent}{2\Dtocadditionalsectnumwidth}%
- \addtolength{\Dtocsectnumwidth}{-2\Dtocadditionalsectnumwidth}%
- \renewcommand{\Dlocaltoc}{false}%
-}
-\Dprovidelength{\Dtocindent}{0pt}%
-\Dprovidelength{\Dtocsectnumwidth}{\Dtocininitialsectnumwidth}
-% Compensate for one additional TOC indentation space so that the
-% top-level is unindented.
-\addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}
-\addtolength{\Dtocindent}{-\Dtocsectnumwidth}
-\providecommand{\Difinsidetoc}[2]{%
- \ifthenelse{\not\equal{\theDtoclevel}{-1}}{#1}{#2}%
-}
-\providecommand{\DNgeneratedCsectnum}[1]{%
- \Difinsidetoc{%
- % Section number inside TOC.
- \makebox[\Dtocsectnumwidth][l]{#1}%
- }{%
- % Section number inside section title.
- #1\quad%
- }%
-}
-\providecommand{\Dtocbulletlist}[1]{%
- \addtocounter{Dtoclevel}{1}%
- \addtolength{\Dtocindent}{\Dtocsectnumwidth}%
- \addtolength{\Dtocsectnumwidth}{\Dtocadditionalsectnumwidth}%
- #1%
- \addtolength{\Dtocsectnumwidth}{-\Dtocadditionalsectnumwidth}%
- \addtolength{\Dtocindent}{-\Dtocsectnumwidth}%
- \addtocounter{Dtoclevel}{-1}%
-}
-
-
-% For \DECpixelunit, the length value is pre-multiplied with 0.75, so by
-% specifying "pt" we get the same notion of "pixel" as graphicx.
-\providecommand{\DECpixelunit}{pt}
-% Normally lengths are relative to the current linewidth.
-\providecommand{\DECrelativeunit}{\linewidth}
-
-
-% ACTION: These commands actually *do* something.
-% Ultimately, everything should be done here, and no active content should be
-% above (not even \usepackage).
-
-\DSearly
-\DSpackages
-\DSfrenchspacing
-\DSsymbols
-\DSlate
-
-\makeatother
-
- \usepackage{fancyvrb}
+++ /dev/null
-from scikits.audiolab import formatinfo as format
-
-f = format('aiff', 'ulaw')
-print f
-
-f = format('ircam', 'float32')
-print f
+++ /dev/null
-from scikits.audiolab import supported_format, supported_encoding, \
- supported_endianness
-
-print supported_format()
-print supported_encoding()
-print supported_endianness()
+++ /dev/null
-from tempfile import mkstemp
-from os.path import join, dirname
-from os import remove
-
-from scikits.audiolab import wavread, wavwrite
-
-(tmp, fs, enc) = wavread('test.wav')
-if tmp.ndim < 2:
- nc = 1
-else:
- nc = tmp.shape[1]
-
-print "The file has %d frames, %d channel(s)" % (tmp.shape[0], nc)
-print "FS is %f, encoding is %s" % (fs, enc)
-
-fd, cfilename = mkstemp('pysndfiletest.wav')
-try:
- wavwrite(tmp, cfilename, fs = 16000, enc = 'pcm24')
-finally:
- remove(cfilename)
+++ /dev/null
-import scikits.audiolab as audiolab
-
-a = audiolab.sndfile('test.flac', 'read')
-data = a.read_frames(1000)
-a.close()
+++ /dev/null
-import scikits.audiolab as audiolab
-
-filename = 'test.flac'
-a = audiolab.sndfile(filename, 'read')
-
-print a
+++ /dev/null
-import numpy as N
-
-import scikits.audiolab as audiolab
-
-filename = 'test.flac'
-a = audiolab.sndfile(filename, 'read')
-
-tmp = a.read_frames(1e4)
-float_tmp = a.read_frames(1e4, dtype = N.float32)
-
-import pylab as P
-P.plot(tmp[:])
+++ /dev/null
-from tempfile import mkstemp
-from os import remove
-
-import numpy as N
-from scikits.audiolab import formatinfo as format
-import scikits.audiolab as audiolab
-
-# Create a temp file in the system temporary dir, and always remove
-# it at the end
-cd, filename = mkstemp('tmptest.wav')
-try:
- fmt = format('wav', 'pcm24')
- nchannels = 2
- fs = 44100
-
- afile = audiolab.sndfile(filename, 'write', fmt, nchannels, fs)
-
- # Create a stereo white noise, with Gaussian distribution
- tmp = 0.1 * N.random.randn(1000, nchannels)
-
- # Write the first 500 frames of the signal
- # Note that the write_frames method uses tmp's numpy dtype to determine how
- # to write to the file; sndfile also converts the data on the fly if necessary
- afile.write_frames(tmp, 500)
-
- afile.close()
-
- # Let's check that the written file has the expected meta data
- afile = audiolab.sndfile(filename, 'read')
- assert(afile.get_samplerate() == fs)
- assert(afile.get_channels() == nchannels)
- assert(afile.get_nframes() == 500)
-finally:
- remove(filename)
+++ /dev/null
-..
- restindex
- page-title: audiolab
- crumb: audiolab
- link-title: audiolab
- encoding: utf-8
- output-encoding: None
- file: audiolab1.png
- file: quick1.py
- file: usage1.py
- file: usage2.py
- file: format1.py
- file: format2.py
- file: write1.py
- file: matlab1.py
- file: audiolab.pdf
- /restindex
-
-.. vim:syntax=rest
-.. Last Change: Tue Jul 17 11:00 AM 2007 J
-
-===============================================================
- Pyaudiolab, a python package to make noise with numpy arrays
-===============================================================
-
-Introduction
-============
-
-.. _scipy: http://www.scipy.org
-.. _libsndfile: http://www.mega-nerd.com/libsndfile/
-
-For people doing audio processing, it is useful to be able to import data from
-audio files, and export them back, as well as listening to the results of some
-processing; matlab have functions such as wavread, wavwrite, soundsc, etc...
-for that purposes. The goal of audiolab is to give those capabilities to the
-`scipy`_ environment by wrapping the excellent library `libsndfile`_ from Erik
-Castro de Lopo. Pyaudio supports all format supported by libsndfile, including
-wav, aiff, ircam files, and flac (an open source lossless compressed format);
-see `here <http://www.mega-nerd.com/libsndfile/#Features">`_ for a complete
-list.
-
- **Note**: The library is still in beta stage: reading and writing
- data is possible, but only in frames, not per item.
- Also, the ability to play data on the system's soundcard is not there yet.
- I have never encountered any data corruption, except when using the buggy
- ctypes included in Ubuntu's python 2.5 (bug which was solved recently).
-
- **Note**: The online version of this document is not always up to date. The
- pdf included in the package is the reference, and always in sync with the
- package. If something does not work, please refer first to the pdf included in
- the package.
-
-.. contents:: Tables of contents
-
-Download and installation
-=========================
-
-Download
---------
-
-audiolab is part of scikits: its source can be downloaded directly from the
-scikits svn repository: svn co http://svn.scipy.org/svn/scikits/trunk/audiolab
-
-Requirements
-------------
-
-audiolab requires the following softwares:
-
- - a python interpreter.
- - libsndfile (including the header sndfile.h, which means linux users should
- download the libsndfile-dev package).
- - numpy (any version >= 1.0 should work).
- - ctypes (version >= 1.0.1)
-
-Starting with version 2.5, python include ctypes in its standart library, so you
-don't need to install ctypes separately in this case.
-
-It has been run succesfully on the following platforms:
-
- - linux ubuntu (32 and 64 bits)
- - windows XP
-
-I would be interested to hear anyone who succeesfully used it on other
-plateforms (Mac Os X, solaris, etc...).
-
- **Note**: the ctypes used in python2.5 package in ubuntu (and maybe debian
- as well) *had* a nasty bug which makes it impossible to use 64 bits integers. You
- should NOT use this package with audiolab (importing audiolab should fail,
- but if the version is not correctly detected, you will have file corruption when
- writing data to audio files). Run the test to check everything is working (a
- test case tests this issue).
-
- `<https://launchpad.net/ubuntu/+source/python2.5/+bug/71914>`_
-
-
-Installation
-------------
-
-For unix users, if libsndfile is installed in standart location (eg /usr/lib,
-/usr/local/lib), the installer should be able to find them automatically, and
-you only need to do a "python setup.py install". In other cases, you need to
-create a file site.cfg to set the location of libsndfile and its header (there
-are site.cfg examples which should give you an idea how to use them on your
-platform).
-
-For windows users: the library distributed by Erik Castro de Lopo cannot be
-used directly; you need to follow the instructions given in libsndfile
-distribution in the file README-precompiled-dll.txt. See also site.cfg.win32.
-
-License
--------
-
-audiolab is released under the LGPL, which forces you to release back the
-modifications you may make in the version of audiolab you are distributing,
-but you can still use it in closed softwares.
-
-Quick view
-==========
-
-The following code shows you how to open a file for read, reading the first
-1000 frames, and closing it:
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/quick1.py}
-
-.. raw:: latex
-
- \input{quick1.tex}
-
-Usage
-=====
-
-Opening a file and getting its parameters
------------------------------------------
-
-Once imported, audiolab gives you access the sndfile class, which is the
-class of audiolab use to open audio files.
-You create a sndfile instance when you want
-to open a file for reading or writing (the file test.flac is included
-in the audiolab package, in the test_data directory):
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/usage1.py}
-
-.. raw:: latex
-
- \input{usage1.tex}
-
-Prints you the informations related to the file, like its sampling rate,
-the number of frames, etc... You can of course get each parameter
-individually by using the corresponding sndfile.get* accessors.
-
-Importing audio data
---------------------
-
-Now that we've opened a file, we would like to read its audio content,
-right ? For now, you can only import the data as floating point data,
-float (32 bits) or double (64 bits). The function
-sndfile.read_frames read n frames,
-where a frame contains a sample of each channel (one in mono, 2 in stereo,
-etc...):
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/usage2.py}
-
-.. raw:: latex
-
- \input{usage2.tex}
-
-The above code import 10000 frames, and plot the first channel using matplotlib
-(see below). A frame holds one sample from each channel: 1000 frames of a stereo
-file is 2000 samples. Each channel is one column of the numpy array. The read
-functions follow numpy conventions, that is by default, the data are read as
-double, but you can give a dtype argument to the function.
-
-.. image:: audiolab1.png
- :width: 500
- :height: 400
-
-The format class
-----------------
-
-When opening a file for writing, you need to give various parameters related to
-the format such as the file format, the encoding. The format class is used to
-create valid formats from those parameters By default, the format class creates
-a format object with file type wav, and 16 bits pcm encoding:
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/format1.py}
-
-.. raw:: latex
-
- \input{format1.tex}
-
-prints back "Major Format: AIFF (Apple/SGI), Encoding Format: U-Law"
-and "Major Format: SF (Berkeley/IRCAM/CARL), Encoding Format: 32 bit float".
-
-To get a list of all possible file format and encoding, the function
-supported_* are available:
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/format2.py}
-
-.. raw:: latex
-
- \input{format2.tex}
-
- **Note**: not all combination of encoding, endianness and format are possible.
- If you try to create a format with incompatible values, you will get an error
- while creating an instance of format.
-
-Writing data to a file
-----------------------
-
-Opening a file for writing is a bit more complicated than reading; you need to
-say which format you are requesting, the number of channels and the sampling
-rate (in Hz) you are requesting; all thoses information are mandatory ! The
-class format is used to build a format understable by libsndfile from
-'user-friendly' values. Let's see how it works.
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/write1.py}
-
-.. raw:: latex
-
- \input{write1.tex}
-
-Matlab-like API
----------------
-
-audiolab also have a matlab-like API for audio IO. Its usage is as similar as it
-can get using python:
-
-.. raw:: html
-
- {mycolorize;input/softwares/audiolab/matlab1.py}
-
-.. raw:: latex
-
- \input{matlab1.tex}
-
-Known bugs:
-===========
-
- - there seems to be a problem when using libsndfile fseek facilities with flac
- files (which are necessary for the functions flacread/flacwrite). The
- problem seems to be with libFLAC; for this reason, seek in flac files is not
- enabled by default for now. See FLAC_SUPPORT.txt for more informations.
-
-TODO
-====
-
-audiolab is still in early stages. Before a release, I would like to implement the
-follwings:
-
- - support (at least some) meta-data embedded in some audio files format.
- - support the libsndfile's error system
- - player on all major plateforms (at least linux/windows/max OS X)
+++ /dev/null
-% Last Change: Wed Jan 31 08:00 PM 2007 J
-% vim:syntax=tex
-
-\newcommand\at{@}
-\newcommand\lb{[}
-\newcommand\rb{]}
-\newcommand\Cba[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\Caz[1]{\textcolor[rgb]{0.00,0.25,0.82}{#1}}
-\newcommand\Cay[1]{\textcolor[rgb]{0.67,0.13,1.00}{#1}}
-\newcommand\Cax[1]{\textcolor[rgb]{0.00,0.63,0.00}{#1}}
-\newcommand\Cbc[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\Cas[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\Car[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}}
-\newcommand\Caq[1]{\textcolor[rgb]{0.73,0.27,0.27}{\textit{#1}}}
-\newcommand\Cap[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}}
-\newcommand\Caw[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\Cav[1]{\textcolor[rgb]{0.60,0.60,0.60}{\textbf{#1}}}
-\newcommand\Cau[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\Cat[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\Cak[1]{\textbf{#1}}
-\newcommand\Caj[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}}
-\newcommand\Cai[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}}
-\newcommand\Cah[1]{\textcolor[rgb]{0.63,0.63,0.00}{#1}}
-\newcommand\Cao[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}}
-\newcommand\Can[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}}
-\newcommand\Cam[1]{\textcolor[rgb]{0.73,0.40,0.13}{\textbf{#1}}}
-\newcommand\Cal[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\Cac[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\Cab[1]{\textit{#1}}
-\newcommand\Caa[1]{\textcolor[rgb]{0.50,0.50,0.50}{#1}}
-\newcommand\Cag[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\Caf[1]{\textcolor[rgb]{0.00,0.53,0.00}{\textit{#1}}}
-\newcommand\Cae[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\Cad[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\Cbb[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\CaZ[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\CaY[1]{\textcolor[rgb]{0.00,0.00,0.50}{\textbf{#1}}}
-\newcommand\CaX[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}}
-\newcommand\Cbd[1]{\textcolor[rgb]{0.73,0.40,0.53}{\textbf{#1}}}
-\newcommand\Cbe[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\CaS[1]{\textcolor[rgb]{0.50,0.00,0.50}{\textbf{#1}}}
-\newcommand\CaR[1]{\textcolor[rgb]{0.00,0.53,0.00}{\textit{#1}}}
-\newcommand\CaQ[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}}
-\newcommand\CaP[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
-\newcommand\CaW[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\CaV[1]{\textcolor[rgb]{0.67,0.13,1.00}{#1}}
-\newcommand\CaU[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\CaT[1]{\textcolor[rgb]{0.00,0.00,1.00}{\textbf{#1}}}
-\newcommand\CaK[1]{\textcolor[rgb]{0.67,0.13,1.00}{#1}}
-\newcommand\CaJ[1]{\textcolor[rgb]{0.00,0.63,0.00}{#1}}
-\newcommand\CaI[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\CaH[1]{\textcolor[rgb]{0.67,0.13,1.00}{\textbf{#1}}}
-\newcommand\CaO[1]{\textcolor[rgb]{0.73,0.27,0.27}{#1}}
-\newcommand\CaN[1]{\textcolor[rgb]{0.00,0.00,0.50}{\textbf{#1}}}
-\newcommand\CaM[1]{\textcolor[rgb]{0.00,0.00,1.00}{#1}}
-\newcommand\CaL[1]{\textcolor[rgb]{0.00,0.53,0.00}{#1}}
-\newcommand\CaC[1]{\textcolor[rgb]{0.00,0.53,0.00}{\textit{#1}}}
-\newcommand\CaB[1]{\textcolor[rgb]{0.82,0.25,0.23}{\textbf{#1}}}
-\newcommand\CaA[1]{\textcolor[rgb]{0.67,0.13,1.00}{#1}}
-\newcommand\CaG[1]{\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{#1}}
-\newcommand\CaF[1]{\textcolor[rgb]{0.72,0.53,0.04}{#1}}
-\newcommand\CaE[1]{\textcolor[rgb]{1.00,0.00,0.00}{#1}}
-\newcommand\CaD[1]{\textcolor[rgb]{0.63,0.00,0.00}{#1}}
-
+++ /dev/null
-VERSION = '0.8dev'
-ignore = False
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Mon Sep 10 07:00 PM 2007 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-"""This module implements functions to read and write to audio files easily
-(ala matlab: wavread, etc...)."""
-
-import numpy as N
-
-from pysndfile import formatinfo, sndfile
-from pysndfile import PyaudioException, FlacUnsupported
-
-__all__ = []
-_MATAPI_FORMAT = ['wav', 'aiff', 'au', 'sdif', 'flac']
-for i in _MATAPI_FORMAT:
- __all__.extend(['%sread' % i, '%swrite' % i])
-
-# writer function factory
-def _writer_factory(name, format, def_fs, descr):
- """ Create a writer function with fileformat described by format, default
- sampling rate def_fs, and docstring descr."""
- def basic_writer(data, filename, fs = def_fs, enc = format.get_encoding()):
- """Common "template" to all write functions."""
- if N.ndim(data) <= 1:
- nc = 1
- nframes = N.size(data)
- elif N.ndim(data) == 2:
- nc = data.shape[1]
- nframes = data.shape[0]
- else:
- RuntimeError("Only rank 0, 1, and 2 arrays supported as audio data")
-
- hdl = sndfile(filename, 'write', format, nc, fs)
- try:
- hdl.write_frames(data, nframes)
- finally:
- hdl.close()
- doc = \
- """ wrapper around pysndfile to write %s file,
- in a similar manner to matlab's wavwrite/auwrite and the likes.
-
- OVERWRITES EXISTING FILE !
-
- Args:
- - data: a rank 0, 1 (mono) or 2 (one channel per col) numpy array
- - filename: a string for the audio file name
- - fs: the sampling rate in Hz (%d Hz by default).
- - enc: a string for the encoding such as 'pcm16', etc...(%s by
- default). Not supported yet !
-
- For a total control over options, such as endianness, append data to an
- existing file, etc... you should use sndfile class instances instead""" \
- % (str(descr), def_fs, format.get_encoding())
- basic_writer.__doc__ = doc
- basic_writer.__name__ = name
- return basic_writer
-
-# template for reader functions
-def _reader_factory(name, filetype, descr):
- """Factory for reader functions ala matlab."""
- def basic_reader(filename, last = None, first = 0):
- """Common "template" to all read functions."""
- hdl = sndfile(filename, 'read')
- try:
- if not hdl.get_file_format() == filetype:
- raise PyaudioException("%s is not a %s file (is %s)" \
- % (filename, filetype, hdl.get_file_format()))
-
- fs = hdl.get_samplerate()
- enc = hdl.get_encoding()
- # Set the pointer to start position
- nf = hdl.seek(first, 1)
- if not nf == first:
- raise IOError("Error while seeking at starting position")
-
- if last is None:
- nframes = hdl.get_nframes() - first
- data = hdl.read_frames(nframes)
- else:
- data = hdl.read_frames(last)
- finally:
- hdl.close()
-
- return data, fs, enc
- doc = \
- """ wrapper around pysndfile to read a %s file in float64,
- in a similar manner to matlab wavread/auread/etc...
-
- Returns a tuple (data, fs, enc), where :
- - data are the read data (one column per channel)
- - fs, the sampling rate
- - enc, a string which is the encoding of the file, such as 'pcm16',
- 'float32', etc...
-
- For a total control over options, such as output's dtype, etc...,
- you should use sndfile class instances instead""" % (str(descr),)
- basic_reader.__doc__ = doc
- basic_reader.__name__ = name
- return basic_reader
-
-wavread = _reader_factory('wavread', 'wav',
- formatinfo('wav', 'pcm16').get_major_str())
-auread = _reader_factory('auread', 'au',
- formatinfo('au', 'pcm16').get_major_str())
-aiffread = _reader_factory('aiffread', 'aiff',
- formatinfo('aiff', 'pcm16').get_major_str())
-sdifread = _reader_factory('sdifread', 'ircam',
- formatinfo('ircam', 'pcm16').get_major_str())
-
-_f1 = formatinfo('wav', 'pcm16')
-wavwrite = _writer_factory('wavwrite', _f1, 8000, _f1.get_major_str())
-
-_f2 = formatinfo('au', 'ulaw')
-auwrite = _writer_factory('auwrite', _f2, 8000, _f2.get_major_str())
-
-_f3 = formatinfo('aiff', 'pcm16')
-aiffwrite = _writer_factory('aiffwrite', _f3, 8000, _f3.get_major_str())
-
-_f4 = formatinfo('ircam', 'pcm16')
-sdifwrite = _writer_factory('sdifwrite', _f4, 44100, _f4.get_major_str())
-
-try:
- flacread = _reader_factory('flacread', 'flac',
- formatinfo('flac', 'pcm16').get_major_str())
- _f5 = formatinfo('flac', 'pcm16')
- flacwrite = _writer_factory('flacwrite', _f5, 44100, _f5.get_major_str())
-except FlacUnsupported,e:
- print e
- print "Matlab API for FLAC is disabled"
- def missing_flacread(*args):
- raise UnimplementedError("Matlab API for FLAC is disabled on your "\
- "installation")
- flacread = missing_flacread
- flacwrite = missing_flacread
+++ /dev/null
-CC = colorgcc
-LD = gcc
-
-CFLAGS = -Wall -W
-
-winfdopen: winfdopen.o
- $(LD) $< -o $@ -lsndfile
-
-winfdopen.o: winfdopen.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-badflac: badflac.o
- $(LD) $< -o $@ -lsndfile
-
-badflac.o: badflac.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-test_badflac: badflac badflac.flac
- ./badflac badflac.flac
-
-clean:
- rm -f *.o
- rm -f badflac
+++ /dev/null
-# vim:syntax=python
-# Last Change: Fri Jun 01 12:00 PM 2007 J
-#
-mainobj = Object('winfdopen.c')
-winfd = Program(mainobj, LIBS = ['sndfile'])
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <sndfile.h>
-
-int main(int argc, char *argv[])
-{
- SF_INFO info;
- SNDFILE* file;
- sf_count_t nf;
-
- char buffer [2048] ;
- if (argc < 2) {
- fprintf(stderr, "usage: badflac filename \n");
- exit(EXIT_FAILURE);
- }
-
- info.format = 0;
- file = sf_open(argv[1], SFM_READ, &info);
- if (file == NULL) {
- fprintf(stderr, "%s:%s failed opening file %s\n", __FILE__, __func__, argv[1]);
- sf_command (file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ;
- fprintf(stderr, "sndfile error is %s:\n", buffer);
- exit(EXIT_FAILURE);
- }
-
- fprintf(stderr, "Values of seek are on this platform: SET %d, CUR %d, END %d\n",
- SEEK_SET, SEEK_CUR, SEEK_END);
-
- fprintf(stderr, "trying to seek %lld frames\n", (long long)1);
- nf = sf_seek(file, 1, SEEK_CUR);
- fprintf(stderr, "seeked through %lld frames\n", nf);
-
- sf_close(file);
-
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <stdlib.h>
-
-#include <sndfile.h>
-
-#ifdef _MSC_VER
-#define __func__ __FUNCTION__
-#else
-#include <unistd.h>
-#endif
-
-int test(const char* filename, int byfd);
-
-int main(int argc, char *argv[])
-{
- int st;
-
- if (argc < 2) {
- fprintf(stderr, "usage: %s filename \n", argv[0]);
- exit(EXIT_FAILURE);
- }
-
- st = test(argv[1], 0);
- if (st) {
- fprintf(stderr, "Error while opening directly\n");
- } else {
- fprintf(stderr, "Opening directly is fine\n");
- }
-
- st = test(argv[1], 1);
- if (st) {
- fprintf(stderr, "Error while opening by fd\n");
- } else {
- fprintf(stderr, "Opening by fd is fine\n");
- }
-
- return 0;
-}
-
-/* If byfd is true, try to open the file with sf_open_fd */
-int test(const char* filename, int byfd)
-{
- SF_INFO info;
- SNDFILE* file;
- int fid, flags, st;
- char buffer [2048];
-
- st = 0;
-
- flags = O_RDONLY;
-#if (defined (WIN32) || defined (_WIN32))
- flags |= O_BINARY;
-#endif
-
- info.format = 0;
- if (byfd) {
- fid = open(filename, flags);
- if (fid < 0) {
- fprintf(stderr, "%s:%s failed opening file %s\n", __FILE__, __func__, filename);
- return -1;
- }
-
- file = sf_open_fd(fid, SFM_READ, &info, SF_TRUE);
- } else {
- file = sf_open(filename, SFM_READ, &info);
- }
-
- if (file == NULL) {
- fprintf(stderr, "%s:%s failed opening file %s\n", __FILE__, __func__, filename);
- sf_command (file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ;
- fprintf(stderr, "sndfile error is %s:\n", buffer);
- close(fid);
- exit(EXIT_FAILURE);
- } else {
- fprintf(stderr, "%s:%s file %s has %d frames \n", __FILE__, __func__, filename, info.frames);
- }
-
- sf_close(file);
-
- return st;
-}
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Tue May 22 10:00 AM 2007 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with this library; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# TODO:
-# - find out why finally does not work with KeyboardInterrupt instances
-
-from tempfile import mkstemp
-from os import remove, popen
-
-from pysndfile import sndfile, formatinfo as format
-
-def play(input, sr = 22050):
- """play(input, sr = 22050): "play" a numpy array input
- to the audio device using aplay command, @ sampling rate
- sr.
-
- Warning: This is really crude, as it copies the numpy array
- into an audio file before writing: I am too lazy to write
- interfaces to also, windows and co..."""
- # Check inputs are OK
- if input.ndim == 1:
- nc = 1
- nframes = input.size
- else:
- (nframes, nc) = input.shape
-
- # Create tmp file
- fd, filename = mkstemp('py_player')
-
- # Copy the data into it
- b = sndfile(filename, 'write', format('wav', 'pcm16'), nc, sr)
- b.write_frames(input, nframes)
- b.close()
-
- # Play using an audio command
- try:
- cmd = "aplay %s" % filename
- popen(cmd)
- remove(filename)
- except KeyboardInterrupt, inst:
- remove(filename)
- raise inst
-
-if __name__ == '__main__':
- # Read the content of a file into numpy array, and play the numpy
- # array using the play command
- import numpy as N
- sr = 22050
- # Play a really small noise to avoid screaming in loudspeakers
- # or headphones.
- noise = 0.0001 * N.random.randn((sr))
- play(noise, sr)
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Wed Oct 03 05:00 PM 2007 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# vim:syntax=python
-
-# TODO:
-# - import format classes so that we get meaningful information from an
-# existing format
-# - better API for reader/writer, including integer formats and partial
-# reading
-# - ability to get log of sndfile ?
-# - check how to play sound under windows, OS X and other UNIX
-
-"""This module implements the wrappers around libsndfile."""
-
-__docformat__ = 'restructuredtext'
-
-#__all__ = ['sndfile', 'formatinfo']
-
-import copy
-import warnings
-
-#================
-# Load libsndfile
-#================
-import ctypes
-from ctypes import cdll, Structure, c_int, pointer, POINTER, \
- create_string_buffer, c_char_p, sizeof, string_at
-try:
- from ctypes import c_int64
-except ImportError, e:
- print "Cannot import c_int64 from ctypes: if you are on ubuntu/debian," +\
- " this is likely because ctypes was compiled with libffi. see" +\
- " https://launchpad.net/ubuntu/+source/python2.5/+bug/71914"
- raise e
-
-from numpy.ctypeslib import ndpointer
-CTYPES_MAJOR = int(ctypes.__version__.split('.')[0])
-CTYPES_MINOR = int(ctypes.__version__.split('.')[1])
-CTYPES_MICRO = int(ctypes.__version__.split('.')[2])
-if CTYPES_MAJOR < 1 or (CTYPES_MINOR == 0 and CTYPES_MICRO < 1):
- raise ImportError("version of ctypes is %s, expected at least %s" \
- % (ctypes.__version__, '1.0.1'))
-import numpy as N
-
-_SND = cdll.LoadLibrary('/usr/lib/libsndfile.so.1')
-
-#=========================
-# Definition of constants
-#=========================
-# READ/WRITE Mode
-SFM = {
- 'SFM_WRITE' : 0x20,
- 'SFM_RDWR' : 0x30,
- 'SFM_READ' : 0x10
-}
-
-# SF BOOL
-SF_BOOL = {
- 'SF_TRUE' : 1,
- 'SF_FALSE' : 0
-}
-
-# Format
-SF_FORMAT = {
- 'SF_FORMAT_VOX_ADPCM' : 0x0021,
- 'SF_FORMAT_FLOAT' : 0x0006,
- 'SF_FORMAT_PCM_S8' : 0x0001,
- 'SF_FORMAT_IMA_ADPCM' : 0x0012,
- 'SF_FORMAT_SVX' : 0x060000,
- 'SF_FORMAT_VOC' : 0x080000,
- 'SF_FORMAT_PCM_U8' : 0x0005,
- 'SF_FORMAT_ALAW' : 0x0011,
- 'SF_FORMAT_G721_32' : 0x0030,
- 'SF_FORMAT_DWVW_N' : 0x0043,
- 'SF_FORMAT_WAV' : 0x010000,
- 'SF_FORMAT_SD2' : 0x160000,
- 'SF_FORMAT_HTK' : 0x100000,
- 'SF_FORMAT_ENDMASK' : 0x30000000,
- 'SF_FORMAT_DPCM_16' : 0x0051,
- 'SF_FORMAT_DWVW_24' : 0x0042,
- 'SF_FORMAT_PCM_32' : 0x0004,
- 'SF_FORMAT_WAVEX' : 0x130000,
- 'SF_FORMAT_DOUBLE' : 0x0007,
- 'SF_FORMAT_NIST' : 0x070000,
- 'SF_FORMAT_PCM_16' : 0x0002,
- 'SF_FORMAT_RAW' : 0x040000,
- 'SF_FORMAT_W64' : 0x0B0000,
- 'SF_FORMAT_PVF' : 0x0E0000,
- 'SF_FORMAT_AU' : 0x030000,
- 'SF_FORMAT_GSM610' : 0x0020,
- 'SF_FORMAT_CAF' : 0x180000,
- 'SF_FORMAT_PAF' : 0x050000,
- 'SF_FORMAT_ULAW' : 0x0010,
- 'SF_FORMAT_MAT4' : 0x0C0000,
- 'SF_FORMAT_MAT5' : 0x0D0000,
- 'SF_FORMAT_XI' : 0x0F0000,
- 'SF_FORMAT_SUBMASK' : 0x0000FFFF,
- 'SF_FORMAT_DPCM_8' : 0x0050,
- 'SF_FORMAT_G723_24' : 0x0031,
- 'SF_FORMAT_G723_40' : 0x0032,
- 'SF_FORMAT_DWVW_16' : 0x0041,
- 'SF_FORMAT_AIFF' : 0x020000,
- 'SF_FORMAT_DWVW_12' : 0x0040,
- 'SF_FORMAT_TYPEMASK' : 0x0FFF0000,
- 'SF_FORMAT_FLAC' : 0x170000,
- 'SF_FORMAT_PCM_24' : 0x0003,
- 'SF_FORMAT_SDS' : 0x110000,
- 'SF_FORMAT_IRCAM' : 0x0A0000,
- 'SF_FORMAT_MS_ADPCM' : 0x0013,
- 'SF_FORMAT_AVR' : 0x120000
-}
-
-# ENDIANESS
-SF_ENDIAN = {
- 'SF_ENDIAN_BIG' : 0x20000000,
- 'SF_ENDIAN_FILE' : 0x00000000,
- 'SF_ENDIAN_LITTLE' : 0x10000000,
- 'SF_ENDIAN_CPU' : 0x30000000
-}
-
-# Commands
-SF_COMMAND = {
- 'SFC_GET_LIB_VERSION' : 0x1000,
- 'SFC_CALC_SIGNAL_MAX' : 0x1040,
- 'SFC_GET_DITHER_INFO' : 0x10A3,
- 'SFC_GET_LOG_INFO' : 0x1001,
- 'SFC_GET_FORMAT_SUBTYPE_COUNT' : 0x1032,
- 'SFC_FILE_TRUNCATE' : 0x1080,
- 'SFC_GET_INSTRUMENT' : 0x10D0,
- 'SFC_UPDATE_HEADER_NOW' : 0x1060,
- 'SFC_SET_DITHER_ON_WRITE' : 0x10A0,
- 'SFC_SET_NORM_DOUBLE' : 0x1012,
- 'SFC_GET_CLIPPING' : 0x10C1,
- 'SFC_SET_RAW_START_OFFSET' : 0x1090,
- 'SFC_CALC_NORM_MAX_ALL_CHANNELS' : 0x1043,
- 'SFC_SET_NORM_FLOAT' : 0x1013,
- 'SFC_SET_ADD_DITHER_ON_WRITE' : 0x1070,
- 'SFC_GET_NORM_FLOAT' : 0x1011,
- 'SFC_GET_SIGNAL_MAX' : 0x1044,
- 'SFC_GET_MAX_ALL_CHANNELS' : 0x1045,
- 'SFC_GET_FORMAT_MAJOR' : 0x1031,
- 'SFC_SET_INSTRUMENT' : 0x10D1,
- 'SFC_CALC_MAX_ALL_CHANNELS' : 0x1042,
- 'SFC_GET_DITHER_INFO_COUNT' : 0x10A2,
- 'SFC_SET_BROADCAST_INFO' : 0x10F1,
- 'SFC_SET_DITHER_ON_READ' : 0x10A1,
- 'SFC_GET_FORMAT_MAJOR_COUNT' : 0x1030,
- 'SFC_GET_FORMAT_INFO' : 0x1028,
- 'SFC_GET_SIMPLE_FORMAT_COUNT' : 0x1020,
- 'SFC_CALC_NORM_SIGNAL_MAX' : 0x1041,
- 'SFC_GET_LOOP_INFO' : 0x10E0,
- 'SFC_SET_ADD_PEAK_CHUNK' : 0x1050,
- 'SFC_SET_ADD_DITHER_ON_READ' : 0x1071,
- 'SFC_SET_SCALE_FLOAT_INT_READ' : 0x1014,
- 'SFC_GET_FORMAT_SUBTYPE' : 0x1033,
- 'SFC_TEST_IEEE_FLOAT_REPLACE' : 0x6001,
- 'SFC_SET_UPDATE_HEADER_AUTO' : 0x1061,
- 'SFC_GET_SIMPLE_FORMAT' : 0x1021,
- 'SFC_SET_CLIPPING' : 0x10C0,
- 'SFC_GET_EMBED_FILE_INFO' : 0x10B0,
- 'SFC_GET_BROADCAST_INFO' : 0x10F0,
- 'SFC_GET_NORM_DOUBLE' : 0x1010
-}
-
-SF_ERRORS = {
- 'SF_ERR_UNRECOGNISED_FORMAT' : 1,
- 'SF_ERR_NO_ERROR' : 0,
- 'SF_ERR_SYSTEM' : 2,
- 'SF_ERR_UNSUPPORTED_ENCODING' : 4,
- 'SF_ERR_MALFORMED_FILE' : 3
-}
-
-# format equivalence: dic used to create internally
-# the right enum values from user friendly strings
-py_to_snd_encoding_dic = {
- 'pcms8' : SF_FORMAT['SF_FORMAT_PCM_S8'],
- 'pcm16' : SF_FORMAT['SF_FORMAT_PCM_16'],
- 'pcm24' : SF_FORMAT['SF_FORMAT_PCM_24'],
- 'pcm32' : SF_FORMAT['SF_FORMAT_PCM_32'],
-
- 'pcmu8' : SF_FORMAT['SF_FORMAT_PCM_U8'],
-
- 'float32' : SF_FORMAT['SF_FORMAT_FLOAT'],
- 'float64' : SF_FORMAT['SF_FORMAT_DOUBLE'],
-
- 'ulaw' : SF_FORMAT['SF_FORMAT_ULAW'],
- 'alaw' : SF_FORMAT['SF_FORMAT_ALAW'],
- 'ima_adpcm' : SF_FORMAT['SF_FORMAT_IMA_ADPCM'],
- 'ms_adpcm' : SF_FORMAT['SF_FORMAT_MS_ADPCM'],
-
- 'gsm610' : SF_FORMAT['SF_FORMAT_GSM610'],
- 'vox_adpcm' : SF_FORMAT['SF_FORMAT_VOX_ADPCM'],
-
- 'g721_32' : SF_FORMAT['SF_FORMAT_G721_32'],
- 'g723_24' : SF_FORMAT['SF_FORMAT_G723_24'],
- 'g723_40' : SF_FORMAT['SF_FORMAT_G723_40'],
-
- 'dww12' : SF_FORMAT['SF_FORMAT_DWVW_12'],
- 'dww16' : SF_FORMAT['SF_FORMAT_DWVW_16'],
- 'dww24' : SF_FORMAT['SF_FORMAT_DWVW_24'],
- 'dwwN' : SF_FORMAT['SF_FORMAT_DWVW_N'],
-
- 'dpcm8' : SF_FORMAT['SF_FORMAT_DPCM_8'],
- 'dpcm16': SF_FORMAT['SF_FORMAT_DPCM_16']
-}
-
-py_to_snd_file_format_dic = {
- 'wav' : SF_FORMAT['SF_FORMAT_WAV'],
- 'aiff' : SF_FORMAT['SF_FORMAT_AIFF'],
- 'au' : SF_FORMAT['SF_FORMAT_AU'],
- 'raw' : SF_FORMAT['SF_FORMAT_RAW'],
- 'paf' : SF_FORMAT['SF_FORMAT_PAF'],
- 'svx' : SF_FORMAT['SF_FORMAT_SVX'],
- 'nist' : SF_FORMAT['SF_FORMAT_NIST'],
- 'voc' : SF_FORMAT['SF_FORMAT_VOC'],
- 'ircam' : SF_FORMAT['SF_FORMAT_IRCAM'],
- 'wav64' : SF_FORMAT['SF_FORMAT_W64'],
- 'mat4' : SF_FORMAT['SF_FORMAT_MAT4'],
- 'mat5' : SF_FORMAT['SF_FORMAT_MAT5'],
- 'pvf' : SF_FORMAT['SF_FORMAT_PVF'],
- 'xi' : SF_FORMAT['SF_FORMAT_XI'],
- 'htk' : SF_FORMAT['SF_FORMAT_HTK'],
- 'sds' : SF_FORMAT['SF_FORMAT_SDS'],
- 'avr' : SF_FORMAT['SF_FORMAT_AVR'],
- 'wavex' : SF_FORMAT['SF_FORMAT_WAVEX'],
- 'sd2' : SF_FORMAT['SF_FORMAT_SD2'],
- 'flac' : SF_FORMAT['SF_FORMAT_FLAC'],
- 'caf' : SF_FORMAT['SF_FORMAT_CAF']
-}
-
-py_to_snd_endianness_dic = {
- 'file' : SF_ENDIAN['SF_ENDIAN_FILE'],
- 'little' : SF_ENDIAN['SF_ENDIAN_LITTLE'],
- 'big' : SF_ENDIAN['SF_ENDIAN_BIG'],
- 'cpu' : SF_ENDIAN['SF_ENDIAN_CPU']
-}
-
-# Those following dic are used internally to get user-friendly values from
-# sndfile enum
-SND_TO_PY_ENCODING = \
- dict([(i, j) for j, i in py_to_snd_encoding_dic.items()])
-SND_TO_PY_FILE_FORMAT = \
- dict([(i, j) for j, i in py_to_snd_file_format_dic.items()])
-SND_TO_PY_ENDIANNESS = \
- dict([(i, j) for j, i in py_to_snd_endianness_dic.items()])
-
-#==========================================
-# Check that libsndfile is expected version
-#==========================================
-def get_libsndfile_version():
- nverbuff = 256
- verbuff = create_string_buffer(nverbuff)
- n = _SND.sf_command(c_int(0), c_int(SF_COMMAND['SFC_GET_LIB_VERSION']),
- verbuff, nverbuff)
- if n < 1:
- raise Exception("Error while getting version of libsndfile")
-
- # Transform the buffer into a string
- ver = ""
- for i in range(n):
- ver += verbuff[i]
-
- # Get major, minor and micro from version
- version = ver.split('-')[1]
- prerelease = 0
- major, minor, micro = [i for i in version.split('.')]
- try:
- micro = int(micro)
- except ValueError,e:
- print "micro is " + str(micro)
- micro, prerelease = micro.split('pre')
-
- return int(major), int(minor), int(micro), prerelease
-
-MAJOR, MINOR, MICRO, PRERELEASE = get_libsndfile_version()
-if not(MAJOR == 1):
- raise Exception("audiolab expects major version %d of libsndfile" % 1)
-if not(MICRO == 17):
- if PRERELEASE == 0:
- prestr = "No"
- else:
- prestr = "%s" % PRERELEASE
- print "WARNING libsndfile-%d.%d.%d (prerelease: %s) "\
- "this has only been tested with libsndfile 1.0.17 for now, "\
- "use at your own risk !" % (MAJOR, MINOR, MICRO, prestr)
-
-#================
-# Python wrappers
-#================
-
-#+++++++++++++++++
-# Public exception
-#+++++++++++++++++
-class PyaudioException(Exception):
- pass
-
-class InvalidFormat(PyaudioException):
- pass
-
-class PyaudioIOError(PyaudioException, IOError):
- pass
-
-class WrappingError(PyaudioException):
- pass
-
-class FlacUnsupported(RuntimeError, PyaudioException):
- pass
-
-#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-# Private classes/function (Should not be used outside this file)
-#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-class _sf_info(Structure):
- """Structure representing C structure SF_INFO"""
- _fields_ = [('frames', c_int64),
- ('samplerate', c_int),
- ('channels', c_int),
- ('format', c_int),
- ('sections', c_int),
- ('seekable', c_int)]
- def __str__(self):
- return "%d frames, sr = %d Hz, %d channels, format is %d" % \
- (self.frames, self.samplerate, self.channels, self.format)
-
-class _sf_format_info(Structure):
- """Structure representing C structure SF_FORMAT_INFO (useful for
- sf_command )"""
- _fields_ = [('format', c_int),
- ('name', c_char_p),
- ('extension', c_char_p)]
- def __str__(self):
- return "format hex is %#010x, name is %s, extension is %s" % \
- (self.format, self.name, self.extension)
-
- def __repr__(self):
- print self.__str__()
-
-class _sndfile(Structure):
- pass
-
-sf_info_p = POINTER(_sf_info)
-sndfile_p = POINTER(_sndfile)
-
-# functions args
-# TODO: is there a way to ensure that arg1 is the right kind of pointer ?
-arg1 = c_char_p
-arg2 = c_int
-arg3 = sf_info_p
-_SND.sf_open.argtypes = [arg1, arg2, arg3]
-_SND.sf_open.restype = sndfile_p
-
-arg1 = sndfile_p
-_SND.sf_close.argtypes = [arg1]
-_SND.sf_close.restype = c_int
-
-arg1 = c_int
-arg2 = c_int
-arg3 = sf_info_p
-arg4 = c_int
-_SND.sf_open_fd.argtypes = [arg1, arg2, arg3, arg4]
-_SND.sf_open_fd.restype = sndfile_p
-
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.float64)
-arg3 = c_int64
-
-# double function
-_SND.sf_readf_double.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_double.restype = c_int64
-
-_SND.sf_writef_double.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_double.restype = c_int64
-
-# float function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.float32)
-arg3 = c_int64
-_SND.sf_readf_float.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_float.restype = c_int64
-
-_SND.sf_writef_float.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_float.restype = c_int64
-
-# int function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.int32)
-arg3 = c_int64
-_SND.sf_readf_int.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_int.restype = c_int64
-
-_SND.sf_writef_int.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_int.restype = c_int64
-
-# short function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.int16)
-arg3 = c_int64
-_SND.sf_readf_short.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_short.restype = c_int64
-
-_SND.sf_writef_short.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_short.restype = c_int64
-
-# Error functions
-arg1 = sndfile_p
-_SND.sf_strerror.argtypes = [arg1]
-_SND.sf_strerror.restype = c_char_p
-
-# Function to sync data to file
-arg1 = sndfile_p
-_SND.sf_write_sync.argtypes = [arg1]
-
-# Function to seek
-arg1 = sndfile_p
-arg2 = c_int64
-arg3 = c_int
-_SND.sf_seek.argtypes = [arg1, arg2, arg3]
-_SND.sf_seek.restype = c_int64
-
-# To pass when a C function needs a NULL arg
-_cNULL = POINTER(c_int)()
-
-class _format_from_internal:
- """Class to handle audio format with sndfile.
-
- DO NOT USE THIS CLASS OUTSIDE pysndfile.py MODULE: YOU MAY CRASH YOUR
- INTERPRETER !
-
- Basically, we have 3 classes of parameters:
- - the main format: (major format), like wav, aiff, etc...
- - the subtype format: pcm, bits resolution
- - endianness: little, big, as the cpu, default of the format
-
- This class encapsulates those parameters, and can build a representation of
- them from the format integer of sf_info. This should *NOT* be used, use
- format instead, which inherits this class to build a valid format from user
- friendly arguments. """
- def __init__(self, format_integer):
- # Get the internal values which corresponds to the values libsndfile
- # can understand
- self._int_type = format_integer & SF_FORMAT['SF_FORMAT_TYPEMASK']
- self._int_encoding = format_integer & SF_FORMAT['SF_FORMAT_SUBMASK']
- self._int_endianness = format_integer & SF_FORMAT['SF_FORMAT_ENDMASK']
-
- assert format_integer == self._int_type | self._int_encoding |\
- self._int_endianness
- self._format = format_integer
-
- # Now, we need to test if the combination of format, encoding and
- # endianness is valid. sf_format_check needs also samplerate and
- # channel information, so just give a fake samplerate and channel
- # number. Looking at sndfile.c, it looks like samplerate is never
- # actually checked, and that when channels is checked, it is only
- # checked against values different than 1 or 2, so giving a value of
- # 1 to channel should be ok.
- self._sfinfo = _sf_info()
- self._sfinfo.channels = 1
- self._sfinfo.samplerate = 8000
- self._sfinfo.format = self._format
-
- ret = _SND.sf_format_check(pointer(self._sfinfo))
- if ret is not SF_BOOL['SF_TRUE']:
- raise InvalidFormat()
-
- # Get the sndfile string description of the format type
- blop = _sf_format_info()
- blop.format = self._int_type
- st = _SND.sf_command(_cNULL, SF_COMMAND['SFC_GET_FORMAT_INFO'], \
- pointer(blop), sizeof(blop))
- if st is not 0:
- if SND_TO_PY_FILE_FORMAT[self._int_type] == 'flac':
- raise FlacUnsupported("Flac is not supported by your version"\
- " of libsndfile")
- else:
- raise WrappingError("Could not get format string for format "\
- "%d, " % blop.format + "please report this problem "\
- "to the maintainer")
-
- self.format_str = blop.name
-
- # Get the sndfile string description of the format subtype
- blop.format = self._int_encoding
- st = _SND.sf_command(_cNULL, SF_COMMAND['SFC_GET_FORMAT_INFO'], \
- pointer(blop), sizeof(blop))
- if st is not 0:
- raise WrappingError()
-
- self.encoding_str = blop.name
-
- def get_format_raw(self):
- """Do not use this function !"""
- return self._format
-
- def get_major_str(self):
- """Do not use this function !"""
- return self.format_str
-
- def get_encoding_str(self):
- """Do not use this function !"""
- return self.encoding_str
-
- def get_file_format(self):
- """return user friendly file format string"""
- return SND_TO_PY_FILE_FORMAT[self._int_type]
-
- def get_encoding(self):
- """return user friendly encoding string"""
- return SND_TO_PY_ENCODING[self._int_encoding]
-
- def get_endianness(self):
- """return user friendly file format string"""
- return SND_TO_PY_ENDIANNESS[self._int_endianness]
-
- # Various function
- def is_type(self, t):
- return (self._format & SF_FORMAT['SF_FORMAT_TYPEMASK']) \
- == py_to_snd_file_format_dic[t]
-
- # Syntactic sugar
- def __str__(self):
- return "Major Format: %s, Encoding Format: %s" % \
- (self.format_str, self.encoding_str)
-
- def __repr__(self):
- return self.__str__()
-
-#+++++++++++
-# Public API
-#+++++++++++
-
-class formatinfo(_format_from_internal):
- def __init__(self, type = 'wav', encoding = 'pcm16', endianness = 'file'):
- """Build a valid format usable by the sndfile class when opening an
- audio file for writing.
-
- Blah blah
-
- :Parameters:
- type : string
- represents the major file format (wav, etc...).
- encoding : string
- represents the encoding (pcm16, etc..).
- endianness : string
- represents the endianess.
-
- Notes
- -----
-
- Valid type strings are listed by file_format_dic.keys() Valid encoding
- strings are listed by encoding_dic.keys() Valid endianness strings are
- listed by endianness_dic.keys() """
- # Keep the arguments
- self.type = type
- self.encoding = encoding
- self.endianness = endianness
-
- # Get the internal values which corresponds to the values libsndfile
- # can understand
- self._int_type = py_to_snd_file_format_dic[type]
- self._int_encoding = py_to_snd_encoding_dic[encoding]
- self._int_endianness = py_to_snd_endianness_dic[endianness]
-
- # Build the internal integer from parameters, and pass it to the super
- # class, which will do all the work
- format = self._int_type | self._int_encoding | self._int_endianness
-
- _format_from_internal.__init__(self, format)
-
-class sndfile:
- """Main class to open, read and write audio files"""
- def __init__(self, filename, mode = 'read', format = None, channels = 0, \
- samplerate = 0):
- """Create an instance of sndfile.
-
- :Parameters:
- filename : string or int
- name of the file to open (string), or file descriptor (integer)
- mode : string
- 'read' for read, 'write' for write, or 'rwrite' for read and
- write.
- format : formatinfo
- when opening a new file for writing, give the format to write
- in.
- channels : int
- number of channels.
- samplerate : int
- sampling rate.
-
- :Returns:
- sndfile: a valid sndfile object
-
- Notes
- -----
-
- format, channels and samplerate need to be given only in the write
- modes and for raw files. """
- # Check the mode is one of the expected values
- if mode == 'read':
- sfmode = SFM['SFM_READ']
- elif mode == 'write':
- sfmode = SFM['SFM_WRITE']
- if format == None:
- raise Exception("For write mode, you should provide"\
- "a format argument !")
- elif mode == 'rwrite':
- sfmode = SFM['SFM_RDWR']
- if format == None:
- raise Exception("For write mode, you should provide"\
- "a format argument !")
- else:
- raise Exception("mode %s not recognized" % str(mode))
-
- sfinfo = _sf_info()
- sfinfo_p = pointer(sfinfo)
-
- # Fill the sfinfo struct
- sfinfo.frames = c_int64(0)
- if type(channels) is not int:
- print "Warning, channels is converted to int, was %s" % \
- str(type(channels))
- sfinfo.channels = int(channels)
- else:
- sfinfo.channels = channels
-
- if type(samplerate) is not int:
- print "Warning, sampling rate is converted to int, was %s" % \
- str(type(samplerate))
- sfinfo.samplerate = int(samplerate)
- else:
- sfinfo.samplerate = samplerate
-
- sfinfo.sections = 0
- sfinfo.seekable = False
- if mode == 'read' and format == None:
- sfinfo.format = 0
- else:
- if sfinfo.channels > 256 or sfinfo.channels < 1:
- msg = "number of channels is %d, expected " \
- "between 1 and 256" % sfinfo.channels
- raise RuntimeError(msg)
- sfinfo.format = format.get_format_raw()
- if not _SND.sf_format_check(sfinfo_p):
- msg = "unknown error in format specification ?" +\
- " Please report this to the author"
- raise WrappingError()
-
- sfinfo_p = pointer(sfinfo)
- self._sfmode = sfmode
- self.hdl = 0
-
- if type(filename) == int:
- res = _SND.sf_open_fd(filename, self._sfmode, sfinfo_p,
- SF_BOOL['SF_FALSE'])
- self._byfd = True
- self.fd = filename
- self.filename = ""
- else:
- res = _SND.sf_open(filename, self._sfmode, sfinfo_p)
- self._byfd = False
- self.filename = filename
-
- try:
- # If res is NULL, this statement will raise a ValueError exception
- a = res[0]
- except ValueError:
- if self._byfd:
- msg = "error while opening file descriptor %d\n\t->" % self.fd
- else:
- msg = "error while opening file %s\n\t-> " % self.filename
- msg += _SND.sf_strerror(res)
- if self._byfd:
- msg += """
-(Check that the mode argument passed to sndfile is the same than the one used
-when getting the file descriptor, eg do not pass 'read' to sndfile if you
-passed 'write' to open to get the file descriptor. If you are on win32, you are
-out of luck, because its implementation of POSIX open is broken)"""
- raise IOError("error while opening %s\n\t->%s" % (filename, msg))
-
- if mode == 'read':
- tmp = _format_from_internal(sfinfo.format)
- self._format = formatinfo(tmp.get_file_format(), \
- tmp.get_encoding(), tmp.get_endianness())
- else:
- self._format = format
-
- self._sfinfo = sfinfo
- self.hdl = res
-
- if self.get_file_format() == 'flac':
- def SeekNotEnabled(self, *args):
- raise FlacUnsupported("seek not supported on Flac by default,"\
- " because\n some version of FLAC libraries are buggy."\
- " Read FLAC_SUPPORT.txt")
- self.seek = SeekNotEnabled
- else:
- self.seek = self._seek
-
- def __del__(self, close_func = _SND.sf_close):
- # Stupid python needs the close_func, otherwise
- # it may clean ctypes before calling here
- if hasattr(self,'hdl'):
- if not(self.hdl == 0):
- close_func(self.hdl)
- self.hdl = 0
-
- def close(self):
- """close the file."""
- self.__del__()
-
- def sync(self):
- """call the operating system's function to force the writing of all
- file cache buffers to disk the file.
-
- No effect if file is open as read"""
- _SND.sf_write_sync(self.hdl)
-
- def _seek(self, offset, whence = 0, mode = 'rw'):
- """similar to python seek function, taking only in account audio data.
-
- :Parameters:
- offset : int
- the number of frames (eg two samples for stereo files) to move
- relatively to position set by whence.
- whence : int
- only 0 (beginning), 1 (current) and 2 (end of the file) are
- valid.
- mode : string
- If set to 'rw', both read and write pointers are updated. If
- 'r' is given, only read pointer is updated, if 'w', only the
- write one is (this may of course make sense only if you open
- the file in a certain mode).
-
- Notes
- -----
-
- - one only takes into accound audio data.
- - if an invalid seek is given (beyond or before the file), a
- PyaudioIOError is launched."""
- c_offset = _num2int64(offset)
- if mode == 'rw':
- # Update both read and write pointers
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- elif mode == 'r':
- whence = whence | SFM['SFM_READ']
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- elif mode == 'w':
- whence = whence | SFM['SFM_WRITE']
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- else:
- raise ValueError("mode should be one of 'r', 'w' or 'rw' only")
-
- if st == -1:
- msg = "Error while seeking, libsndfile error is %s" \
- % (_SND.sf_strerror(self.hdl))
- raise PyaudioIOError(msg)
- return st
-
- # Functions to get informations about the file
- def get_nframes(self):
- """ Return the number of frames of the file"""
- if self._sfmode == SFM['SFM_READ']:
- # XXX: is this reliable for any file (think pipe and co ?)
- return self._sfinfo.frames
- else:
- # In write/rwrite mode, the only reliable way to get the number of
- # frames is to use seek.
- raise NotImplementedError("Sorry, getting the current number of"
- "frames in write modes is not supported yet")
-
- def get_samplerate(self):
- """ Return the samplerate in Hz of the file"""
- return self._sfinfo.samplerate
-
- def get_channels(self):
- """ Return the number of channels of the file"""
- return self._sfinfo.channels
-
- def get_file_format(self):
- """return user friendly file format string"""
- return SND_TO_PY_FILE_FORMAT[self._format._int_type]
-
- def get_encoding(self):
- """return user friendly encoding string"""
- return SND_TO_PY_ENCODING[self._format._int_encoding]
-
- def get_endianness(self):
- """return user friendly file format string"""
- return SND_TO_PY_ENDIANNESS[self._format._int_endianness]
-
- #------------------
- # Functions to read
- #------------------
- def read_frames(self, nframes, dtype = N.float64):
- """Read nframes frames of the file.
-
- :Parameters:
- nframes : int
- number of frames to read.
- dtype : numpy dtype
- dtype of the returned array containing read data (see note).
-
- Notes
- -----
-
- - read_frames updates the read pointer.
- - One column is one channel.
- - if float are requested when the file contains integer data, you will
- get normalized data (that is the max possible integer will be 1.0,
- and the minimal possible value -1.0).
- - if integers are requested when the file contains floating point data,
- it may give wrong results because there is an ambiguity: if the
- floating data are normalized, you can get a file with only 0 !
- Getting integer data from files encoded in normalized floating point
- is not supported (yet: sndfile supports it)."""
- c_nframes = _num2int64(nframes)
- if c_nframes < 0:
- raise ValueError("number of frames has to be >= 0")
-
- # XXX: inout argument
- if self._sfinfo.channels > 1:
- y = N.zeros((nframes, self._sfinfo.channels), dtype)
- else:
- y = N.zeros(nframes, dtype)
-
- if dtype == N.float64:
- res = _SND.sf_readf_double(self.hdl, y, c_nframes)
- elif dtype == N.float32:
- res = _SND.sf_readf_float(self.hdl, y, c_nframes)
- elif dtype == N.int32:
- res = _SND.sf_readf_int(self.hdl, y, c_nframes)
- elif dtype == N.int16:
- res = _SND.sf_readf_short(self.hdl, y, c_nframes)
- else:
- RuntimeError("Sorry, only float, double, int and short read " + \
- "supported for now")
-
- if not(res == nframes):
- msg = "Read %d frames, expected to read %d" % (res, nframes)
- msg += ", libsndfile last msg is \n\t%s" \
- % _SND.sf_strerror(self.hdl)
- raise IOError(msg)
-
- return y
-
- #-------------------
- # Functions to write
- #-------------------
- # TODO: Think about overflow vs type of input, etc...
- def write_frames(self, input, nframes = -1):
- """write data to file.
-
- :Parameters:
- input : ndarray
- array containing data to write.
- nframes : int
- number of frames to write.
-
- Notes
- -----
-
- - one channel is one column
- - updates the write pointer.
- - if float are given when the file contains integer data, you should
- put normalized data (that is the range [-1..1] will be written as the
- maximum range allowed by the integer bitwidth)."""
- # First, get the number of channels and frames from input
- if input.ndim == 1:
- nc = 1
- else:
- if input.ndim > 2:
- raise Exception("Expect array of rank <= 2, got %d" \
- % input.ndim)
- nc = input.shape[1]
-
- if nframes == -1:
- nframes = N.size(input)
- # Number of channels should be the one expected
- if not(nc == self._sfinfo.channels):
- raise Exception("Expected %d channels, got %d" % \
- (self._sfinfo.channels, nc))
-
- # Writing to the file
- c_nframes = _num2int64(nframes)
- if c_nframes < 0:
- raise ValueError("number of frames has to be >= 0")
-
- input = N.require(input, requirements = 'C')
-
- if input.dtype == N.float32:
- if self._check_overflow(input):
- warnings.warn("Warning, overflow detected when writing.")
- res = _SND.sf_writef_float(self.hdl, input, c_nframes)
- elif input.dtype == N.float64:
- self._check_overflow(input)
- if self._check_overflow(input):
- warnings.warn("Warning, overflow detected when writing.")
- res = _SND.sf_writef_double(self.hdl, input, c_nframes)
- elif input.dtype == N.int32:
- res = _SND.sf_writef_int(self.hdl, input, c_nframes)
- elif input.dtype == N.int16:
- res = _SND.sf_writef_short(self.hdl, input, c_nframes)
- else:
- raise Exception("type of input not understood: input should"
- " be float64 or float32""")
-
- if not(res == nframes):
- raise IOError("write %d frames, expected to write %d" \
- % res, nframes)
-
- def _check_overflow(self, data):
- if N.max(data ** 2) >= 1.:
- return True
- return False
-
- # Syntactic sugar
- def __repr__(self):
- return self.__str__()
-
- def __str__(self):
- repstr = "----------------------------------------\n"
- if self._byfd:
- repstr += "File : %d (opened by file descriptor)\n" % self.fd
- else:
- repstr += "File : %s\n" % self.filename
- repstr += "Channels : %d\n" % self._sfinfo.channels
- repstr += "Sample rate : %d\n" % self._sfinfo.samplerate
- repstr += "Frames : %d\n" % self._sfinfo.frames
- repstr += "Raw Format : %#010x -> %s\n" % \
- (self._format.get_format_raw(), self._format.get_major_str())
- repstr += "File format : %s\n" % self.get_file_format()
- repstr += "Encoding : %s\n" % self.get_encoding()
- repstr += "Endianness : %s\n" % self.get_endianness()
- repstr += "Sections : %d\n" % self._sfinfo.sections
- if self._sfinfo.seekable:
- seek = 'True'
- else:
- seek = 'False'
- repstr += "Seekable : %s\n" % seek
- repstr += "Duration : %s\n" % self._generate_duration_str()
- return repstr
-
- def _generate_duration_str(self):
- if self._sfinfo.samplerate < 1:
- return None
- tsec = self._sfinfo.frames / self._sfinfo.samplerate
- hrs = tsec / 60 / 60
- tsec = tsec % (60 ** 2)
- mins = tsec / 60
- tsec = tsec % 60
- secs = tsec
- ms = 1000 * self._sfinfo.frames / self._sfinfo.samplerate % 1000
-
- return "%02d:%02d:%02d.%3d" % (hrs, mins, secs, ms)
-
-def supported_format():
- # XXX: broken
- return py_to_snd_file_format_dic.keys()
-
-def supported_endianness():
- # XXX: broken
- return py_to_snd_endianness_dic.keys()
-
-def supported_encoding():
- # XXX: broken
- return py_to_snd_encoding_dic.keys()
-
-def _num2int64(value):
- """ Convert a python objet to a c_int64, safely."""
- if not (type(value) == int or type(value) == long):
- value = long(value)
- print "Warning, converting %s to long" % str(value)
- c_value = c_int64(value)
- if not c_value.value == value:
- raise RuntimeError("Error while converting %s to a c_int64"\
- ", maybe %s is too big ?" % str(value))
- return c_value
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Wed Oct 03 05:00 PM 2007 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# vim:syntax=python
-
-# TODO:
-# - import format classes so that we get meaningful information from an
-# existing format
-# - better API for reader/writer, including integer formats and partial
-# reading
-# - ability to get log of sndfile ?
-# - check how to play sound under windows, OS X and other UNIX
-
-"""This module implements the wrappers around libsndfile."""
-
-__docformat__ = 'restructuredtext'
-
-#__all__ = ['sndfile', 'formatinfo']
-
-import copy
-import warnings
-
-#================
-# Load libsndfile
-#================
-import ctypes
-from ctypes import cdll, Structure, c_int, pointer, POINTER, \
- create_string_buffer, c_char_p, sizeof, string_at
-try:
- from ctypes import c_int64
-except ImportError, e:
- print "Cannot import c_int64 from ctypes: if you are on ubuntu/debian," +\
- " this is likely because ctypes was compiled with libffi. see" +\
- " https://launchpad.net/ubuntu/+source/python2.5/+bug/71914"
- raise e
-
-from numpy.ctypeslib import ndpointer
-CTYPES_MAJOR = int(ctypes.__version__.split('.')[0])
-CTYPES_MINOR = int(ctypes.__version__.split('.')[1])
-CTYPES_MICRO = int(ctypes.__version__.split('.')[2])
-if CTYPES_MAJOR < 1 or (CTYPES_MINOR == 0 and CTYPES_MICRO < 1):
- raise ImportError("version of ctypes is %s, expected at least %s" \
- % (ctypes.__version__, '1.0.1'))
-import numpy as N
-
-_SND = cdll.LoadLibrary('%SHARED_LOCATION%')
-
-#=========================
-# Definition of constants
-#=========================
-# READ/WRITE Mode
-%SFM%
-
-# SF BOOL
-%SF_BOOL%
-
-# Format
-%SF_FORMAT%
-
-# ENDIANESS
-%SF_ENDIAN%
-
-# Commands
-%SF_COMMAND%
-
-%SF_ERR%
-
-# format equivalence: dic used to create internally
-# the right enum values from user friendly strings
-py_to_snd_encoding_dic = {
- 'pcms8' : SF_FORMAT['SF_FORMAT_PCM_S8'],
- 'pcm16' : SF_FORMAT['SF_FORMAT_PCM_16'],
- 'pcm24' : SF_FORMAT['SF_FORMAT_PCM_24'],
- 'pcm32' : SF_FORMAT['SF_FORMAT_PCM_32'],
-
- 'pcmu8' : SF_FORMAT['SF_FORMAT_PCM_U8'],
-
- 'float32' : SF_FORMAT['SF_FORMAT_FLOAT'],
- 'float64' : SF_FORMAT['SF_FORMAT_DOUBLE'],
-
- 'ulaw' : SF_FORMAT['SF_FORMAT_ULAW'],
- 'alaw' : SF_FORMAT['SF_FORMAT_ALAW'],
- 'ima_adpcm' : SF_FORMAT['SF_FORMAT_IMA_ADPCM'],
- 'ms_adpcm' : SF_FORMAT['SF_FORMAT_MS_ADPCM'],
-
- 'gsm610' : SF_FORMAT['SF_FORMAT_GSM610'],
- 'vox_adpcm' : SF_FORMAT['SF_FORMAT_VOX_ADPCM'],
-
- 'g721_32' : SF_FORMAT['SF_FORMAT_G721_32'],
- 'g723_24' : SF_FORMAT['SF_FORMAT_G723_24'],
- 'g723_40' : SF_FORMAT['SF_FORMAT_G723_40'],
-
- 'dww12' : SF_FORMAT['SF_FORMAT_DWVW_12'],
- 'dww16' : SF_FORMAT['SF_FORMAT_DWVW_16'],
- 'dww24' : SF_FORMAT['SF_FORMAT_DWVW_24'],
- 'dwwN' : SF_FORMAT['SF_FORMAT_DWVW_N'],
-
- 'dpcm8' : SF_FORMAT['SF_FORMAT_DPCM_8'],
- 'dpcm16': SF_FORMAT['SF_FORMAT_DPCM_16']
-}
-
-py_to_snd_file_format_dic = {
- 'wav' : SF_FORMAT['SF_FORMAT_WAV'],
- 'aiff' : SF_FORMAT['SF_FORMAT_AIFF'],
- 'au' : SF_FORMAT['SF_FORMAT_AU'],
- 'raw' : SF_FORMAT['SF_FORMAT_RAW'],
- 'paf' : SF_FORMAT['SF_FORMAT_PAF'],
- 'svx' : SF_FORMAT['SF_FORMAT_SVX'],
- 'nist' : SF_FORMAT['SF_FORMAT_NIST'],
- 'voc' : SF_FORMAT['SF_FORMAT_VOC'],
- 'ircam' : SF_FORMAT['SF_FORMAT_IRCAM'],
- 'wav64' : SF_FORMAT['SF_FORMAT_W64'],
- 'mat4' : SF_FORMAT['SF_FORMAT_MAT4'],
- 'mat5' : SF_FORMAT['SF_FORMAT_MAT5'],
- 'pvf' : SF_FORMAT['SF_FORMAT_PVF'],
- 'xi' : SF_FORMAT['SF_FORMAT_XI'],
- 'htk' : SF_FORMAT['SF_FORMAT_HTK'],
- 'sds' : SF_FORMAT['SF_FORMAT_SDS'],
- 'avr' : SF_FORMAT['SF_FORMAT_AVR'],
- 'wavex' : SF_FORMAT['SF_FORMAT_WAVEX'],
- 'sd2' : SF_FORMAT['SF_FORMAT_SD2'],
- 'flac' : SF_FORMAT['SF_FORMAT_FLAC'],
- 'caf' : SF_FORMAT['SF_FORMAT_CAF']
-}
-
-py_to_snd_endianness_dic = {
- 'file' : SF_ENDIAN['SF_ENDIAN_FILE'],
- 'little' : SF_ENDIAN['SF_ENDIAN_LITTLE'],
- 'big' : SF_ENDIAN['SF_ENDIAN_BIG'],
- 'cpu' : SF_ENDIAN['SF_ENDIAN_CPU']
-}
-
-# Those following dic are used internally to get user-friendly values from
-# sndfile enum
-SND_TO_PY_ENCODING = \
- dict([(i, j) for j, i in py_to_snd_encoding_dic.items()])
-SND_TO_PY_FILE_FORMAT = \
- dict([(i, j) for j, i in py_to_snd_file_format_dic.items()])
-SND_TO_PY_ENDIANNESS = \
- dict([(i, j) for j, i in py_to_snd_endianness_dic.items()])
-
-#==========================================
-# Check that libsndfile is expected version
-#==========================================
-def get_libsndfile_version():
- nverbuff = 256
- verbuff = create_string_buffer(nverbuff)
- n = _SND.sf_command(c_int(0), c_int(SF_COMMAND['SFC_GET_LIB_VERSION']),
- verbuff, nverbuff)
- if n < 1:
- raise Exception("Error while getting version of libsndfile")
-
- # Transform the buffer into a string
- ver = ""
- for i in range(n):
- ver += verbuff[i]
-
- # Get major, minor and micro from version
- version = ver.split('-')[1]
- prerelease = 0
- major, minor, micro = [i for i in version.split('.')]
- try:
- micro = int(micro)
- except ValueError,e:
- print "micro is " + str(micro)
- micro, prerelease = micro.split('pre')
-
- return int(major), int(minor), int(micro), prerelease
-
-MAJOR, MINOR, MICRO, PRERELEASE = get_libsndfile_version()
-if not(MAJOR == 1):
- raise Exception("audiolab expects major version %d of libsndfile" % 1)
-if not(MICRO == 17):
- if PRERELEASE == 0:
- prestr = "No"
- else:
- prestr = "%s" % PRERELEASE
- print "WARNING libsndfile-%d.%d.%d (prerelease: %s) "\
- "this has only been tested with libsndfile 1.0.17 for now, "\
- "use at your own risk !" % (MAJOR, MINOR, MICRO, prestr)
-
-#================
-# Python wrappers
-#================
-
-#+++++++++++++++++
-# Public exception
-#+++++++++++++++++
-class PyaudioException(Exception):
- pass
-
-class InvalidFormat(PyaudioException):
- pass
-
-class PyaudioIOError(PyaudioException, IOError):
- pass
-
-class WrappingError(PyaudioException):
- pass
-
-class FlacUnsupported(RuntimeError, PyaudioException):
- pass
-
-#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-# Private classes/function (Should not be used outside this file)
-#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-class _sf_info(Structure):
- """Structure representing C structure SF_INFO"""
- _fields_ = [('frames', c_int64),
- ('samplerate', c_int),
- ('channels', c_int),
- ('format', c_int),
- ('sections', c_int),
- ('seekable', c_int)]
- def __str__(self):
- return "%d frames, sr = %d Hz, %d channels, format is %d" % \
- (self.frames, self.samplerate, self.channels, self.format)
-
-class _sf_format_info(Structure):
- """Structure representing C structure SF_FORMAT_INFO (useful for
- sf_command )"""
- _fields_ = [('format', c_int),
- ('name', c_char_p),
- ('extension', c_char_p)]
- def __str__(self):
- return "format hex is %#010x, name is %s, extension is %s" % \
- (self.format, self.name, self.extension)
-
- def __repr__(self):
- print self.__str__()
-
-class _sndfile(Structure):
- pass
-
-sf_info_p = POINTER(_sf_info)
-sndfile_p = POINTER(_sndfile)
-
-# functions args
-# TODO: is there a way to ensure that arg1 is the right kind of pointer ?
-arg1 = c_char_p
-arg2 = c_int
-arg3 = sf_info_p
-_SND.sf_open.argtypes = [arg1, arg2, arg3]
-_SND.sf_open.restype = sndfile_p
-
-arg1 = sndfile_p
-_SND.sf_close.argtypes = [arg1]
-_SND.sf_close.restype = c_int
-
-arg1 = c_int
-arg2 = c_int
-arg3 = sf_info_p
-arg4 = c_int
-_SND.sf_open_fd.argtypes = [arg1, arg2, arg3, arg4]
-_SND.sf_open_fd.restype = sndfile_p
-
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.float64)
-arg3 = c_int64
-
-# double function
-_SND.sf_readf_double.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_double.restype = c_int64
-
-_SND.sf_writef_double.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_double.restype = c_int64
-
-# float function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.float32)
-arg3 = c_int64
-_SND.sf_readf_float.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_float.restype = c_int64
-
-_SND.sf_writef_float.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_float.restype = c_int64
-
-# int function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.int32)
-arg3 = c_int64
-_SND.sf_readf_int.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_int.restype = c_int64
-
-_SND.sf_writef_int.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_int.restype = c_int64
-
-# short function
-arg1 = sndfile_p
-arg2 = ndpointer(dtype=N.int16)
-arg3 = c_int64
-_SND.sf_readf_short.argtypes = [arg1, arg2, arg3]
-_SND.sf_readf_short.restype = c_int64
-
-_SND.sf_writef_short.argtypes = [arg1, arg2, arg3]
-_SND.sf_writef_short.restype = c_int64
-
-# Error functions
-arg1 = sndfile_p
-_SND.sf_strerror.argtypes = [arg1]
-_SND.sf_strerror.restype = c_char_p
-
-# Function to sync data to file
-arg1 = sndfile_p
-_SND.sf_write_sync.argtypes = [arg1]
-
-# Function to seek
-arg1 = sndfile_p
-arg2 = c_int64
-arg3 = c_int
-_SND.sf_seek.argtypes = [arg1, arg2, arg3]
-_SND.sf_seek.restype = c_int64
-
-# To pass when a C function needs a NULL arg
-_cNULL = POINTER(c_int)()
-
-class _format_from_internal:
- """Class to handle audio format with sndfile.
-
- DO NOT USE THIS CLASS OUTSIDE pysndfile.py MODULE: YOU MAY CRASH YOUR
- INTERPRETER !
-
- Basically, we have 3 classes of parameters:
- - the main format: (major format), like wav, aiff, etc...
- - the subtype format: pcm, bits resolution
- - endianness: little, big, as the cpu, default of the format
-
- This class encapsulates those parameters, and can build a representation of
- them from the format integer of sf_info. This should *NOT* be used, use
- format instead, which inherits this class to build a valid format from user
- friendly arguments. """
- def __init__(self, format_integer):
- # Get the internal values which corresponds to the values libsndfile
- # can understand
- self._int_type = format_integer & SF_FORMAT['SF_FORMAT_TYPEMASK']
- self._int_encoding = format_integer & SF_FORMAT['SF_FORMAT_SUBMASK']
- self._int_endianness = format_integer & SF_FORMAT['SF_FORMAT_ENDMASK']
-
- assert format_integer == self._int_type | self._int_encoding |\
- self._int_endianness
- self._format = format_integer
-
- # Now, we need to test if the combination of format, encoding and
- # endianness is valid. sf_format_check needs also samplerate and
- # channel information, so just give a fake samplerate and channel
- # number. Looking at sndfile.c, it looks like samplerate is never
- # actually checked, and that when channels is checked, it is only
- # checked against values different than 1 or 2, so giving a value of
- # 1 to channel should be ok.
- self._sfinfo = _sf_info()
- self._sfinfo.channels = 1
- self._sfinfo.samplerate = 8000
- self._sfinfo.format = self._format
-
- ret = _SND.sf_format_check(pointer(self._sfinfo))
- if ret is not SF_BOOL['SF_TRUE']:
- raise InvalidFormat()
-
- # Get the sndfile string description of the format type
- blop = _sf_format_info()
- blop.format = self._int_type
- st = _SND.sf_command(_cNULL, SF_COMMAND['SFC_GET_FORMAT_INFO'], \
- pointer(blop), sizeof(blop))
- if st is not 0:
- if SND_TO_PY_FILE_FORMAT[self._int_type] == 'flac':
- raise FlacUnsupported("Flac is not supported by your version"\
- " of libsndfile")
- else:
- raise WrappingError("Could not get format string for format "\
- "%d, " % blop.format + "please report this problem "\
- "to the maintainer")
-
- self.format_str = blop.name
-
- # Get the sndfile string description of the format subtype
- blop.format = self._int_encoding
- st = _SND.sf_command(_cNULL, SF_COMMAND['SFC_GET_FORMAT_INFO'], \
- pointer(blop), sizeof(blop))
- if st is not 0:
- raise WrappingError()
-
- self.encoding_str = blop.name
-
- def get_format_raw(self):
- """Do not use this function !"""
- return self._format
-
- def get_major_str(self):
- """Do not use this function !"""
- return self.format_str
-
- def get_encoding_str(self):
- """Do not use this function !"""
- return self.encoding_str
-
- def get_file_format(self):
- """return user friendly file format string"""
- return SND_TO_PY_FILE_FORMAT[self._int_type]
-
- def get_encoding(self):
- """return user friendly encoding string"""
- return SND_TO_PY_ENCODING[self._int_encoding]
-
- def get_endianness(self):
- """return user friendly file format string"""
- return SND_TO_PY_ENDIANNESS[self._int_endianness]
-
- # Various function
- def is_type(self, t):
- return (self._format & SF_FORMAT['SF_FORMAT_TYPEMASK']) \
- == py_to_snd_file_format_dic[t]
-
- # Syntactic sugar
- def __str__(self):
- return "Major Format: %s, Encoding Format: %s" % \
- (self.format_str, self.encoding_str)
-
- def __repr__(self):
- return self.__str__()
-
-#+++++++++++
-# Public API
-#+++++++++++
-
-class formatinfo(_format_from_internal):
- def __init__(self, type = 'wav', encoding = 'pcm16', endianness = 'file'):
- """Build a valid format usable by the sndfile class when opening an
- audio file for writing.
-
- Blah blah
-
- :Parameters:
- type : string
- represents the major file format (wav, etc...).
- encoding : string
- represents the encoding (pcm16, etc..).
- endianness : string
- represents the endianess.
-
- Notes
- -----
-
- Valid type strings are listed by file_format_dic.keys() Valid encoding
- strings are listed by encoding_dic.keys() Valid endianness strings are
- listed by endianness_dic.keys() """
- # Keep the arguments
- self.type = type
- self.encoding = encoding
- self.endianness = endianness
-
- # Get the internal values which corresponds to the values libsndfile
- # can understand
- self._int_type = py_to_snd_file_format_dic[type]
- self._int_encoding = py_to_snd_encoding_dic[encoding]
- self._int_endianness = py_to_snd_endianness_dic[endianness]
-
- # Build the internal integer from parameters, and pass it to the super
- # class, which will do all the work
- format = self._int_type | self._int_encoding | self._int_endianness
-
- _format_from_internal.__init__(self, format)
-
-class sndfile:
- """Main class to open, read and write audio files"""
- def __init__(self, filename, mode = 'read', format = None, channels = 0, \
- samplerate = 0):
- """Create an instance of sndfile.
-
- :Parameters:
- filename : string or int
- name of the file to open (string), or file descriptor (integer)
- mode : string
- 'read' for read, 'write' for write, or 'rwrite' for read and
- write.
- format : formatinfo
- when opening a new file for writing, give the format to write
- in.
- channels : int
- number of channels.
- samplerate : int
- sampling rate.
-
- :Returns:
- sndfile: a valid sndfile object
-
- Notes
- -----
-
- format, channels and samplerate need to be given only in the write
- modes and for raw files. """
- # Check the mode is one of the expected values
- if mode == 'read':
- sfmode = SFM['SFM_READ']
- elif mode == 'write':
- sfmode = SFM['SFM_WRITE']
- if format == None:
- raise Exception("For write mode, you should provide"\
- "a format argument !")
- elif mode == 'rwrite':
- sfmode = SFM['SFM_RDWR']
- if format == None:
- raise Exception("For write mode, you should provide"\
- "a format argument !")
- else:
- raise Exception("mode %s not recognized" % str(mode))
-
- sfinfo = _sf_info()
- sfinfo_p = pointer(sfinfo)
-
- # Fill the sfinfo struct
- sfinfo.frames = c_int64(0)
- if type(channels) is not int:
- print "Warning, channels is converted to int, was %s" % \
- str(type(channels))
- sfinfo.channels = int(channels)
- else:
- sfinfo.channels = channels
-
- if type(samplerate) is not int:
- print "Warning, sampling rate is converted to int, was %s" % \
- str(type(samplerate))
- sfinfo.samplerate = int(samplerate)
- else:
- sfinfo.samplerate = samplerate
-
- sfinfo.sections = 0
- sfinfo.seekable = False
- if mode == 'read' and format == None:
- sfinfo.format = 0
- else:
- if sfinfo.channels > 256 or sfinfo.channels < 1:
- msg = "number of channels is %d, expected " \
- "between 1 and 256" % sfinfo.channels
- raise RuntimeError(msg)
- sfinfo.format = format.get_format_raw()
- if not _SND.sf_format_check(sfinfo_p):
- msg = "unknown error in format specification ?" +\
- " Please report this to the author"
- raise WrappingError()
-
- sfinfo_p = pointer(sfinfo)
- self._sfmode = sfmode
- self.hdl = 0
-
- if type(filename) == int:
- res = _SND.sf_open_fd(filename, self._sfmode, sfinfo_p,
- SF_BOOL['SF_FALSE'])
- self._byfd = True
- self.fd = filename
- self.filename = ""
- else:
- res = _SND.sf_open(filename, self._sfmode, sfinfo_p)
- self._byfd = False
- self.filename = filename
-
- try:
- # If res is NULL, this statement will raise a ValueError exception
- a = res[0]
- except ValueError:
- if self._byfd:
- msg = "error while opening file descriptor %d\n\t->" % self.fd
- else:
- msg = "error while opening file %s\n\t-> " % self.filename
- msg += _SND.sf_strerror(res)
- if self._byfd:
- msg += """
-(Check that the mode argument passed to sndfile is the same than the one used
-when getting the file descriptor, eg do not pass 'read' to sndfile if you
-passed 'write' to open to get the file descriptor. If you are on win32, you are
-out of luck, because its implementation of POSIX open is broken)"""
- raise IOError("error while opening %s\n\t->%s" % (filename, msg))
-
- if mode == 'read':
- tmp = _format_from_internal(sfinfo.format)
- self._format = formatinfo(tmp.get_file_format(), \
- tmp.get_encoding(), tmp.get_endianness())
- else:
- self._format = format
-
- self._sfinfo = sfinfo
- self.hdl = res
-
- if self.get_file_format() == 'flac':
- def SeekNotEnabled(self, *args):
- raise FlacUnsupported("seek not supported on Flac by default,"\
- " because\n some version of FLAC libraries are buggy."\
- " Read FLAC_SUPPORT.txt")
- self.seek = SeekNotEnabled
- else:
- self.seek = self._seek
-
- def __del__(self, close_func = _SND.sf_close):
- # Stupid python needs the close_func, otherwise
- # it may clean ctypes before calling here
- if hasattr(self,'hdl'):
- if not(self.hdl == 0):
- close_func(self.hdl)
- self.hdl = 0
-
- def close(self):
- """close the file."""
- self.__del__()
-
- def sync(self):
- """call the operating system's function to force the writing of all
- file cache buffers to disk the file.
-
- No effect if file is open as read"""
- _SND.sf_write_sync(self.hdl)
-
- def _seek(self, offset, whence = 0, mode = 'rw'):
- """similar to python seek function, taking only in account audio data.
-
- :Parameters:
- offset : int
- the number of frames (eg two samples for stereo files) to move
- relatively to position set by whence.
- whence : int
- only 0 (beginning), 1 (current) and 2 (end of the file) are
- valid.
- mode : string
- If set to 'rw', both read and write pointers are updated. If
- 'r' is given, only read pointer is updated, if 'w', only the
- write one is (this may of course make sense only if you open
- the file in a certain mode).
-
- Notes
- -----
-
- - one only takes into accound audio data.
- - if an invalid seek is given (beyond or before the file), a
- PyaudioIOError is launched."""
- c_offset = _num2int64(offset)
- if mode == 'rw':
- # Update both read and write pointers
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- elif mode == 'r':
- whence = whence | SFM['SFM_READ']
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- elif mode == 'w':
- whence = whence | SFM['SFM_WRITE']
- st = _SND.sf_seek(self.hdl, c_offset, whence)
- else:
- raise ValueError("mode should be one of 'r', 'w' or 'rw' only")
-
- if st == -1:
- msg = "Error while seeking, libsndfile error is %s" \
- % (_SND.sf_strerror(self.hdl))
- raise PyaudioIOError(msg)
- return st
-
- # Functions to get informations about the file
- def get_nframes(self):
- """ Return the number of frames of the file"""
- if self._sfmode == SFM['SFM_READ']:
- # XXX: is this reliable for any file (think pipe and co ?)
- return self._sfinfo.frames
- else:
- # In write/rwrite mode, the only reliable way to get the number of
- # frames is to use seek.
- raise NotImplementedError("Sorry, getting the current number of"
- "frames in write modes is not supported yet")
-
- def get_samplerate(self):
- """ Return the samplerate in Hz of the file"""
- return self._sfinfo.samplerate
-
- def get_channels(self):
- """ Return the number of channels of the file"""
- return self._sfinfo.channels
-
- def get_file_format(self):
- """return user friendly file format string"""
- return SND_TO_PY_FILE_FORMAT[self._format._int_type]
-
- def get_encoding(self):
- """return user friendly encoding string"""
- return SND_TO_PY_ENCODING[self._format._int_encoding]
-
- def get_endianness(self):
- """return user friendly file format string"""
- return SND_TO_PY_ENDIANNESS[self._format._int_endianness]
-
- #------------------
- # Functions to read
- #------------------
- def read_frames(self, nframes, dtype = N.float64):
- """Read nframes frames of the file.
-
- :Parameters:
- nframes : int
- number of frames to read.
- dtype : numpy dtype
- dtype of the returned array containing read data (see note).
-
- Notes
- -----
-
- - read_frames updates the read pointer.
- - One column is one channel.
- - if float are requested when the file contains integer data, you will
- get normalized data (that is the max possible integer will be 1.0,
- and the minimal possible value -1.0).
- - if integers are requested when the file contains floating point data,
- it may give wrong results because there is an ambiguity: if the
- floating data are normalized, you can get a file with only 0 !
- Getting integer data from files encoded in normalized floating point
- is not supported (yet: sndfile supports it)."""
- c_nframes = _num2int64(nframes)
- if c_nframes < 0:
- raise ValueError("number of frames has to be >= 0")
-
- # XXX: inout argument
- if self._sfinfo.channels > 1:
- y = N.zeros((nframes, self._sfinfo.channels), dtype)
- else:
- y = N.zeros(nframes, dtype)
-
- if dtype == N.float64:
- res = _SND.sf_readf_double(self.hdl, y, c_nframes)
- elif dtype == N.float32:
- res = _SND.sf_readf_float(self.hdl, y, c_nframes)
- elif dtype == N.int32:
- res = _SND.sf_readf_int(self.hdl, y, c_nframes)
- elif dtype == N.int16:
- res = _SND.sf_readf_short(self.hdl, y, c_nframes)
- else:
- RuntimeError("Sorry, only float, double, int and short read " + \
- "supported for now")
-
- if not(res == nframes):
- msg = "Read %d frames, expected to read %d" % (res, nframes)
- msg += ", libsndfile last msg is \n\t%s" \
- % _SND.sf_strerror(self.hdl)
- raise IOError(msg)
-
- return y
-
- #-------------------
- # Functions to write
- #-------------------
- # TODO: Think about overflow vs type of input, etc...
- def write_frames(self, input, nframes = -1):
- """write data to file.
-
- :Parameters:
- input : ndarray
- array containing data to write.
- nframes : int
- number of frames to write.
-
- Notes
- -----
-
- - one channel is one column
- - updates the write pointer.
- - if float are given when the file contains integer data, you should
- put normalized data (that is the range [-1..1] will be written as the
- maximum range allowed by the integer bitwidth)."""
- # First, get the number of channels and frames from input
- if input.ndim == 1:
- nc = 1
- else:
- if input.ndim > 2:
- raise Exception("Expect array of rank <= 2, got %d" \
- % input.ndim)
- nc = input.shape[1]
-
- if nframes == -1:
- nframes = N.size(input)
- # Number of channels should be the one expected
- if not(nc == self._sfinfo.channels):
- raise Exception("Expected %d channels, got %d" % \
- (self._sfinfo.channels, nc))
-
- # Writing to the file
- c_nframes = _num2int64(nframes)
- if c_nframes < 0:
- raise ValueError("number of frames has to be >= 0")
-
- input = N.require(input, requirements = 'C')
-
- if input.dtype == N.float32:
- if self._check_overflow(input):
- warnings.warn("Warning, overflow detected when writing.")
- res = _SND.sf_writef_float(self.hdl, input, c_nframes)
- elif input.dtype == N.float64:
- self._check_overflow(input)
- if self._check_overflow(input):
- warnings.warn("Warning, overflow detected when writing.")
- res = _SND.sf_writef_double(self.hdl, input, c_nframes)
- elif input.dtype == N.int32:
- res = _SND.sf_writef_int(self.hdl, input, c_nframes)
- elif input.dtype == N.int16:
- res = _SND.sf_writef_short(self.hdl, input, c_nframes)
- else:
- raise Exception("type of input not understood: input should"
- " be float64 or float32""")
-
- if not(res == nframes):
- raise IOError("write %d frames, expected to write %d" \
- % res, nframes)
-
- def _check_overflow(self, data):
- if N.max(data ** 2) >= 1.:
- return True
- return False
-
- # Syntactic sugar
- def __repr__(self):
- return self.__str__()
-
- def __str__(self):
- repstr = "----------------------------------------\n"
- if self._byfd:
- repstr += "File : %d (opened by file descriptor)\n" % self.fd
- else:
- repstr += "File : %s\n" % self.filename
- repstr += "Channels : %d\n" % self._sfinfo.channels
- repstr += "Sample rate : %d\n" % self._sfinfo.samplerate
- repstr += "Frames : %d\n" % self._sfinfo.frames
- repstr += "Raw Format : %#010x -> %s\n" % \
- (self._format.get_format_raw(), self._format.get_major_str())
- repstr += "File format : %s\n" % self.get_file_format()
- repstr += "Encoding : %s\n" % self.get_encoding()
- repstr += "Endianness : %s\n" % self.get_endianness()
- repstr += "Sections : %d\n" % self._sfinfo.sections
- if self._sfinfo.seekable:
- seek = 'True'
- else:
- seek = 'False'
- repstr += "Seekable : %s\n" % seek
- repstr += "Duration : %s\n" % self._generate_duration_str()
- return repstr
-
- def _generate_duration_str(self):
- if self._sfinfo.samplerate < 1:
- return None
- tsec = self._sfinfo.frames / self._sfinfo.samplerate
- hrs = tsec / 60 / 60
- tsec = tsec % (60 ** 2)
- mins = tsec / 60
- tsec = tsec % 60
- secs = tsec
- ms = 1000 * self._sfinfo.frames / self._sfinfo.samplerate % 1000
-
- return "%02d:%02d:%02d.%3d" % (hrs, mins, secs, ms)
-
-def supported_format():
- # XXX: broken
- return py_to_snd_file_format_dic.keys()
-
-def supported_endianness():
- # XXX: broken
- return py_to_snd_endianness_dic.keys()
-
-def supported_encoding():
- # XXX: broken
- return py_to_snd_encoding_dic.keys()
-
-def _num2int64(value):
- """ Convert a python objet to a c_int64, safely."""
- if not (type(value) == int or type(value) == long):
- value = long(value)
- print "Warning, converting %s to long" % str(value)
- c_value = c_int64(value)
- if not c_value.value == value:
- raise RuntimeError("Error while converting %s to a c_int64"\
- ", maybe %s is too big ?" % str(value))
- return c_value
+++ /dev/null
-Program('main', source = ['simple.c'], LIBS = ['asound'])
-Program('main2', source = ['simple2.c'], LIBS = ['asound'])
+++ /dev/null
-cdef extern from "alsa/asoundlib.h":
- ctypedef enum snd_pcm_stream_t:
- SND_PCM_STREAM_PLAYBACK
- SND_PCM_STREAM_CAPTURE
- ctypedef enum snd_pcm_access_t :
- SND_PCM_ACCESS_MMAP_INTERLEAVED
- SND_PCM_ACCESS_MMAP_NONINTERLEAVED
- SND_PCM_ACCESS_MMAP_COMPLEX
- SND_PCM_ACCESS_RW_INTERLEAVED
- SND_PCM_ACCESS_RW_NONINTERLEAVED
- ctypedef enum snd_pcm_format_t :
- SND_PCM_FORMAT_UNKNOWN
- SND_PCM_FORMAT_S8
- SND_PCM_FORMAT_U8
- SND_PCM_FORMAT_S16_LE
- SND_PCM_FORMAT_S16_BE
- SND_PCM_FORMAT_U16_LE
- SND_PCM_FORMAT_U16_BE
- SND_PCM_FORMAT_S24_LE
- SND_PCM_FORMAT_S24_BE
- SND_PCM_FORMAT_U24_LE
- SND_PCM_FORMAT_U24_BE
- SND_PCM_FORMAT_S32_LE
- SND_PCM_FORMAT_S32_BE
- SND_PCM_FORMAT_U32_LE
- SND_PCM_FORMAT_U32_BE
- SND_PCM_FORMAT_FLOAT_LE
- SND_PCM_FORMAT_FLOAT_BE
- SND_PCM_FORMAT_FLOAT64_LE
- SND_PCM_FORMAT_FLOAT64_BE
- SND_PCM_FORMAT_IEC958_SUBFRAME_LE
- SND_PCM_FORMAT_IEC958_SUBFRAME_BE
- SND_PCM_FORMAT_MU_LAW
- SND_PCM_FORMAT_A_LAW
- SND_PCM_FORMAT_IMA_ADPCM
- SND_PCM_FORMAT_MPEG
- SND_PCM_FORMAT_GSM
- SND_PCM_FORMAT_SPECIAL
- SND_PCM_FORMAT_S24_3LE
- SND_PCM_FORMAT_S24_3BE
- SND_PCM_FORMAT_U24_3LE
- SND_PCM_FORMAT_U24_3BE
- SND_PCM_FORMAT_S20_3LE
- SND_PCM_FORMAT_S20_3BE
- SND_PCM_FORMAT_U20_3LE
- SND_PCM_FORMAT_U20_3BE
- SND_PCM_FORMAT_S18_3LE
- SND_PCM_FORMAT_S18_3BE
- SND_PCM_FORMAT_U18_3LE
- SND_PCM_FORMAT_U18_3BE
- SND_PCM_FORMAT_S16
- SND_PCM_FORMAT_U16
- SND_PCM_FORMAT_S24
- SND_PCM_FORMAT_U24
- SND_PCM_FORMAT_S32
- SND_PCM_FORMAT_U32
- SND_PCM_FORMAT_FLOAT
- SND_PCM_FORMAT_FLOAT64
- SND_PCM_FORMAT_IEC958_SUBFRAME
-
- ctypedef struct snd_pcm_t
- # XXX: how to make sure the typedef is OK ?
- ctypedef unsigned long snd_pcm_uframes_t
-
- int snd_pcm_open(snd_pcm_t **, char*, int, int)
- int snd_pcm_close(snd_pcm_t *)
- int snd_pcm_drain(snd_pcm_t *)
-
- int snd_pcm_set_params(snd_pcm_t *, snd_pcm_format_t,
- snd_pcm_access_t, unsigned int,
- unsigned int, int, unsigned int)
-
- int snd_pcm_writei(snd_pcm_t *, void*, snd_pcm_uframes_t)
-
- char* snd_strerror(int error)
-
- int snd_card_next(int *icard)
- int snd_card_get_name(int icard, char** name)
- char* snd_asoundlib_version()
-
-cdef extern from "numpy/arrayobject.h":
- ctypedef int intp
- ctypedef extern class numpy.ndarray [object PyArrayObject]:
- cdef char *data
- cdef int nd
- cdef intp *dimensions
- cdef intp *strides
- cdef int flags
-
-cdef extern from "stdlib.h":
- ctypedef unsigned long size_t
- void free(void *ptr)
- void *malloc(size_t size)
- void *realloc(void *ptr, size_t size)
- size_t strlen(char *s)
- char *strcpy(char *dest, char *src)
-
-cdef extern from "stdint.h":
- ctypedef unsigned short int16_t
-
-cdef extern from "Python.h":
- object PyString_FromStringAndSize(char *v, int len)
-
-class AlsaException(Exception):
- pass
-
-def asoundlib_version():
- return snd_asoundlib_version()
-
-def card_indexes():
- """Returns a list containing index of cards recognized by alsa."""
- cdef int icur = -1
-
- cards = []
- while 1:
- st = snd_card_next(&icur)
- if st < 0:
- raise AlsaException("Could not get next card")
- if icur < 0:
- break
- cards.append(icur)
- return tuple(cards)
-
-def card_name(index):
- """Get the name of the card corresponding to the given index."""
- cdef char* sptr
- st = snd_card_get_name(index, &sptr)
- if st < 0:
- raise AlsaException("Error while getting card name %d: alsa error "\
- "was %s" % (index, snd_strerror(st)))
- else:
- cardname = PyString_FromStringAndSize(sptr, len(sptr))
- free(sptr)
- return cardname
-
-cdef class _PCM:
- cdef snd_pcm_t* pcmhdl
- cdef public char* name
-
- def __new__(self, device = "default", stream = SND_PCM_STREAM_PLAYBACK):
- self.pcmhdl = NULL
-
- st = snd_pcm_open(&self.pcmhdl, device, stream, 0)
- if st < 0:
- raise AlsaException("Cannot open device %s: %s" % (device, snd_strerror(st)))
-
- def __init__(self, device = "default", stream = SND_PCM_STREAM_PLAYBACK):
- self.name = device
-
- def __dealloc__(self):
- if self.pcmhdl:
- snd_pcm_close(self.pcmhdl)
-
-cdef class Device:
- cdef _PCM pcm
- cdef unsigned int samplerate
- # XXX: set property instead
- cdef public unsigned int channels
- cdef snd_pcm_format_t format
- cdef snd_pcm_access_t access
- def __init__(self, samplerate = 48000, channels = 1,
- format = SND_PCM_FORMAT_S16,
- access = SND_PCM_ACCESS_RW_INTERLEAVED):
- self.pcm = _PCM()
-
- self.samplerate = samplerate
- self.channels = channels
-
- self.access = access
- self.format = format
-
- st = snd_pcm_set_params(self.pcm.pcmhdl, format, access, channels,
- samplerate, 1, 1000000)
- if st < 0:
- raise AlsaException()
-
- def play_short(self, ndarray input):
- cdef int16_t* p = <int16_t*>input.data
- cdef int16_t* buff = NULL
- #cdef int n = input.dimensions[0]
- cdef int n = input.dimensions[0]
- cdef int nb = n / 1024 / 16
- cdef snd_pcm_uframes_t bufsz = 1024 * 16
-
- assert self.format == SND_PCM_FORMAT_S16
- assert self.access == SND_PCM_ACCESS_RW_INTERLEAVED
-
- for i from 0 <= i < nb:
- st = snd_pcm_writei(self.pcm.pcmhdl, &p[i * bufsz], bufsz)
- if not st == bufsz:
- print "Error while writing to device", st
- print snd_strerror(st)
-
- snd_pcm_drain(self.pcm.pcmhdl)
-
- def _get_name(self):
- return self.pcm.name
- name = property(_get_name)
+++ /dev/null
-import numpy as np
-
-from _alsa import card_name, card_indexes, asoundlib_version
-from _alsa import Device, AlsaException
-
-def play(input, samplerate = 48000):
- if input.ndim == 1:
- n = input.size
- nc = 1
- elif input.ndim == 2:
- n, nc = input.shape
- else:
- raise ValueError("Only ndim 1 or 2 supported")
-
- if not input.dtype in (np.float32, np.float64):
- raise ValueError("input should be array of float32 or float64 !")
-
- try:
- dev = Device(samplerate = samplerate, channels = nc)
- dev.play_short((16384 * input).astype(np.int16))
- except AlsaException, e:
- raise IOError(str(e))
-
-if __name__ == '__main__':
- print "Asoundlib version is", asoundlib_version()
- for i in card_indexes():
- print card_name(i)
-
- dev = Device()
- print "Device name:", dev.name
-
- a = 0.2 * np.random.randn(4e4)
- play(a, 16000)
- play(a, 8000)
- play(a, 22050)
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Fri Sep 07 02:00 PM 2007 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# vim:syntax=python
-
-"""This is a small module to wrap basic functionalities of alsa: it uses ctypes
-for the wrapping."""
-
-__docformat__ = 'restructuredtext'
-
-__all__ = ['asoundlib_version', 'asoundlib_version_numbers', 'card_indexes', \
- 'card_name', 'card_longname']
-#================
-# Load alsa lib
-#================
-import ctypes
-from ctypes import cdll, Structure, c_int, pointer, POINTER, c_uint,\
- create_string_buffer, c_char_p, sizeof, byref, string_at, c_size_t,\
- c_void_p, c_ulong, c_uint16, c_long, c_uint8, c_int16, c_float
-try:
- from ctypes import c_int64
-except ImportError, e:
- print "Cannot import c_int64 from ctypes: if you are on ubuntu/debian," +\
- " this is likely because ctypes was compiled with libffi. see" +\
- " https://launchpad.net/ubuntu/+source/python2.5/+bug/71914"
- raise e
-
-from numpy.ctypeslib import ndpointer
-CTYPES_MAJOR = int(ctypes.__version__.split('.')[0])
-CTYPES_MINOR = int(ctypes.__version__.split('.')[1])
-CTYPES_MICRO = int(ctypes.__version__.split('.')[2])
-if CTYPES_MAJOR < 1 or (CTYPES_MINOR == 0 and CTYPES_MICRO < 1):
- raise ImportError("version of ctypes is %s, expected at least %s" \
- % (ctypes.__version__, '1.0.1'))
-import numpy as N
-
-ALSALOC = 'libasound.so.2'
-_ALSA = cdll.LoadLibrary(ALSALOC)
-# XXX: alsa means linux, normally. How to locate the glibc ?
-_C = cdll.LoadLibrary("libc.so.6")
-
-# Check version
-_ALSA.snd_asoundlib_version.args = []
-_ALSA.snd_asoundlib_version.restype = c_char_p
-
-def asoundlib_version():
- """Return the version of asoundlib as a string"""
- version = _ALSA.snd_asoundlib_version()
- return version
-
-def asoundlib_version_numbers():
- """Return the version of asoundlib as a tuple(major, minor, micro)."""
- version = asoundlib_version()
- return tuple(int(i) for i in version.split('.'))
-
-major, minor, micro = asoundlib_version_numbers()
-if not (major == 1 and minor == 0):
- raise RuntimeError("Expected 1.0.x version, got %s instead" % asoundlib_version())
-
-# Define pointers to opaque structures
-class snd_pcm_t(Structure):
- pass
-
-class snd_pcm_hw_params_t(Structure):
- pass
-
-class snd_pcm_sw_params_t(Structure):
- pass
-
-class snd_output_t(Structure):
- pass
-
-snd_pcm_t_p = POINTER(snd_pcm_t)
-snd_pcm_hw_params_t_p = POINTER(snd_pcm_hw_params_t)
-snd_pcm_sw_params_t_p = POINTER(snd_pcm_sw_params_t)
-snd_output_t_p = POINTER(snd_output_t)
-
-#------------
-# Define enum
-#------------
-SND_PCM_STREAM = {'SND_PCM_STREAM_PLAYBACK' : 0,
- 'SND_PCM_STREAM_CAPTURE' : 1}
-
-#-----------------------------------------------
-# Define all the function we need from asoundlib
-#-----------------------------------------------
-arg1 = c_int
-arg2 = POINTER(c_char_p)
-_ALSA.snd_card_get_name.argtypes = [arg1, arg2]
-_ALSA.snd_card_get_name.restype = c_int
-
-arg1 = c_int
-arg2 = POINTER(c_char_p)
-_ALSA.snd_card_get_longname.argtypes = [arg1, arg2]
-_ALSA.snd_card_get_longname.restype = c_int
-
-arg1 = POINTER(c_int)
-_ALSA.snd_card_next.argtypes = [arg1]
-_ALSA.snd_card_next.restype = c_int
-
-arg1 = c_int
-_ALSA.snd_strerror.argtypes = [arg1]
-_ALSA.snd_strerror.restype = c_char_p
-
-# output related functions
-arg1 = POINTER(snd_output_t_p)
-_ALSA.snd_output_buffer_open.argtypes = [arg1]
-_ALSA.snd_output_buffer_open.restype = c_int
-
-arg1 = snd_output_t_p
-_ALSA.snd_output_close.argtypes = [arg1]
-_ALSA.snd_output_close.restype = c_int
-
-arg1 = snd_output_t_p
-arg2 = POINTER(c_char_p)
-_ALSA.snd_output_buffer_string.argtypes = [arg1, arg2]
-_ALSA.snd_output_buffer_string.restype = c_size_t
-
-arg1 = snd_pcm_t_p
-arg2 = snd_output_t_p
-_ALSA.snd_pcm_dump.argtypes = [arg1, arg2]
-_ALSA.snd_pcm_dump.restype = c_int
-
-# pcm related functions
-arg1 = POINTER(POINTER(snd_pcm_t))
-arg2 = c_char_p
-arg3 = c_int
-arg4 = c_int
-_ALSA.snd_pcm_open.argtypes = [arg1, arg2, arg3, arg4]
-_ALSA.snd_pcm_open.restype = c_int
-
-arg1 = POINTER(snd_pcm_t)
-_ALSA.snd_pcm_close.argtypes = [arg1]
-_ALSA.snd_pcm_close.restype = c_int
-
-arg1 = POINTER(snd_pcm_t)
-_ALSA.snd_pcm_reset.argtypes = [arg1]
-_ALSA.snd_pcm_reset.restype = c_int
-
-arg1 = POINTER(snd_pcm_t)
-_ALSA.snd_pcm_drain.argtypes = [arg1]
-_ALSA.snd_pcm_drain.restype = c_int
-
-arg1 = POINTER(snd_pcm_hw_params_t_p)
-_ALSA.snd_pcm_hw_params_malloc.argtypes = [arg1]
-_ALSA.snd_pcm_hw_params_malloc.restype = c_int
-
-arg1 = snd_pcm_hw_params_t_p
-_ALSA.snd_pcm_hw_params_free.argtypes = [arg1]
-_ALSA.snd_pcm_hw_params_free.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-_ALSA.snd_pcm_hw_params_any.argtypes = [arg1, arg2]
-_ALSA.snd_pcm_hw_params_any.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-_ALSA.snd_pcm_hw_params.argtypes = [arg1, arg2]
-_ALSA.snd_pcm_hw_params.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = c_int
-_ALSA.snd_pcm_hw_params_set_access.argtypes = [arg1, arg2, arg3]
-_ALSA.snd_pcm_hw_params_set_access.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = POINTER(c_uint)
-arg4 = c_int
-_ALSA.snd_pcm_hw_params_set_rate_near.argtypes = [arg1, arg2, arg3, arg4]
-_ALSA.snd_pcm_hw_params_set_rate_near.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = c_uint
-_ALSA.snd_pcm_hw_params_set_channels.argtypes = [arg1, arg2, arg3]
-_ALSA.snd_pcm_hw_params_set_channels.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = c_int
-_ALSA.snd_pcm_hw_params_set_format.argtypes = [arg1, arg2, arg3]
-_ALSA.snd_pcm_hw_params_set_format.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = POINTER(c_ulong)
-_ALSA.snd_pcm_hw_params_set_buffer_size_near.argtypes = [arg1, arg2, arg3]
-_ALSA.snd_pcm_hw_params_set_buffer_size_near.restype = c_int
-
-arg1 = snd_pcm_t_p
-arg2 = snd_pcm_hw_params_t_p
-arg3 = POINTER(c_ulong)
-arg4 = c_int
-_ALSA.snd_pcm_hw_params_set_period_size_near.argtypes = [arg1, arg2, arg3, arg4]
-_ALSA.snd_pcm_hw_params_set_period_size_near.restype = c_int
-
-# write
-arg1 = snd_pcm_t_p
-arg2 = c_void_p
-arg3 = c_ulong
-_ALSA.snd_pcm_writei.argtypes = [arg1, arg2, arg3]
-_ALSA.snd_pcm_writei.restype = c_ulong
-
-#==================
-# General functions
-#==================
-class AlsaException(Exception):
- pass
-
-class OutputBuffer():
- def __init__(self):
- ohdl = snd_output_t_p()
- st = _ALSA.snd_output_buffer_open(byref(ohdl))
- if st:
- raise AlsaException("Error creating output buffer")
- self._hdl = ohdl
-
- def __del__(self, close_func = _ALSA.snd_output_close):
- if hasattr(self, '_hdl'):
- if not(self._hdl == 0):
- close_func(self._hdl)
- self._hdl = 0
-
-
-OHDL = OutputBuffer()
-
-#========================
-# Cards related functions
-#========================
-def card_indexes():
- """Returns a list containing index of cards recognized by alsa."""
- cards = []
- cur = c_int(-1)
- while 1:
- st = _ALSA.snd_card_next(byref(cur))
- if st < 0:
- raise AlsaException("Could not get next card")
- if cur.value < 0:
- break
- cards.append(cur.value)
- return tuple(cards)
-
-def card_name(index):
- """Get the name of the card corresponding to the given index."""
- sptr = c_char_p(0)
- st = _ALSA.snd_card_get_name(index, byref(sptr))
- if st < 0:
- raise AlsaException("Error while getting card name %d: alsa error "\
- "was %s" % (index, _ALSA.snd_strerror(st)))
- cardname = string_at(sptr)
- _C.free(sptr)
- return cardname
-
-def card_longname(index):
- """Get the long name of the card corresponding to the given index."""
- sptr = c_char_p(0)
- st = _ALSA.snd_card_get_longname(index, byref(sptr))
- if st < 0:
- raise AlsaException("Error while getting card longname %d: alsa error "\
- "was %s" % (index, _ALSA.snd_strerror(st)))
- cardname = string_at(sptr)
- _C.free(sptr)
- return cardname
-
-#=======================
-# Pcm related functions
-#=======================
-class _HwParams:
- """Small class to assure that the hw parmas are always freed."""
- def __init__(self):
- self._hdl = snd_pcm_hw_params_t_p()
- st = _ALSA.snd_pcm_hw_params_malloc(byref(self._hdl))
- if st:
- raise AlsaException("error while creating hw params %s" \
- % _ALSA.snd_strerror(st))
-
- def __del__(self, close_func = _ALSA.snd_pcm_hw_params_free):
- if hasattr(self, '_hdl'):
- if not(self._hdl == 0):
- close_func(self._hdl)
- self._hdl = 0
-
-class Pcm:
- def __init__(self, device = 'default', samplerate = 48000, channels = 1):
- self._pcmhdl = POINTER(snd_pcm_t)()
-
- # Open the pcm device
- st = _ALSA.snd_pcm_open(byref(self._pcmhdl), device,
- SND_PCM_STREAM['SND_PCM_STREAM_PLAYBACK'], 0)
- if st:
- raise AlsaException("error while opening pcm device %s; alsa error is %s"\
- % (device, _ALSA.snd_strerror(st)))
-
- # Set hw params
- self._set_hw_params(samplerate, channels)
-
- # Reset the pcm device
- st = _ALSA.snd_pcm_reset(self._pcmhdl)
- if st:
- raise AlsaException("error while resetting pcm : %s" \
- % _ALSA.snd_strerror(st))
-
- self.nc = channels
- self.samplerate = samplerate
-
- def _set_hw_params(self, samplerate, channels):
- # XXX: Parameters copied from sndfile-play.c from libsndfile. Check the
- # meaning
- alsa_period_size = c_ulong(1024)
- alsa_buffer_frames = c_ulong(alsa_period_size.value * 4)
-
- hw = _HwParams()
- hwhdl = hw._hdl
- st = _ALSA.snd_pcm_hw_params_any(self._pcmhdl, hwhdl)
- if st < 0:
- raise AlsaException("cannot initialize hw st: %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params_set_access(self._pcmhdl, hwhdl, 3)
- if st < 0:
- raise AlsaException("cannot initialize hw st: %s" \
- % _ALSA.snd_strerror(st))
-
- rrate = c_uint(samplerate)
- st = _ALSA.snd_pcm_hw_params_set_rate_near(self._pcmhdl, hwhdl, byref(rrate), 0)
- if st < 0:
- raise AlsaException("cannot set samplerate : %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params_set_format(self._pcmhdl, hwhdl, 14)
- if st < 0:
- raise AlsaException("cannot set format : %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params_set_channels(self._pcmhdl, hwhdl, channels)
- if st < 0:
- raise AlsaException("cannot set number of channels : %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params_set_buffer_size_near(self._pcmhdl, hwhdl,
- byref(alsa_buffer_frames))
- if st < 0:
- raise AlsaException("cannot set buffer size: %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params_set_period_size_near(self._pcmhdl, hwhdl,
- byref(alsa_period_size), 0)
- if st < 0:
- raise AlsaException("cannot set period size: %s" \
- % _ALSA.snd_strerror(st))
-
- st = _ALSA.snd_pcm_hw_params(self._pcmhdl, hwhdl)
- if st < 0:
- raise AlsaException("cannot set params : %s" \
- % _ALSA.snd_strerror(st))
-
- def __del__(self, close_func = _ALSA.snd_pcm_close):
- if hasattr(self, '_pcmhdl'):
- try:
- self._pcmhdl[0]
- close_func(self._pcmhdl)
- self._pcmhdl = POINTER(snd_pcm_t)()
- except ValueError:
- pass
-
- def __str__(self):
- buf = c_char_p()
- msg = "Pcm device: "
- if self._pcmhdl > 0:
- msg += " Opened\n"
- # XXX error checking
- st = _ALSA.snd_pcm_dump(self._pcmhdl, OHDL._hdl)
- st = _ALSA.snd_output_buffer_string(OHDL._hdl, byref(buf))
- if st > 0:
- msg += string_at(buf)
- return msg
-
- def __repr__(self):
- return self.__str__()
-
- def write_float(self, data):
- bufsz = 1024 * 2
- nb = data.size / bufsz / self.nc
- for i in range(nb):
- b = a[i * bufsz: (i+1) * bufsz]
- st = _ALSA.snd_pcm_writei(self._pcmhdl,
- b.ctypes.data_as(POINTER(c_float)), bufsz)
- if not st == bufsz:
- print "Error while writing to device"
- b = a[nb * bufsz: -1]
- reframes = b.size / self.nc
- st = _ALSA.snd_pcm_writei(self._pcmhdl,
- b.ctypes.data_as(POINTER(c_float)), reframes)
- if not st == reframes:
- print "Error while writing to device"
-
- _ALSA.snd_pcm_drain(self._pcmhdl)
-#class AlsaPlayer:
-# def __init__(self, device = "default"):
-# pcm = _Pcm(device)
-# hw = _HwParams()
-# err = _ALSA.snd_pcm_hw_params_any(pcm.pcmhdl, hw.hwparamshdl)
-# if err:
-# raise AlsaException("
-
-if __name__ == '__main__':
- print card_indexes()
- print [card_name(i) for i in card_indexes()]
- print [card_longname(i) for i in card_indexes()]
- print asoundlib_version()
- print asoundlib_version_numbers()
- from scikits.audiolab import wavread
- a, fs = wavread('test.wav')[:2]
- if a.ndim > 1:
- nc = a.shape[1]
- else:
- nc = 1
- a = a.astype(N.float32)
- pcm = Pcm("default:1", 22050, channels = nc)
- print pcm
- pcm.write_float(a)
+++ /dev/null
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Distutils import build_ext
-from numpy.distutils.misc_util import get_numpy_include_dirs
-
-setup(name = "PyrexGuide",
- ext_modules=[
- Extension("_alsa", ["_alsa.pyx"],
- libraries = ['asound'],
- include_dirs = get_numpy_include_dirs())],
- cmdclass = {'build_ext': build_ext})
-
+++ /dev/null
-#include <stdio.h>
-
-#include <alsa/asoundlib.h>
-
-int main()
-{
- snd_pcm_t *pcm;
- snd_pcm_hw_params_t *hw;
-
- int st;
- unsigned int rrate = 44100;
- snd_output_t *output;
-
- st = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
- if (st) {
- fprintf(stderr, "Error opening pcm\n");
- return -1;
- }
-
- st = snd_pcm_hw_params_malloc(&hw);
- if (st) {
- fprintf(stderr, "Error while allocating hw\n");
- return -1;
- }
-
- st = snd_pcm_hw_params_any(pcm, hw);
- if (st) {
- fprintf(stderr, "Error while allocating hw\n");
- return -1;
- }
-
- st = snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
- if (st) {
- fprintf(stderr, "Error while allocating hw\n");
- return -1;
- }
-
- st = snd_pcm_hw_params_set_rate_near(pcm, hw, &rrate, 0);
- if (st) {
- fprintf(stderr, "Error while allocating hw\n");
- return -1;
- }
- fprintf(stdout, "rate is %d\n", rrate);
-
- st = snd_pcm_hw_params(pcm, hw);
- if (st) {
- fprintf(stderr, "Error while allocating hw\n");
- return -1;
- }
-
- //st = snd_output_stdio_attach(&output, stdout, 0);
- //if (st < 0) {
- // printf("Output failed: %s\n", snd_strerror(st));
- // return 0;
- //}
- st = snd_output_buffer_open(&output);
- if (st < 0) {
- printf("Output buffer open failed: %s\n", snd_strerror(st));
- return 0;
- }
- char* buf;
- snd_pcm_dump(pcm, output);
- st = snd_output_buffer_string(output, &buf);
- fprintf(stdout, "%d chars\n", st);
- fprintf(stdout, "%s", buf);
-
- //snd_output_close(output);
- //snd_pcm_hw_params_free(hw);
- snd_pcm_close(pcm);
-
- snd_config_update_free_global();
-
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdint.h>
-
-#include <alsa/asoundlib.h>
-
-int play(snd_pcm_t *pcm)
-{
- int16_t buff[1024 * 16];
- int i, j;
- snd_pcm_uframes_t frames;
-
- for (i = 0; i < 4; ++i) {
- for (j = 0; j < 1024 * 16; ++j) {
- buff[j] = random() & 0xff;
- }
- frames = snd_pcm_writei(pcm, buff, 1024 * 16);
- fprintf(stderr, "%lu\n", frames);
- }
-
- return 0;
-}
-
-int set(snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access,
- unsigned int channels, unsigned int samplerate)
-{
- int st;
-
- st = snd_pcm_set_params(pcm, format, access, channels, samplerate,
- 1, 1000000);
- if (st < 0) {
- printf("Output failed: %s\n", snd_strerror(st));
- return st;
- }
-
- return 0;
-}
-
-int main()
-{
- snd_pcm_t *pcm;
- snd_pcm_hw_params_t *hw;
-
- int st;
- unsigned int rrate = 48000;
- unsigned int nc = 1;
- snd_output_t *output;
-
- int i, j;
- snd_pcm_sframes_t frames;
-
- st = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
- if (st) {
- fprintf(stderr, "Error opening pcm\n");
- return -1;
- }
-
- st = snd_output_stdio_attach(&output, stdout, 0);
- if (st < 0) {
- printf("Output failed: %s\n", snd_strerror(st));
- return -1;
- }
-
- set(pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 44100);
-
- play(pcm);
- snd_pcm_drain(pcm);
-
- set(pcm, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 8000);
-
- play(pcm);
-
- //snd_pcm_dump(pcm, output);
-
- snd_output_close(output);
- snd_pcm_close(pcm);
-
- snd_config_update_free_global();
-
- return 0;
-}
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Mon May 21 12:00 PM 2007 J
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Tue Jul 17 11:00 AM 2007 J
-from os.path import join, dirname
-from os import remove
-from tempfile import mkstemp
-
-from numpy.testing import *
-import numpy as N
-
-set_package_path()
-from audiolab.matapi import wavread, auread, aiffread, sdifread, flacread
-from audiolab.matapi import wavwrite, auwrite, aiffwrite, sdifwrite, flacwrite
-from audiolab.pysndfile import PyaudioException, sndfile, formatinfo as audio_format
-from audiolab.pysndfile import FlacUnsupported
-restore_path()
-
-#Optional:
-set_local_path()
-# import modules that are located in the same directory as this file.
-from testcommon import open_tmp_file, close_tmp_file
-restore_path()
-
-class test_audiolab(NumpyTestCase):
- def _test_read(self, func, format, filext):
- # Create a tmp audio file, write some random data into it, and check it
- # is the expected data when read from a function from the matapi.
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.' + filext)
- try:
- nbuff = 22050
- noise = 0.1 * N.random.randn(nbuff)
-
- # Open the copy file for writing
- b = sndfile(cfilename, 'write', format, 1, nbuff)
- b.write_frames(noise, nbuff)
- b.close()
-
- # Reread the data
- b = sndfile(cfilename, 'read')
- rcnoise = b.read_frames(nbuff)
- b.close()
-
- rnoise = func(cfilename)[0]
-
- assert_array_equal(rnoise, rcnoise)
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_wavread(self):
- """ Check wavread """
- self._test_read(wavread, audio_format('wav', 'pcm16', 'file'), 'wav')
-
- def test_flacread(self):
- """ Check flacread """
- try:
- self._test_read(flacread, audio_format('flac', 'pcm16', 'file'), 'flac')
- except FlacUnsupported:
- print "Flac unsupported, flacread not tested"
-
- def test_auread(self):
- """ Check auread """
- self._test_read(auread, audio_format('au', 'ulaw', 'file'), 'au')
-
- def test_aiffread(self):
- """ Check aiffread """
- self._test_read(aiffread, audio_format('aiff', 'pcm16', 'file'), 'aiff')
-
- def test_sdifread(self):
- """ Check sdifread (ircam format) """
- self._test_read(sdifread, audio_format('ircam', 'pcm16', 'file'), 'sdif')
-
- def test_bad_wavread(self):
- """ Check wavread on bad file"""
- # Create a tmp audio file with non wav format, write some random data into it,
- # and check it can not be opened by wavread
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nbuff = 22050
- noise = 0.1 * N.random.randn(nbuff)
-
- # Open the copy file for writing
- format = audio_format('aiff', 'pcm16')
- b = sndfile(cfilename, 'write', format, 1, nbuff)
-
- b.write_frames(noise, nbuff)
-
- b.close()
-
- b = sndfile(cfilename, 'read')
- rcnoise = b.read_frames(nbuff)
- b.close()
-
- try:
- rnoise = wavread(cfilename)[0]
- raise Exception("wavread on non wav file succeded, expected to fail")
- except PyaudioException, e:
- pass
- #print str(e) + ", as expected"
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def _test_write(self, func, format, filext):
- """ Check *write functions from matpi """
- rfd1, fd1, cfilename1 = open_tmp_file('pysndfiletest.' + filext)
- rfd2, fd2, cfilename2 = open_tmp_file('pysndfiletest.' + filext)
- try:
- nbuff = 22050
- fs = nbuff
- noise = 0.1 * N.random.randn(nbuff)
-
- # Open the first file for writing with sndfile
- b = sndfile(cfilename1, 'write', format, 1, fs)
-
- b.write_frames(noise, nbuff)
-
- b.close()
-
- # Write same data with wavwrite
- func(noise, cfilename2, fs)
-
- # Compare if both files have same hash
- f1 = open(cfilename1)
- f2 = open(cfilename2)
-
- import md5
-
- m1 = md5.new()
- m2 = md5.new()
-
- m1.update(f1.read())
- m2.update(f2.read())
-
- f1.close()
- f2.close()
- assert m1.hexdigest() == m2.hexdigest()
- finally:
- close_tmp_file(rfd1, cfilename1)
- close_tmp_file(rfd2, cfilename2)
-
- def test_wavwrite(self):
- """ Check wavwrite """
- self._test_write(wavwrite, audio_format('wav', 'pcm16', 'file'), 'wav')
-
- def test_aiffwrite(self):
- """ Check aiffwrite """
- self._test_write(aiffwrite, audio_format('aiff', 'pcm16', 'file'), 'aiff')
-
- def test_auwrite(self):
- """ Check wavwrite """
- self._test_write(auwrite, audio_format('au', 'ulaw', 'file'), 'au')
-
- def test_sdifwrite(self):
- """ Check wavwrite """
- self._test_write(sdifwrite, audio_format('ircam', 'pcm16', 'file'), 'sdif')
-
- def test_flacwrite(self):
- """ Check flacwrite """
- try:
- self._test_write(flacwrite, audio_format('flac', 'pcm16', 'file'), 'flac')
- except FlacUnsupported:
- print "Flac unsupported, flacwrite not tested"
-
-if __name__ == "__main__":
- NumpyTest().run()
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Tue Jul 17 11:00 AM 2007 J
-"""Test for the sndfile class."""
-from os.path import join, dirname
-import os
-import sys
-
-from numpy.testing import NumpyTestCase, assert_array_equal, NumpyTest, \
- assert_array_almost_equal, set_package_path, restore_path, set_local_path
-import numpy as N
-
-set_package_path()
-from audiolab import pysndfile
-from audiolab.pysndfile import sndfile, formatinfo as audio_format
-restore_path()
-
-set_local_path()
-from testcommon import open_tmp_file, close_tmp_file
-restore_path()
-
-# XXX: there is a lot to refactor here
-class test_pysndfile(NumpyTestCase):
- def test_basic_io(self):
- """ Check open, close and basic read/write"""
- # dirty !
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nbuff = 22050
-
- # Open the test file for reading
- a = sndfile(ofilename, 'read')
- nframes = a.get_nframes()
-
- # Open the copy file for writing
- format = audio_format('wav', 'pcm16')
- b = sndfile(fd, 'write', format, a.get_channels(),
- a.get_samplerate())
-
- # Copy the data
- for i in range(nframes / nbuff):
- tmpa = a.read_frames(nbuff)
- assert tmpa.dtype == N.float
- b.write_frames(tmpa, nbuff)
- nrem = nframes % nbuff
- tmpa = a.read_frames(nrem)
- assert tmpa.dtype == N.float
- b.write_frames(tmpa, nrem)
-
- a.close()
- b.close()
- finally:
- close_tmp_file(rfd, cfilename)
-
-
- def test_basic_io_fd(self):
- """ Check open from fd works"""
- # dirty !
- if sys.platform == 'win32':
- print "Not testing opening by fd because does not work on win32"
- else:
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- fd = os.open(ofilename, os.O_RDONLY)
- hdl = sndfile(fd, 'read')
- hdl.close()
-
- def test_raw(self):
- rawname = join(dirname(pysndfile.__file__), 'test_data', 'test.raw')
- format = audio_format('raw', 'pcm16', 'little')
- a = sndfile(rawname, 'read', format, 1, 11025)
- assert a.get_nframes() == 11290
- a.close()
-
- def test_float64(self):
- """Check float64 write/read works"""
- # dirty !
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nbuff = 22050
-
- # Open the test file for reading
- a = sndfile(ofilename, 'read')
- nframes = a.get_nframes()
-
- # Open the copy file for writing
- format = audio_format('wav', 'float64')
- b = sndfile(fd, 'write', format, a.get_channels(),
- a.get_samplerate())
-
- # Copy the data in the wav file
- for i in range(nframes / nbuff):
- tmpa = a.read_frames(nbuff, dtype = N.float64)
- assert tmpa.dtype == N.float64
- b.write_frames(tmpa, nbuff)
- nrem = nframes % nbuff
- tmpa = a.read_frames(nrem)
- b.write_frames(tmpa, nrem)
-
- a.close()
- b.close()
-
- # Now, reopen both files in for reading, and check data are
- # the same
- a = sndfile(ofilename, 'read')
- b = sndfile(cfilename, 'read')
- for i in range(nframes / nbuff):
- tmpa = a.read_frames(nbuff, dtype = N.float64)
- tmpb = b.read_frames(nbuff, dtype = N.float64)
- assert_array_equal(tmpa, tmpb)
-
- a.close()
- b.close()
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_float32(self):
- """Check float write/read works"""
- # dirty !
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nbuff = 22050
-
- # Open the test file for reading
- a = sndfile(ofilename, 'read')
- nframes = a.get_nframes()
-
- # Open the copy file for writing
- format = audio_format('wav', 'float32')
- b = sndfile(fd, 'write', format, a.get_channels(),
- a.get_samplerate())
-
- # Copy the data in the wav file
- for i in range(nframes / nbuff):
- tmpa = a.read_frames(nbuff, dtype = N.float32)
- assert tmpa.dtype == N.float32
- b.write_frames(tmpa, nbuff)
- nrem = nframes % nbuff
- tmpa = a.read_frames(nrem)
- b.write_frames(tmpa, nrem)
-
- a.close()
- b.close()
-
- # Now, reopen both files in for reading, and check data are
- # the same
- a = sndfile(ofilename, 'read')
- b = sndfile(cfilename, 'read')
- for i in range(nframes / nbuff):
- tmpa = a.read_frames(nbuff, dtype = N.float32)
- tmpb = b.read_frames(nbuff, dtype = N.float32)
- assert_array_equal(tmpa, tmpb)
-
- a.close()
- b.close()
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_supported_features(self):
- msg = "\nsupported file format are : this test is broken FIXME"
- #for i in pysndfile.supported_format():
- # msg += str(i) + ', '
- #print msg
- #msg = "supported encoding format are : "
- #for i in pysndfile.supported_encoding():
- # msg += str(i) + ', '
- #print msg
- #msg = "supported endianness are : "
- #for i in pysndfile.supported_endianness():
- # msg += str(i) + ', '
- print msg
-
- def test_short_io(self):
- # TODO: check if neg or pos value is the highest in abs
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nb = 2 ** 14
- nbuff = 22050
- fs = 22050
- a = N.random.random_integers(-nb, nb, nbuff)
- a = a.astype(N.short)
-
- # Open the file for writing
- format = audio_format('wav', 'pcm16')
- b = sndfile(fd, 'write', format, 1, fs)
-
- b.write_frames(a, nbuff)
- b.close()
-
- b = sndfile(cfilename, 'read')
-
- read_a = b.read_frames(nbuff, dtype = N.short)
- b.close()
-
- assert_array_equal(a, read_a)
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_int_io(self):
- # TODO: check if neg or pos value is the highest in abs
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- nb = 2 ** 25
- nbuff = 22050
- fs = 22050
- a = N.random.random_integers(-nb, nb, nbuff)
- a = a.astype(N.int32)
-
- # Open the file for writing
- format = audio_format('wav', 'pcm32')
- b = sndfile(fd, 'write', format, 1, fs)
-
- b.write_frames(a, nbuff)
- b.close()
-
- b = sndfile(cfilename, 'read')
-
- read_a = b.read_frames(nbuff, dtype = N.int32)
- b.close()
-
- assert_array_equal(a, read_a)
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_mismatch(self):
- # This test open a file for writing, but with bad args (channels and
- # nframes inverted)
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- # Open the file for writing
- format = audio_format('wav', 'pcm16')
- try:
- b = sndfile(fd, 'write', \
- format, channels = 22000, samplerate = 1)
- raise Exception("Try to open a file with more than 256 "\
- "channels, this should not succeed !")
- except RuntimeError, e:
- #print "Gave %d channels, error detected is \"%s\"" % (22000, e)
- pass
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_bigframes(self):
- """ Try to seek really far"""
- rawname = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- a = sndfile(rawname, 'read')
- try:
- try:
- a.seek(2 ** 60)
- raise Exception("Seek really succeded ! This should not happen")
- except pysndfile.PyaudioIOError, e:
- pass
- finally:
- a.close()
-
- def test_float_frames(self):
- """ Check nframes can be a float"""
- rfd, fd, cfilename = open_tmp_file('pysndfiletest.wav')
- try:
- # Open the file for writing
- format = audio_format('wav', 'pcm16')
- a = sndfile(fd, 'rwrite', format, channels = 1,
- samplerate = 22050)
- tmp = N.random.random_integers(-100, 100, 1000)
- tmp = tmp.astype(N.short)
- a.write_frames(tmp, tmp.size)
- a.seek(0)
- a.sync()
- ctmp = a.read_frames(1e2, dtype = N.short)
- a.close()
-
- finally:
- close_tmp_file(rfd, cfilename)
-
- def test_nofile(self):
- """ Check the failure when opening a non existing file."""
- try:
- f = sndfile("floupi.wav", "read")
- raise AssertionError("call to non existing file should not succeed")
- except IOError:
- pass
- except Exception, e:
- raise AssertionError("opening non existing file should raise a IOError exception, got %s instead" % e.__class__)
-
-class test_seek(NumpyTestCase):
- def test_simple(self):
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- # Open the test file for reading
- a = sndfile(ofilename, 'read')
- nframes = a.get_nframes()
-
- buffsize = 1024
- buffsize = min(nframes, buffsize)
-
- # First, read some frames, go back, and compare buffers
- buff = a.read_frames(buffsize)
- a.seek(0)
- buff2 = a.read_frames(buffsize)
- assert_array_equal(buff, buff2)
-
- a.close()
-
- # Now, read some frames, go back, and compare buffers
- # (check whence == 1 == SEEK_CUR)
- a = sndfile(ofilename, 'read')
- a.read_frames(buffsize)
- buff = a.read_frames(buffsize)
- a.seek(-buffsize, 1)
- buff2 = a.read_frames(buffsize)
- assert_array_equal(buff, buff2)
-
- a.close()
-
- # Now, read some frames, go back, and compare buffers
- # (check whence == 2 == SEEK_END)
- a = sndfile(ofilename, 'read')
- buff = a.read_frames(nframes)
- a.seek(-buffsize, 2)
- buff2 = a.read_frames(buffsize)
- assert_array_equal(buff[-buffsize:], buff2)
-
- def test_rw(self):
- """Test read/write pointers for seek."""
- ofilename = join(dirname(pysndfile.__file__), 'test_data', 'test.wav')
- rfd, fd, cfilename = open_tmp_file('rwseektest.wav')
- try:
- ref = sndfile(ofilename, 'read')
- test = sndfile(fd, 'rwrite', format = ref._format, channels =
- ref.get_channels(), samplerate = ref.get_samplerate())
- n = 1024
-
- rbuff = ref.read_frames(n, dtype = N.int16)
- test.write_frames(rbuff)
- tbuff = test.read_frames(n, dtype = N.int16)
-
- assert_array_equal(rbuff, tbuff)
-
- # Test seeking both read and write pointers
- test.seek(0, 0)
- test.write_frames(rbuff)
- tbuff = test.read_frames(n, dtype = N.int16)
- assert_array_equal(rbuff, tbuff)
-
- # Test seeking only read pointer
- rbuff1 = rbuff.copy()
- rbuff2 = rbuff1 * 2 + 1
- rbuff2.clip(-30000, 30000)
- test.seek(0, 0, 'r')
- test.write_frames(rbuff2)
- tbuff1 = test.read_frames(n, dtype = N.int16)
- try:
- tbuff2 = test.read_frames(n, dtype = N.int16)
- except IOError, e:
- msg = "write pointer was updated in read seek !"
- msg += "\n(msg is %s)" % e
- raise AssertionError(msg)
-
- assert_array_equal(rbuff1, tbuff1)
- assert_array_equal(rbuff2, tbuff2)
- if N.all(rbuff2 == tbuff1):
- raise AssertionError("write pointer was updated"\
- " in read seek !")
-
- # Test seeking only write pointer
- rbuff3 = rbuff1 * 2 - 1
- rbuff3.clip(-30000, 30000)
- test.seek(0, 0, 'rw')
- test.seek(n, 0, 'w')
- test.write_frames(rbuff3)
- tbuff1 = test.read_frames(n, N.int16)
- try:
- assert_array_equal(tbuff1, rbuff1)
- except AssertionError:
- raise AssertionError("read pointer was updated in write seek !")
-
- try:
- tbuff3 = test.read_frames(n, N.int16)
- except IOError, e:
- msg = "read pointer was updated in write seek !"
- msg += "\n(msg is %s)" % e
- raise AssertionError(msg)
-
- assert_array_equal(tbuff3, rbuff3)
- test.close()
-
- finally:
- close_tmp_file(rfd, cfilename)
-
-if __name__ == "__main__":
- NumpyTest().run()
+++ /dev/null
-import os
-from tempfile import mkstemp
-import sys
-
-def open_tmp_file(name):
- """On any sane platforms, return a fd on a tmp file. On windows, returns
- the filename, and as such, is not secure (someone else can reopen the file
- in between)."""
- fd, cfilename = mkstemp('pysndfiletest.wav')
- if sys.platform == 'win32':
- return fd, cfilename, cfilename
- else:
- return fd, fd, cfilename
-
-def close_tmp_file(fd, filename):
- """On any sane platforms, remove the file . On windows, only close the
- file."""
- os.close(fd)
- os.remove(filename)
-
+++ /dev/null
-[egg_info]
-#tag_svn_revision = 1
-tag_build = .dev
-
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Tue Jul 29 12:00 PM 2008 J
-
-# Copyright (C) 2006-2007 Cournapeau David <cournape@gmail.com>
-#
-# This library is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation; either version 2.1 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with this library; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# TODO:
-# - check how to handle cmd line build options with distutils and use
-# it in the building process
-
-descr = """ audiolab is a small python package to import data from audio
-files to numpy arrays and export data from numpy arrays to audio files. It uses
-libsndfile from Erik Castro de Lopo for the underlying IO, which supports many
-different audio formats: http://www.mega-nerd.com/libsndfile/
-
-For now, the python api for audio IO should be stable; a matlab-like API is
-also available for quick read/write (ala wavread, wavwrite, etc...). For 1.0
-release, I hope to add support for simple read/write to soundcard, to be able
-to record and listen to data in numpy arrays.
-
-2006-2007, David Cournapeau
-
-LICENSE: audiolab is licensed under the LGPL, as is libsndfile itself. See
-COPYING.txt for details. """
-
-from os.path import join
-import os
-import sys
-
-DISTNAME = 'scikits.audiolab'
-DESCRIPTION = 'A python module to make noise from numpy arrays'
-LONG_DESCRIPTION = descr
-MAINTAINER = 'David Cournapeau',
-MAINTAINER_EMAIL = 'david@ar.media.kyoto-u.ac.jp',
-URL = 'http://www.ar.media.kyoto-u.ac.jp/members/david/softwares/audiolab',
-LICENSE = 'LGPL'
-DOWNLOAD_URL = URL
-
-SNDFILE_MAJ_VERSION = 1
-
-# The following is more or less random copy/paste from numpy.distutils ...
-import setuptools
-from distutils.errors import DistutilsError
-from numpy.distutils.system_info import system_info, NotFoundError, dict_append, so_ext
-from numpy.distutils.core import setup, Extension
-
-class SndfileNotFoundError(NotFoundError):
- """ sndfile (http://www.mega-nerd.com/libsndfile/) library not found.
- Directories to search for the libraries can be specified in the
- site.cfg file (section [sndfile])."""
-
-class sndfile_info(system_info):
- #variables to override
- section = 'sndfile'
- notfounderror = SndfileNotFoundError
- libname = 'sndfile'
- header = 'sndfile.h'
-
- def __init__(self):
- system_info.__init__(self)
-
- def library_extensions(self):
- # We rewrite library_extension
- exts = system_info.library_extensions(self)
- if sys.platform == 'win32':
- exts.insert(0, '.dll')
- return exts
-
- def calc_info(self):
- """ Compute the informations of the library """
- prefix = 'lib'
-
- # Look for the shared library
- sndfile_libs = self.get_libs('sndfile_libs', self.libname)
- lib_dirs = self.get_lib_dirs()
- tmp = None
- for i in lib_dirs:
- tmp = self.check_libs(i, sndfile_libs)
- if tmp is not None:
- info = tmp
- break
- if tmp is None:
- raise SndfileNotFoundError("sndfile library not found")
-
- # Look for the header file
- include_dirs = self.get_include_dirs()
- inc_dir = None
- for d in include_dirs:
- p = self.combine_paths(d,self.header)
- if p:
- inc_dir = os.path.dirname(p[0])
- headername = os.path.abspath(p[0])
- break
-
- if inc_dir is None:
- raise SndfileNotFoundError("header not found")
-
- if inc_dir is not None and tmp is not None:
- if sys.platform == 'win32':
- # win32 case
- fullname = prefix + tmp['libraries'][0] + \
- '.dll'
- elif sys.platform == 'darwin':
- # Mac Os X case
- fullname = prefix + tmp['libraries'][0] + '.' + \
- str(SNDFILE_MAJ_VERSION) + '.dylib'
- else:
- # All others (Linux for sure; what about solaris) ?
- fullname = prefix + tmp['libraries'][0] + '.so' + \
- '.' + str(SNDFILE_MAJ_VERSION)
- fullname = os.path.join(info['library_dirs'][0], fullname)
- dict_append(info, include_dirs=[inc_dir],
- fullheadloc = headername,
- fulllibloc = fullname)
- else:
- raise RuntimeError("This is a bug")
-
- #print self
- self.set_info(**info)
- return
-
-from header_parser import do_subst_in_file
-def configuration(parent_package='',top_path=None, package_name=DISTNAME):
- if os.path.exists('MANIFEST'): os.remove('MANIFEST')
- if os.path.exists('scikits/audiolab/pysndfile.py'): os.remove('scikits/audiolab/pysndfile.py')
-
- pkg_prefix_dir = os.path.join('scikits', 'audiolab')
- # Check that sndfile can be found and get necessary informations
- # (assume only one header and one library file)
- sf_info = sndfile_info()
- sf_config = sf_info.get_info(2)
- headername = sf_config['fullheadloc']
- libname = sf_config['fulllibloc']
-
- # Now, generate pysndfile.py.in
- from generate_const import generate_enum_dicts
- repdict = generate_enum_dicts(headername)
- repdict['%SHARED_LOCATION%'] = libname
- #do_subst_in_file('pysndfile.py.in', 'pysndfile.py', repdict)
- do_subst_in_file(os.path.join(pkg_prefix_dir, 'pysndfile.py.in'),
- os.path.join(pkg_prefix_dir, 'pysndfile.py'),
- repdict)
-
- # Get the version
- from scikits.audiolab.info import VERSION as audiolab_version
-
- from numpy.distutils.misc_util import Configuration
- config = Configuration(package_name,parent_package,top_path,
- version = audiolab_version,
- maintainer = MAINTAINER,
- maintainer_email = MAINTAINER_EMAIL,
- description = DESCRIPTION,
- license = LICENSE,
- url = URL,
- download_url = DOWNLOAD_URL,
- long_description = LONG_DESCRIPTION)
-
- # XXX: once in SVN, should add svn version...
- #print config.make_svn_version_py()
-
- # package_data does not work with sdist for setuptools 0.5 (setuptools bug),
- # so we need to add them here while the bug is not solved...
- config.add_data_files(('docs', \
- ['scikits/audiolab/docs/' + i for i in DOC_FILES]))
-
- config.add_data_files(('test_data', \
- ['scikits/audiolab/test_data/' + i
- for i in TEST_DATA_FILES]))
-
- config.add_data_files(('misc', \
- ['scikits/audiolab/misc/' + i
- for i in BAD_FLAC_FILES]))
-
- config.add_data_dir(('examples', 'scikits/audiolab/docs/examples'))
-
- return config
-
-TEST_DATA_FILES = ['test.raw', 'test.flac', 'test.wav', 'test.au',
- 'test.sdif']
-DOC_FILES = ['audiolab.pdf', 'index.txt']
-BAD_FLAC_FILES = ['Makefile', 'badflac.flac', 'badflac.c']
-
-if __name__ == "__main__":
- # setuptools version of config script
-
- # package_data does not work with sdist for setuptools 0.5 (setuptools bug)
- # So we cannot add data files via setuptools yet.
-
- #data_files = ['test_data/' + i for i in TEST_DATA_FILES]
- #data_files.extend(['docs/' + i for i in doc_files])
-
- setup(configuration = configuration,
- install_requires='numpy', # can also add version specifiers
- namespace_packages=['scikits'],
- packages=setuptools.find_packages(),
- include_package_data = True,
- #package_data = {'scikits.audiolab': data_files},
- test_suite="tester", # for python setup.py test
- zip_safe=True, # the package can run out of an .egg file
- #FIXME url, download_url, ext_modules
- classifiers =
- [ 'Development Status :: 4 - Beta',
- 'Environment :: Console',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Science/Research',
- 'License :: OSI Approved :: LGPL License',
- 'Topic :: Multimedia :: Sound/Audio',
- 'Topic :: Scientific/Engineering']
- )
+++ /dev/null
-# Check Win32 info for using audiolab on windows
-[sndfile]
-include_dirs = c:\local\include
-library_dirs = c:\local\lib
-sndfile_libs = sndfile-1
+++ /dev/null
-[sndfile]
-include_dirs = /usr/media/boulot/src/sigtools/pyaudio/local/include
-library_dirs = /usr/media/boulot/src/sigtools/pyaudio/local/lib
-sndfile_libs = sndfile
-#include_dirs = /home/david/local/include
-#library_dirs = /home/david/local/lib
-#libraries = sndfile
-
+++ /dev/null
-#! /usr/bin/env python
-# Last Change: Sat Jul 21 03:00 PM 2007 J
-
-"""Mini script useful for top level testing of the learn package."""
-
-from numpy.testing import NumpyTest
-
-def additional_tests():
- # XXX: does this guarantee that the package is the one in the dev trunk, and
- # not scikits.foo installed somewhere else ?
- import scikits.audiolab
- np = NumpyTest(scikits.audiolab)
- return np._test_suite_from_all_tests(np.package, level = 10, verbosity = 1)