Merge branch 'master' into debian

This commit is contained in:
Hubert Pham 2012-10-20 21:41:20 -04:00
commit 791122f068
12 changed files with 761 additions and 429 deletions

View file

@ -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

View file

@ -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

View file

@ -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
View file

@ -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/

View file

@ -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
View 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
View 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
View 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`

View file

@ -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) ||

File diff suppressed because it is too large Load diff

View file

@ -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()

View file

@ -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()