Merge branch 'master' into debian
This commit is contained in:
commit
791122f068
12 changed files with 761 additions and 429 deletions
13
CHANGELOG
13
CHANGELOG
|
@ -1,3 +1,16 @@
|
|||
2012-10-20 Hubert Pham <hubert@mit.edu>
|
||||
|
||||
PyAudio 0.2.7
|
||||
|
||||
- Callback-mode: support callables.
|
||||
|
||||
Thanks to John Luebs and Bastian Bechtold for this patch.
|
||||
|
||||
- Update documentation to use Sphinx.
|
||||
|
||||
Thanks again to Bastian Bechtold for his incredible contribution!
|
||||
|
||||
|
||||
2012-09-01 Hubert Pham <hubert@mit.edu>
|
||||
|
||||
PyAudio 0.2.6
|
||||
|
|
|
@ -2,3 +2,4 @@ include src/*.c src/*.h src/*.py
|
|||
include Makefile CHANGELOG INSTALL MANIFEST.in
|
||||
recursive-include test *.py *.c
|
||||
graft docs
|
||||
graft sphinx
|
||||
|
|
34
Makefile
34
Makefile
|
@ -1,19 +1,23 @@
|
|||
# This is the PyAudio distribution makefile.
|
||||
|
||||
.PHONY: docs clean
|
||||
.PHONY: docs clean build
|
||||
|
||||
EPYDOC ?= epydoc
|
||||
|
||||
VERSION := 0.2.6
|
||||
VERSION := 0.2.7
|
||||
PYTHON ?= python
|
||||
BUILD_ARGS ?=
|
||||
SPHINX ?= sphinx-build
|
||||
DOCS_OUTPUT=docs/
|
||||
DOC_NAME := PyAudio-$(VERSION)
|
||||
DOC_URL=http://people.csail.mit.edu/hubert/pyaudio/
|
||||
PYTHON_BUILD_DIR:=$(shell $(PYTHON) -c "import distutils.util; import sys; print(distutils.util.get_platform() + '-' + sys.version[0:3])")
|
||||
BUILD_DIR:=lib.$(PYTHON_BUILD_DIR)
|
||||
BUILD_STAMP:=$(BUILD_DIR)/build
|
||||
SRCFILES := src/*.c src/*.h src/*.py
|
||||
EXAMPLES := test/*.py
|
||||
|
||||
what:
|
||||
@echo "make targets:"
|
||||
@echo
|
||||
@echo " tarball : build source tarball"
|
||||
@echo " docs : generate documentation (requires epydoc)"
|
||||
@echo " docs : generate documentation (requires sphinx)"
|
||||
@echo " clean : remove build files"
|
||||
@echo
|
||||
@echo "To build pyaudio, run:"
|
||||
|
@ -27,13 +31,17 @@ clean:
|
|||
# Documentation
|
||||
######################################################################
|
||||
|
||||
docs:
|
||||
@cd src; \
|
||||
$(EPYDOC) -v -o ../$(DOCS_OUTPUT) --name $(DOC_NAME) --url $(DOC_URL) \
|
||||
--no-private pyaudio.py
|
||||
build: build/$(BUILD_STAMP)
|
||||
|
||||
build/$(BUILD_STAMP): $(SRCFILES)
|
||||
$(PYTHON) setup.py build $(BUILD_ARGS)
|
||||
touch $@
|
||||
|
||||
docs: build
|
||||
PYTHONPATH=build/$(BUILD_DIR) $(SPHINX) -b html sphinx/ $(DOCS_OUTPUT)
|
||||
|
||||
######################################################################
|
||||
# Source Tarball
|
||||
######################################################################
|
||||
tarball: docs $(SRCFILES) MANIFEST.in
|
||||
@python setup.py sdist
|
||||
tarball: docs $(SRCFILES) $(EXAMPLES) MANIFEST.in
|
||||
@$(PYTHON) setup.py sdist
|
||||
|
|
2
README
2
README
|
@ -1,5 +1,5 @@
|
|||
======================================================================
|
||||
PyAudio v0.2.6: Python Bindings for PortAudio.
|
||||
PyAudio v0.2.7: Python Bindings for PortAudio.
|
||||
======================================================================
|
||||
|
||||
See: http://people.csail.mit.edu/hubert/pyaudio/
|
||||
|
|
4
setup.py
4
setup.py
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
PyAudio v0.2.6: Python Bindings for PortAudio.
|
||||
PyAudio v0.2.7: Python Bindings for PortAudio.
|
||||
|
||||
Copyright (c) 2006-2012 Hubert Pham
|
||||
|
||||
|
@ -30,7 +30,7 @@ from distutils.core import setup, Extension
|
|||
import sys
|
||||
import os
|
||||
|
||||
__version__ = "0.2.6"
|
||||
__version__ = "0.2.7"
|
||||
|
||||
# Note: distutils will try to locate and link dynamically
|
||||
# against portaudio.
|
||||
|
|
252
sphinx/conf.py
Normal file
252
sphinx/conf.py
Normal file
|
@ -0,0 +1,252 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# PyAudio documentation build configuration file, created by
|
||||
# sphinx-quickstart on Wed Aug 29 08:37:41 2012.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'PyAudio'
|
||||
copyright = '2012, Hubert Pham'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.2.7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.2.7'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'nature'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
"nosidebar": True
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
#html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'PyAudiodoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'PyAudio.tex', 'PyAudio Documentation',
|
||||
'Hubert Pham', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'pyaudio', 'PyAudio Documentation',
|
||||
['Hubert Pham'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'PyAudio', 'PyAudio Documentation',
|
||||
'Hubert Pham', 'PyAudio', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
try:
|
||||
from _portaudio import paMacCoreStreamInfo
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
tags.add('pamac')
|
50
sphinx/examples.rst
Normal file
50
sphinx/examples.rst
Normal file
|
@ -0,0 +1,50 @@
|
|||
Example: Blocking Mode Audio I/O
|
||||
--------------------------------
|
||||
|
||||
.. literalinclude:: ../test/play_wave.py
|
||||
|
||||
To use PyAudio, first instantiate PyAudio using
|
||||
:py:func:`pyaudio.PyAudio` (1), which sets up the portaudio system.
|
||||
|
||||
To record or play audio, open a stream on the desired device with the
|
||||
desired audio parameters using :py:func:`pyaudio.PyAudio.open`
|
||||
(2). This sets up a :py:class:`pyaudio.Stream` to play or record
|
||||
audio.
|
||||
|
||||
Play audio by writing audio data to the stream using
|
||||
:py:func:`pyaudio.Stream.write`, or read audio data from the stream
|
||||
using :py:func:`pyaudio.Stream.read`. (3)
|
||||
|
||||
Note that in "blocking mode", each :py:func:`pyaudio.Stream.write` or
|
||||
:py:func:`pyaudio.Stream.read` blocks until all the given/requested
|
||||
frames have been played/recorded. Alternatively, to generate audio
|
||||
data on the fly or immediately process recorded audio data, use the
|
||||
"callback mode" outlined below.
|
||||
|
||||
Use :py:func:`pyaudio.Stream.stop_stream` to pause playing/recording,
|
||||
and :py:func:`pyaudio.Stream.close` to terminate the stream. (4)
|
||||
|
||||
Finally, terminate the portaudio session using
|
||||
:py:func:`pyaudio.PyAudio.terminate` (5)
|
||||
|
||||
Example: Callback Mode Audio I/O
|
||||
--------------------------------
|
||||
|
||||
.. literalinclude:: ../test/play_wave_callback.py
|
||||
|
||||
In callback mode, PyAudio will call a specified callback function (2)
|
||||
whenever it needs new audio data (to play) and/or when there is new
|
||||
(recorded) audio data available. Note that PyAudio calls the callback
|
||||
function in a separate thread. The function has the following
|
||||
signature ``callback(<input_data>, <frame_count>, <time_info>,
|
||||
<status_flag>)`` and must return a tuple containing ``frame_count``
|
||||
frames of audio data and a flag signifying whether there are more
|
||||
frames to play/record.
|
||||
|
||||
Start processing the audio stream using
|
||||
:py:func:`pyaudio.Stream.start_stream` (4), which will call the
|
||||
callback function repeatedly until that function returns
|
||||
:py:data:`pyaudio.paComplete`.
|
||||
|
||||
To keep the stream active, the main thread must not terminate, e.g.,
|
||||
by sleeping (5).
|
52
sphinx/index.rst
Normal file
52
sphinx/index.rst
Normal file
|
@ -0,0 +1,52 @@
|
|||
PyAudio Documentation
|
||||
=====================
|
||||
|
||||
.. contents::
|
||||
|
||||
------------
|
||||
Introduction
|
||||
------------
|
||||
|
||||
.. automodule:: pyaudio
|
||||
:members:
|
||||
:special-members:
|
||||
:exclude-members: PyAudio, Stream, PaMacCoreStreamInfo
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
-------------
|
||||
Class PyAudio
|
||||
-------------
|
||||
|
||||
.. autoclass:: pyaudio.PyAudio
|
||||
:members:
|
||||
:special-members:
|
||||
|
||||
------------
|
||||
Class Stream
|
||||
------------
|
||||
|
||||
.. autoclass:: pyaudio.Stream
|
||||
:members:
|
||||
:special-members:
|
||||
|
||||
-----------------
|
||||
Platform Specific
|
||||
-----------------
|
||||
|
||||
.. only:: pamac
|
||||
|
||||
Class PaMacCoreStreamInfo
|
||||
-------------------------
|
||||
|
||||
.. autoclass:: pyaudio.PaMacCoreStreamInfo
|
||||
:members:
|
||||
:special-members:
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
|
@ -1651,7 +1651,7 @@ pa_open(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
int output_device_index = -1;
|
||||
PyObject *input_device_index_arg = NULL;
|
||||
PyObject *output_device_index_arg = NULL;
|
||||
PyFunctionObject *stream_callback = NULL;
|
||||
PyObject *stream_callback = NULL;
|
||||
PaSampleFormat format;
|
||||
PaError err;
|
||||
|
||||
|
@ -1687,9 +1687,9 @@ pa_open(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
#ifdef MACOSX
|
||||
"iik|iiOOiO!O!O!",
|
||||
"iik|iiOOiO!O!O",
|
||||
#else
|
||||
"iik|iiOOiOOO!",
|
||||
"iik|iiOOiOOO",
|
||||
#endif
|
||||
kwlist,
|
||||
&rate, &channels, &format,
|
||||
|
@ -1705,11 +1705,14 @@ pa_open(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
&_pyAudio_MacOSX_hostApiSpecificStreamInfoType,
|
||||
#endif
|
||||
&outputHostSpecificStreamInfo,
|
||||
&PyFunction_Type,
|
||||
&stream_callback))
|
||||
&stream_callback))
|
||||
|
||||
return NULL;
|
||||
|
||||
if (stream_callback && (PyCallable_Check(stream_callback) == 0)) {
|
||||
PyErr_SetString(PyExc_TypeError, "stream_callback must be callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check to see if device indices were specified */
|
||||
if ((input_device_index_arg == NULL) ||
|
||||
|
|
747
src/pyaudio.py
747
src/pyaudio.py
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
PyAudio Example: Play a wave file.
|
||||
"""
|
||||
"""PyAudio Example: Play a wave file."""
|
||||
|
||||
import pyaudio
|
||||
import wave
|
||||
|
@ -14,20 +12,26 @@ if len(sys.argv) < 2:
|
|||
|
||||
wf = wave.open(sys.argv[1], 'rb')
|
||||
|
||||
# instantiate PyAudio (1)
|
||||
p = pyaudio.PyAudio()
|
||||
|
||||
# open stream (2)
|
||||
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
|
||||
channels=wf.getnchannels(),
|
||||
rate=wf.getframerate(),
|
||||
output=True)
|
||||
|
||||
# read data
|
||||
data = wf.readframes(CHUNK)
|
||||
|
||||
# play stream (3)
|
||||
while data != '':
|
||||
stream.write(data)
|
||||
data = wf.readframes(CHUNK)
|
||||
|
||||
# stop stream (4)
|
||||
stream.stop_stream()
|
||||
stream.close()
|
||||
|
||||
# close PyAudio (5)
|
||||
p.terminate()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
PyAudio Example: Play a wave file (callback version)
|
||||
"""
|
||||
"""PyAudio Example: Play a wave file (callback version)."""
|
||||
|
||||
import pyaudio
|
||||
import wave
|
||||
|
@ -13,24 +11,32 @@ if len(sys.argv) < 2:
|
|||
|
||||
wf = wave.open(sys.argv[1], 'rb')
|
||||
|
||||
# instantiate PyAudio (1)
|
||||
p = pyaudio.PyAudio()
|
||||
|
||||
# define callback (2)
|
||||
def callback(in_data, frame_count, time_info, status):
|
||||
data = wf.readframes(frame_count)
|
||||
return (data, pyaudio.paContinue)
|
||||
|
||||
# open stream using callback (3)
|
||||
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
|
||||
channels=wf.getnchannels(),
|
||||
rate=wf.getframerate(),
|
||||
output=True,
|
||||
stream_callback=callback)
|
||||
|
||||
# start the stream (4)
|
||||
stream.start_stream()
|
||||
|
||||
# wait for stream to finish (5)
|
||||
while stream.is_active():
|
||||
time.sleep(0.1)
|
||||
|
||||
# stop stream (6)
|
||||
stream.stop_stream()
|
||||
stream.close()
|
||||
wf.close()
|
||||
|
||||
# close PyAudio (7)
|
||||
p.terminate()
|
||||
|
|
Loading…
Add table
Reference in a new issue