[xiph-cvs] cvs commit: ao-python/src aomodule.c aomodule.h

Andrew Catham Master of Python andrew at xiph.org
Sun Jan 21 14:11:56 PST 2001



andrew      01/01/21 14:11:55

  Modified:    .        README setup.py
               src      aomodule.c aomodule.h
  Added:       .        .cvsignore ChangeLog MANIFEST.in
  Removed:     .        build.py
  Log:
  2001-01-21  Andrew H. Chatham <andrew.chatham at duke.edu>
          * src/aomodule.c (dict_to_options): Size checking removed; no
          longer necessary
  
          * src/aomodule.h: Made comments closer to Python style guide
          * src/aomodule.[ch]: Switched to C-style comments
  
          * src/aomodule.c (py_ao_new) (py_ao_get_driver_info): Support
          string argument
  
          * src/aomodule.c (initao): Removed extra calls to AddInt
  
          * ChangeLog: Started
          * build.py: removed
  
          * setup.py: Added configuration

Revision  Changes    Path
1.2       +47 -13    ao-python/README

Index: README
===================================================================
RCS file: /usr/local/cvsroot/ao-python/README,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- README	2001/01/18 00:10:15	1.1
+++ README	2001/01/21 22:11:54	1.2
@@ -5,17 +5,51 @@
 
 To build you need distutils package from
 http://www.python.org/sigs/distutils-sig/download.html (it comes with
-Python 2.0). First edit setup.py so that the AO_INCLUDE_DIR and
-AO_LIB_DIR point to the right place. Type "python setup.py build" and
-then "python setup.py install" as root to install the module.
-
-Access the module by using "import ao" in your Python code.
-
-There is currently a problem where you can't use any ao output plugin
-which requires a symbol inside libao. This has something to do with
-linker magic and dlopen voodoo. Everything works fine compiled into a
-program, but linked into a Python module, libao's ao_is_big_endian
-function isn't available to the plugins it opens (most importantly,
-'oss'). If anybody has any clue, please let me know how to fix this...
+Python 2.0). To install:
 
-Also, right now (Nov-28-2000) the CVS for ao is a little inconsistent.
\ No newline at end of file
+python setup.py config
+python setup.py build
+[as root] python setup.py install
+
+The config script is new and still pretty weak. If you have any
+problems let me know. Access the module by using "import ao" in your
+Python code.
+
+Here's an interactive session of just playing with the module, until I
+create better documentation (there should be docstrings for
+everything). Watch as I read some random data and "play" it to a wave
+file.
+
+>>> import ao
+
+>>> myoptions = {'file': 'myoutput.wav'}
+
+>>> dev = ao.AudioDevice('wav', options = myoptions)
+
+>>> f = open('/dev/urandom', 'r') #that's some good stuff
+
+>>> print dev
+<AudioDevice object at 0x812ac28>
+
+>>> print dev.get_driver_info()
+{'author': 'Aaron Holtzman <aholtzma at ess.engr.uvic.ca>', 
+ 'short_name': 'wav', 
+ 'name': 'WAV file output', 
+ 'comment': 'Sends output to a .wav file'}
+
+>>> print ao.get_driver_info('oss')
+{'author': 'Aaron Holtzman <aholtzma at ess.engr.uvic.ca>', 
+ 'short_name': 'oss', 
+ 'name': 'OSS audio driver output ', 
+ 'comment': 'Outputs audio to the Open Sound System driver.'}
+
+>>> data = f.read(1024*8)
+
+>>> dev.play(data)
+
+>>> <control-d>
+
+And now I have a file myoutput.wav with random noise in it.
+
+
+Andrew Chatham <andrew.chatham at duke.edu>
\ No newline at end of file

1.2       +96 -9     ao-python/setup.py

Index: setup.py
===================================================================
RCS file: /usr/local/cvsroot/ao-python/setup.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- setup.py	2001/01/18 00:10:15	1.1
+++ setup.py	2001/01/21 22:11:54	1.2
@@ -1,14 +1,98 @@
 #!/usr/bin/env python
 
-"""Setup script for the Ao module distribution."""
+"""Setup script for the Ao module distribution.
+Configuration in particular could use some work."""
 
-import os
+import os, sys
 from distutils.core import setup
 from distutils.extension import Extension
+from distutils.command.config import config
+from distutils.command.build import build
 
-AO_INCLUDE_DIR = '/usr/local/include'
-AO_LIB_DIR = '/usr/local/lib'
+def load_config():
+    '''This is still a bit creaky. Hopefully distutils will
+    offer better configuration support in the future.'''
 
+    if not os.path.isfile('config.ao'):
+        print "File config.ao not found"
+        return {}
+    f = open('config.ao', 'r')
+    dict = eval(f.read())
+    return dict
+
+
+class config_ao (config):
+
+    added_variables = ('ao_include_dirs', 'ao_library_dirs', 'ao_libraries')
+
+    user_options = config.user_options + [
+        ('ao-prefix=', None,
+         'prefix in which to find ao headers and libraries'),
+        ('ao-include-dirs=', None,
+         "directories to search for ao header files"),
+        ('ao-library-dirs=', None,
+         "directories to search for ao library files"),
+        ]
+
+    def _save(self):
+        '''Save the variables I want as the representation of a dictionary'''
+        
+        dict = {}
+        for v in self.added_variables:
+            dict[v] = getattr(self, v)
+        f = open('config.ao', 'w')
+        f.write(repr(dict))
+        f.write('\n')
+
+    def initialize_options (self):
+        config.initialize_options(self)
+        self.ao_prefix = '/usr/local'
+        self.ao_include_dirs = []
+        self.ao_library_dirs = []
+        self.ao_libraries = ['ao', 'dl']
+
+
+    def finalize_options (self):
+        if not self.ao_include_dirs:
+            self.ao_include_dirs = [os.path.join(self.ao_prefix, 'include')]
+        if not self.ao_library_dirs:
+            self.ao_library_dirs = [os.path.join(self.ao_prefix, 'lib')]
+                
+    def run (self):
+        self.have_ao = self.check_lib("ao", self.ao_library_dirs,
+                                 ['ao/ao.h'], self.ao_include_dirs, ['dl'])
+
+        if not self.have_ao:
+            print "*** ao check failed ***"
+            print "You may need to install the ao library"
+            print "or pass the paths where it can be found"
+            print "(setup.py --help)"
+            sys.exit(1)
+
+        self._save()
+
+
+class nullBuilder (build):
+    '''Prevents building. This is used for when they try to build
+    without having run configure first.'''
+
+    def run(self):
+        print
+        print "*** You must first run 'setup.py config' ***"
+        print
+        sys.exit(1)
+
+cmdclass = {'config' : config_ao}
+
+config_data = load_config()
+if not config_data:
+    cmdclass['build'] = nullBuilder
+    ao_include_dirs = ao_library_dirs = ao_libraries = []
+else:
+    ao_include_dirs = config_data['ao_include_dirs']
+    ao_library_dirs = config_data['ao_library_dirs']
+    ao_libraries = config_data['ao_libraries']
+
 setup (# Distribution meta-data
         name = "pyao",
         version = "0.0.2",
@@ -17,13 +101,16 @@
         author_email = "andrew.chatham at duke.edu",
         url = "http://dulug.duke.edu/~andrew/pyvorbis.html",
 
+        cmdclass = cmdclass,
+
         # Description of the modules and packages in the distribution
 
         ext_modules = [Extension(
-                name='aomodule',
-                sources=['src/aomodule.c'],
-                include_dirs=[AO_INCLUDE_DIR],
-		library_dirs=[AO_LIB_DIR],
-                libraries=['ao'])]
+                name = 'aomodule',
+                sources = ['src/aomodule.c'],
+                include_dirs = ao_include_dirs,
+		library_dirs = ao_library_dirs,
+                libraries = ao_libraries)]
 )
+
 

1.1                  ao-python/.cvsignore

Index: .cvsignore
===================================================================
Setup
config.ao
MANIFEST
build
dist
*.pyc

1.1                  ao-python/ChangeLog

Index: ChangeLog
===================================================================
2001-01-21  Andrew H. Chatham <andrew.chatham at duke.edu>
        * src/aomodule.c (dict_to_options): Size checking removed; no
        longer necessary
        
        * src/aomodule.h: Made comments closer to Python style guide
        * src/aomodule.[ch]: Switched to C-style comments
        
        * src/aomodule.c (py_ao_new) (py_ao_get_driver_info): Support
        string argument

        * src/aomodule.c (initao): Removed extra calls to AddInt

        * ChangeLog: Started
        * build.py: removed
        
        * setup.py: Added configuration

1.1                  ao-python/MANIFEST.in

Index: MANIFEST.in
===================================================================
include ChangeLog README COPYING AUTHORS NEWS setup.py test.py MANIFEST.in
recursive-include src/ *.c *.h

1.2       +39 -29    ao-python/src/aomodule.c

Index: aomodule.c
===================================================================
RCS file: /usr/local/cvsroot/ao-python/src/aomodule.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- aomodule.c	2001/01/18 00:10:15	1.1
+++ aomodule.c	2001/01/21 22:11:55	1.2
@@ -1,7 +1,5 @@
 #include "aomodule.h"
 
-#define ERR(x) "key:val pairs limited to " #x " characters. Go bug Andrew if this is a problem."
-
 static ao_option_t *
 dict_to_options(PyObject *dict)
 {
@@ -22,11 +20,6 @@
       goto error;
     }
 
-    if (PyString_Size(key) + PyString_Size(val) > OPTSIZE - 1) {
-      PyErr_SetString(PyExc_ValueError, ERR(OPTSIZE));
-      goto error;
-    }
-
     ret = ao_append_option(&head, PyString_AsString(key), PyString_AsString(val));
     if (ret == 0) {
       PyErr_SetString(Py_aoError, "Error appending options");
@@ -47,6 +40,7 @@
 py_ao_new(PyObject *self, PyObject *args, PyObject *kwargs)
 {
   uint_32 driver_id, bits, rate, channels;
+  char * driver_name;
   PyObject *py_options = NULL;
   ao_option_t *c_options;
   ao_device_t *dev;
@@ -57,16 +51,22 @@
   channels = 2;
   c_options = NULL;
 
-  //TODO : Add support for string driver_id
+  if(PyArg_ParseTupleAndKeywords(args, kwargs, "s|lllO!", new_kwlist,
+				 &driver_name, &bits, &rate, &channels, 
+				 &PyDict_Type, &py_options)) {
+    driver_id = ao_get_driver_id(driver_name);
+  } else {
 
-  if(!(PyArg_ParseTupleAndKeywords(args, kwargs, "i|lllO!", new_kwlist,
-				   &driver_id, &bits, &rate, &channels, 
-				   &py_options, &PyDict_Type)))
-    return NULL;
+    PyErr_Clear();
+    if(!(PyArg_ParseTupleAndKeywords(args, kwargs, "i|lllO!", new_kwlist,
+				     &driver_id, &bits, &rate, &channels, 
+				     &PyDict_Type, &py_options)))
+      return NULL;
 
+  }  
   if (py_options && PyDict_Size(py_options) > 0) {
-    // dict_to_options returns NULL on error, so you can't pass
-    // an empty dictionary. We can skip this then anyway.
+    /* dict_to_options returns NULL on error, so you can't pass
+       an empty dictionary. We can skip this then anyway. */
 
     c_options = dict_to_options(py_options);
     if (!c_options) {
@@ -107,7 +107,7 @@
   if (!PyArg_ParseTuple(args, "|s", &str))
     return NULL;
 
-  driver_id = ao_get_driver_id(str); //takes NULL for default
+  driver_id = ao_get_driver_id(str); /* akes NULL for default */
 
   if (driver_id == -1) {
     PyErr_SetString(Py_aoError, "No such driver");
@@ -120,19 +120,37 @@
 static PyObject *
 py_ao_get_driver_info(PyObject *self, PyObject *args)
 {
-  int driver_id;
+  int driver_id = 0;
+  char *driver_name;
   ao_info_t *info; 
   PyObject *retdict;
 
   if (self != NULL) {
-    //It's a method
+
+    /* It's a method */
     ao_Object *ao_self = (ao_Object *) self;
     info = ao_self->dev->funcs->get_driver_info();
+
   } else {
-    //It's a string
-    if (!(PyArg_ParseTuple(args, "i", &driver_id)))
-      return NULL;
+
+    /* Maybe it's a string */
+    if ((PyArg_ParseTuple(args, "s", &driver_name))) {
+
+      driver_id = ao_get_driver_id(driver_name);
+      if (driver_id == -1) {
+	PyErr_SetString(Py_aoError, "Invalid driver name");
+      }
+
+    } else {
+      
+      /* Maybe it's an int */
+      PyErr_Clear();
+      if (!(PyArg_ParseTuple(args, "i", &driver_id)))
+	return NULL;
+    }
+    
     info = ao_get_driver_info(driver_id);
+
   }
   if (!info) {
     PyErr_SetString(Py_aoError, "Error getting info");
@@ -140,7 +158,7 @@
   }
 
   retdict = PyDict_New();
-  //TODO: More error checking here.
+
   PyDict_SetItemString(retdict, "name", 
                        PyString_FromString(info->name));
   PyDict_SetItemString(retdict, "short_name", 
@@ -202,14 +220,6 @@
   str = PyString_FromString(docstring);
   PyDict_SetItemString(dict, "__doc__", str);
   Py_DECREF(str);
-
-#ifdef AO_NULL
-  AddInt(AO_NULL);
-#endif
-
-#ifdef AO_NULL
-  AddInt(AO_NULL);
-#endif
 
 #ifdef AO_NULL
   AddInt(AO_NULL);

1.2       +11 -11    ao-python/src/aomodule.h

Index: aomodule.h
===================================================================
RCS file: /usr/local/cvsroot/ao-python/src/aomodule.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- aomodule.h	2001/01/18 00:10:15	1.1
+++ aomodule.h	2001/01/21 22:11:55	1.2
@@ -20,19 +20,21 @@
 static PyObject* py_ao_getattr(PyObject *, char *);
 
 static char py_ao_play_doc[] = 
-"x.play(buff, n=len(buff))\n\
-Writes n characters from the string/buffer buff to the audio\n\
-device represented by x. n defaults to the size of buff.";
-
+"Play the contents of a given audio buffer.\n\
+\
+\n
+Arguments:\n\
+buff : Buffer or string containing audio data\n\
+n : Number of bytes to play (defaults to len(buff))";
 static PyObject *py_ao_play(PyObject *, PyObject *);
 
 static char py_ao_get_driver_id_doc[] = 
-"get_driver_id(s)\n\
-Returns the integer identifier for the driver with name s";
+"Return the integer identifier for the driver with the given name (or object).";
 static PyObject *py_ao_get_driver_id(PyObject *, PyObject *);
 
 static char py_ao_get_driver_info_doc[] =
-"Returns a dictionary of information about a driver.\n\
+"Return a dictionary of information about a driver.\n\
+\n\
 It can either be called as a member function of an AudioDevice object:\n\
    x.get_driver_info()\n\
 or as a standalone function which takes the integer id of the driver:\n\
@@ -80,7 +82,6 @@
 
 
 struct PyMethodDef ao_Object_methods[] = {
-  // add support for open and close?
   {"get_driver_info", py_ao_get_driver_info, 
    METH_VARARGS, py_ao_get_driver_info_doc},
   {"play", py_ao_play, 
@@ -101,9 +102,8 @@
 };
 
 static char docstring[] = 
-"A Python wrapper for the ao library using in the ogg project.\n\
-By Andrew Chatham <andrew.chatham at duke.edu>\n\
-Documentation will come!";
+"A Python wrapper for the ao library using in the ogg project.";
+
 
 #endif __AO_MODULE_H__
 

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list