summaryrefslogtreecommitdiff
path: root/gr-audio-windows
diff options
context:
space:
mode:
authorjcorgan2006-08-03 04:51:51 +0000
committerjcorgan2006-08-03 04:51:51 +0000
commit5d69a524f81f234b3fbc41d49ba18d6f6886baba (patch)
treeb71312bf7f1e8d10fef0f3ac6f28784065e73e72 /gr-audio-windows
downloadgnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.gz
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.tar.bz2
gnuradio-5d69a524f81f234b3fbc41d49ba18d6f6886baba.zip
Houston, we have a trunk.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gr-audio-windows')
-rw-r--r--gr-audio-windows/AUTHORS2
-rw-r--r--gr-audio-windows/ChangeLog42
-rw-r--r--gr-audio-windows/Makefile.am24
-rw-r--r--gr-audio-windows/README66
-rw-r--r--gr-audio-windows/src/Makefile.am87
-rw-r--r--gr-audio-windows/src/audio_windows.i68
-rw-r--r--gr-audio-windows/src/audio_windows_sink.cc324
-rw-r--r--gr-audio-windows/src/audio_windows_sink.h83
-rw-r--r--gr-audio-windows/src/audio_windows_source.cc208
-rw-r--r--gr-audio-windows/src/audio_windows_source.h68
-rwxr-xr-xgr-audio-windows/src/qa_audio_windows.py40
-rwxr-xr-xgr-audio-windows/src/run_tests.in47
12 files changed, 1059 insertions, 0 deletions
diff --git a/gr-audio-windows/AUTHORS b/gr-audio-windows/AUTHORS
new file mode 100644
index 000000000..a11898d63
--- /dev/null
+++ b/gr-audio-windows/AUTHORS
@@ -0,0 +1,2 @@
+Eric Blossom <eb@comsec.com>
+Martin Dvh <nldudok1 at olifantasia com >
diff --git a/gr-audio-windows/ChangeLog b/gr-audio-windows/ChangeLog
new file mode 100644
index 000000000..3e5ffe024
--- /dev/null
+++ b/gr-audio-windows/ChangeLog
@@ -0,0 +1,42 @@
+2005-08-09 Eric Blossom <eb@comsec.com>
+
+ * config/gr_python.m4: tweak for cygwin from Andrew Beck.
+ * src/audio_windows_sink.h: #define NOMINMAX to keep windows from
+ defining min and max under Cygwin.
+
+2005-07-23 Stephane Fillod <f8cfe@free.fr>
+
+ * config/gr_libgnuradio_core_extra_ldflags.m4: new
+ * config/Makefile.am, configure.ac, src/Makefile.am: added
+ EXTRA_LDFLAGS for --enable-runtime-pseudo-reloc option.
+ * config/gr_python.m4: update from gnuradio-core
+
+2005-07-07 Eric Blossom <eb@comsec.com>
+
+ * src/audio_windows_source.cc: reformatted slightly.
+
+2005-05-12 Martin Dvh <nldudok1 at olifantasia com>
+
+ Initial version based loosely on gr-audio-oss-0.6
+ only audio_sink for now (audio_source is empty stub)
+
+#
+# Copyright 2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
diff --git a/gr-audio-windows/Makefile.am b/gr-audio-windows/Makefile.am
new file mode 100644
index 000000000..ed5e75246
--- /dev/null
+++ b/gr-audio-windows/Makefile.am
@@ -0,0 +1,24 @@
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-audio-windows/README b/gr-audio-windows/README
new file mode 100644
index 000000000..70fbe3ad2
--- /dev/null
+++ b/gr-audio-windows/README
@@ -0,0 +1,66 @@
+
+# Copyright 2001,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+gr-audio-windows will add an audio-sink to gnuradio for windows
+
+Requirements for building:
+make sure you have the following installed:
+mingw
+libtool (recent version ,built yourself, (if needed remove old libtool macros from /usr/share/aclocal))
+msys
+python2.4 (just install the prebuild binary for windows)
+boost (built yourself, maybe just unpacking the source somewhere will do, we only use header files)
+cppunit (built yourself)
+gnuradio-core (built with mingw)
+
+Building:
+sources from cvs:
+edit bootstrap to your needs (see below for example)
+./bootstrap
+./configure /configure --with-cppunit-prefix=/whereiscppunit --with-boost-include-dir=/c/whereisboost PYTHON=/c/Python24/python am_cv_python_pythondir=/c/Python24/Lib/site-packages am_cv_python_pyexecdir=/c/Python24/Lib/site-packages
+make
+make check
+make install
+
+
+If you have multiple versions of aclocal then edit bootstrap and change aclocal and automake to the latest version
+
+You really need a recent libtool to get this built on mingw.
+If you build it with default options it will be placed in /usr/local, but the default libtool will still be in /usr.
+This will result in old m4 macros will be used by aclocal.
+So if you have a more recent libtool installed in /usr/local add -I /usr/local/share/aclocal to the aclocal commandline in bootstrap.
+(And add any other directories with the most recent m4 macros)
+You could also uninstall (delete) the old libtool macros in /usr/share/aclocal
+
+bootstrap example:
+
+!/bin/sh
+rm -fr config.cache autom4te*.cache
+aclocal-1.8 -I /usr/local/share/aclocal -I config
+autoconf
+autoheader
+libtoolize --automake
+automake-1.8 --add-missing
+
+
+configuration example:
+./configure --with-cppunit-prefix=/usr/local --with-boost-include-dir=/d/boost_1_32_0/include/boost-1_32 PYTHON=/d/Python24/python am_cv_python_pythondir=/d/Python24/Lib/site-packages am_cv_python_pyexecdir=/d/Python24/Lib/site-packages
+
+Martin Dvh, juli 2005
diff --git a/gr-audio-windows/src/Makefile.am b/gr-audio-windows/src/Makefile.am
new file mode 100644
index 000000000..3d9446d3e
--- /dev/null
+++ b/gr-audio-windows/src/Makefile.am
@@ -0,0 +1,87 @@
+#
+# Copyright 2004,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.audio_windows module
+# This usually ends up at:
+# ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES = \
+ audio_windows.i
+
+NON_LOCAL_IFILES = \
+ $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES = \
+ $(LOCAL_IFILES) \
+ $(NON_LOCAL_IFILES)
+
+BUILT_SOURCES = \
+ audio_windows.cc \
+ audio_windows.py
+
+ourpython_PYTHON = \
+ audio_windows.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGCPPPYTHONARGS = -python $(PYTHON_CPPFLAGS) \
+ -I$(swigincludedir) -I$(grincludedir)
+
+ourlib_LTLIBRARIES = _audio_windows.la
+
+_audio_windows_la_SOURCES = \
+ audio_windows.cc \
+ audio_windows_sink.cc \
+ audio_windows_source.cc
+
+
+grinclude_HEADERS = \
+ audio_windows_sink.h \
+ audio_windows_source.h
+
+swiginclude_HEADERS = \
+ $(LOCAL_IFILES)
+
+_audio_windows_la_LIBADD = \
+ $(PYTHON_LDFLAGS) \
+ $(GNURADIO_CORE_LIBS) \
+ -lwinmm \
+ -lstdc++
+
+_audio_windows_la_LDFLAGS = -no-undefined -module -avoid-version \
+ $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+
+audio_windows.cc audio_windows.py: audio_windows.i
+ $(SWIG) $(SWIGCPPPYTHONARGS) -module audio_windows -o audio_windows.cc $<
+
+
+noinst_PYTHON = qa_audio_windows.py
+
+MOSTLYCLEANFILES = \
+ $(BUILT_SOURCES) *~ *.pyc
diff --git a/gr-audio-windows/src/audio_windows.i b/gr-audio-windows/src/audio_windows.i
new file mode 100644
index 000000000..99e9e43a2
--- /dev/null
+++ b/gr-audio-windows/src/audio_windows.i
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i" // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
+#include "audio_windows_sink.h"
+#include "audio_windows_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_windows,sink)
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq,
+ const std::string dev = ""
+ ) throw (std::runtime_error);
+
+
+class audio_windows_sink : public gr_sync_block {
+ protected:
+ audio_windows_sink (int sampling_freq, const std::string device_name = "");
+
+ public:
+ ~audio_windows_sink ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_windows,source)
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq,
+ const std::string dev = ""
+ ) throw (std::runtime_error);
+
+class audio_windows_source : public gr_sync_block {
+ protected:
+ audio_windows_source (int sampling_freq, const std::string device_name = "");
+
+ public:
+ ~audio_windows_source ();
+};
diff --git a/gr-audio-windows/src/audio_windows_sink.cc b/gr-audio-windows/src/audio_windows_sink.cc
new file mode 100644
index 000000000..ff1d19cdc
--- /dev/null
+++ b/gr-audio-windows/src/audio_windows_sink.cc
@@ -0,0 +1,324 @@
+/* -*- c++ -*- */
+/*
+* Copyright 2004 Free Software Foundation, Inc.
+*
+* This file is part of GNU Radio
+*
+* GNU Radio is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* GNU Radio 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with GNU Radio; see the file COPYING. If not, write to
+* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_windows_sink.h>
+#include <gr_io_signature.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+
+static const double CHUNK_TIME = 0.1; //0.001; // 100 ms
+
+// FIXME these should query some kind of user preference
+
+static std::string
+default_device_name ()
+{
+ return "WAVE_MAPPER";
+}
+
+audio_windows_sink::audio_windows_sink (int sampling_freq, const std::string device_name)
+ : gr_sync_block ("audio_windows_sink",
+ gr_make_io_signature (1, 2, sizeof (float)),
+ gr_make_io_signature (0, 0, 0)),
+ d_sampling_freq (sampling_freq),
+ d_device_name (device_name.empty ()? default_device_name () : device_name),
+ d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+ d_wave_write_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+ if (open_waveout_device () < 0)
+ {
+ //fprintf (stderr, "audio_windows_sink:open_waveout_device() failed\n");
+ perror ("audio_windows_sink:open_waveout_device( ) failed\n");
+ throw
+ std::runtime_error ("audio_windows_sink:open_waveout_device() failed");
+ }
+
+ d_chunk_size = (int) (d_sampling_freq * CHUNK_TIME);
+ set_output_multiple (d_chunk_size);
+
+ d_buffer = new short[d_chunk_size * 2];
+
+}
+
+audio_windows_sink::~audio_windows_sink ()
+{
+ /* Free the callback Event */
+ CloseHandle (d_wave_write_event);
+ waveOutClose (d_h_waveout);
+ delete[]d_buffer;
+}
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq, const std::string dev)
+{
+ return audio_windows_sink_sptr (new
+ audio_windows_sink (sampling_freq, dev));
+}
+
+
+int
+audio_windows_sink::work (int noutput_items,
+ gr_vector_const_void_star & input_items,
+ gr_vector_void_star & output_items)
+{
+ const float *f0, *f1;
+ bool playtestsound = false;
+ if (playtestsound)
+ {
+ // dummy
+
+ f0 = (const float *) input_items[0];
+
+ for (int i = 0; i < noutput_items; i += d_chunk_size)
+ {
+ for (int j = 0; j < d_chunk_size; j++)
+ {
+ d_buffer[2 * j + 0] = (short) (sin (2.0 * 3.1415926535897932384626 * (float) j * 1000.0 / (float) d_sampling_freq) * 8192 + 0); //+32767
+ d_buffer[2 * j + 1] = d_buffer[2 * j + 0];
+ }
+ f0 += d_chunk_size;
+ if (write_waveout
+ ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+ {
+ fprintf (stderr, "audio_windows_sink: write failed\n");
+ perror ("audio_windows_sink: write failed");
+ }
+ }
+ // break;
+ }
+ else
+ {
+ switch (input_items.size ())
+ {
+
+ case 1: // mono input
+
+ f0 = (const float *) input_items[0];
+
+ for (int i = 0; i < noutput_items; i += d_chunk_size)
+ {
+ for (int j = 0; j < d_chunk_size; j++)
+ {
+ d_buffer[2 * j + 0] = (short) (f0[j] * 32767);
+ d_buffer[2 * j + 1] = (short) (f0[j] * 32767);
+ }
+ f0 += d_chunk_size;
+ if (write_waveout
+ ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+ {
+ //fprintf (stderr, "audio_windows_sink: write failed\n");
+ perror ("audio_windows_sink: write failed");
+ }
+ }
+ break;
+
+ case 2: // stereo input
+
+ f0 = (const float *) input_items[0];
+ f1 = (const float *) input_items[1];
+
+ for (int i = 0; i < noutput_items; i += d_chunk_size)
+ {
+ for (int j = 0; j < d_chunk_size; j++)
+ {
+ d_buffer[2 * j + 0] = (short) (f0[j] * 32767);
+ d_buffer[2 * j + 1] = (short) (f1[j] * 32767);
+ }
+ f0 += d_chunk_size;
+ f1 += d_chunk_size;
+ if (write_waveout
+ ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+ {
+ //fprintf (stderr, "audio_windows_sink: write failed\n");
+ perror ("audio_windows_sink: write failed");
+ }
+ }
+ break;
+ }
+ }
+ return noutput_items;
+}
+
+int
+audio_windows_sink::string_to_int (const std::string & s)
+{
+ int i;
+ std::istringstream (s) >> i;
+ return i;
+} //ToInt()
+
+int
+audio_windows_sink::open_waveout_device (void)
+{
+
+ UINT /*UINT_PTR */ u_device_id;
+ /** Identifier of the waveform-audio output device to open. It can be either a device identifier or a handle of an open waveform-audio input device. You can use the following flag instead of a device identifier.
+ *
+ * Value Meaning
+ * WAVE_MAPPER The function selects a waveform-audio output device capable of playing the given format.
+ */
+ if (d_device_name.empty () || default_device_name () == d_device_name)
+ u_device_id = WAVE_MAPPER;
+ else
+ u_device_id = (UINT) string_to_int (d_device_name);
+ // Open a waveform device for output using event callback.
+
+ unsigned long result;
+ //HWAVEOUT outHandle;
+ WAVEFORMATEX wave_format;
+
+ /* Initialize the WAVEFORMATEX for 16-bit, 44KHz, stereo */
+ wave_format.wFormatTag = WAVE_FORMAT_PCM;
+ wave_format.nChannels = 2;
+ wave_format.nSamplesPerSec = d_sampling_freq; //44100;
+ wave_format.wBitsPerSample = 16;
+ wave_format.nBlockAlign =
+ wave_format.nChannels * (wave_format.wBitsPerSample / 8);
+ wave_format.nAvgBytesPerSec =
+ wave_format.nSamplesPerSec * wave_format.nBlockAlign;
+ wave_format.cbSize = 0;
+
+ /* Open the (preferred) Digital Audio Out device. */
+ result = waveOutOpen (&d_h_waveout, WAVE_MAPPER, &wave_format, (DWORD_PTR) d_wave_write_event, 0, CALLBACK_EVENT | WAVE_ALLOWSYNC); //|WAVE_FORMAT_DIRECT | CALLBACK_EVENT| WAVE_ALLOWSYNC
+ if (result)
+ {
+ fprintf (stderr,
+ "audio_windows_sink: Failed to open waveform output device.\n");
+ perror ("audio_windows_sink: Failed to open waveform output device.");
+ //LocalUnlock(hFormat);
+ //LocalFree(hFormat);
+ //mmioClose(hmmio, 0);
+ return -1;
+ }
+
+ //
+ // Do not Swallow the "open" event.
+ //
+ //WaitForSingleObject(d_wave_write_event, INFINITE);
+
+ // Allocate and lock memory for the header.
+
+ d_h_wave_hdr = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE,
+ (DWORD) sizeof (WAVEHDR));
+ if (d_h_wave_hdr == NULL)
+ {
+ //GlobalUnlock(hData);
+ //GlobalFree(hData);
+ //fprintf (stderr, "audio_windows_sink: Not enough memory for header.\n");
+ perror ("audio_windows_sink: Not enough memory for header.");
+ return -1;
+ }
+
+ d_lp_wave_hdr = (LPWAVEHDR) GlobalLock (d_h_wave_hdr);
+ if (d_lp_wave_hdr == NULL)
+ {
+ //GlobalUnlock(hData);
+ //GlobalFree(hData);
+ //fprintf (stderr, "audio_windows_sink: Failed to lock memory for header.\n");
+ perror ("audio_windows_sink: Failed to lock memory for header.");
+ return -1;
+ }
+ //d_lp_wave_hdr->dwFlags = WHDR_DONE;
+ return 0;
+}
+
+int
+audio_windows_sink::write_waveout (HPSTR lp_data, DWORD dw_data_size)
+{
+ UINT w_result;
+ int teller = 100;
+ // After allocation, set up and prepare header.
+ /*while ((d_lp_wave_hdr->dwFlags & WHDR_DONE)==0 && teller>0)
+ {
+ teller--;
+ Sleep(1);
+ } */
+ // Wait until previous wave write completes (first event is the open event).
+ WaitForSingleObject (d_wave_write_event, 100); //INFINITE
+ d_lp_wave_hdr->lpData = lp_data;
+ d_lp_wave_hdr->dwBufferLength = dw_data_size;
+ d_lp_wave_hdr->dwFlags = 0L;
+ /* Clear the WHDR_DONE bit (which the driver set last time that
+ this WAVEHDR was sent via waveOutWrite and was played). Some
+ drivers need this to be cleared */
+ //d_lp_wave_hdr->dwFlags &= ~WHDR_DONE;
+
+ d_lp_wave_hdr->dwLoops = 0L;
+ w_result =
+ waveOutPrepareHeader (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+ if (w_result != 0)
+ {
+ //GlobalUnlock( hData);
+ //GlobalFree(hData);
+ //fprintf (stderr, "audio_windows_sink: Failed to waveOutPrepareHeader. error %i\n",w_result);
+ perror ("audio_windows_sink: Failed to waveOutPrepareHeader");
+ }
+ // Now the data block can be sent to the output device. The
+ // waveOutWrite function returns immediately and waveform
+ // data is sent to the output device in the background.
+ //while (! readyforplayback) Sleep(1);
+ //readyforplayback=false;
+ //
+ //
+
+ w_result = waveOutWrite (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+ if (w_result != 0)
+ {
+ //GlobalUnlock( hData);
+ //GlobalFree(hData);
+ //fprintf (stderr, "audio_windows_sink: Failed to write block to device.error %i\n",w_result);
+ perror ("audio_windows_sink: Failed to write block to device");
+ switch (w_result)
+ {
+ case MMSYSERR_INVALHANDLE:
+ fprintf (stderr, "Specified device handle is invalid. \n");
+ break;
+ case MMSYSERR_NODRIVER:
+ fprintf (stderr, " No device driver is present. \n");
+ break;
+ case MMSYSERR_NOMEM:
+ fprintf (stderr, " Unable to allocate or lock memory. \n");
+ break;
+ case WAVERR_UNPREPARED:
+ fprintf (stderr,
+ " The data block pointed to by the pwh parameter hasn't been prepared. \n");
+ break;
+ default:
+ fprintf (stderr, "Unknown error %i\n", w_result);
+ }
+ waveOutUnprepareHeader (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+ return -1;
+ }
+ // WaitForSingleObject(d_wave_write_event, INFINITE);
+ return 0;
+}
diff --git a/gr-audio-windows/src/audio_windows_sink.h b/gr-audio-windows/src/audio_windows_sink.h
new file mode 100644
index 000000000..0d7e630da
--- /dev/null
+++ b/gr-audio-windows/src/audio_windows_sink.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_AUDIO_WINDOWS_SINK_H
+#define INCLUDED_AUDIO_WINDOWS_SINK_H
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX // stops windef.h defining max/min under cygwin
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_windows_sink;
+typedef boost::shared_ptr <audio_windows_sink> audio_windows_sink_sptr;
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq, const std::string dev = "");
+
+/*!
+ * \brief audio sink using winmm mmsystem (win32 only)
+ *
+ * input signature is one or two streams of floats.
+ * Input samples must be in the range [-1,1].
+ */
+
+class audio_windows_sink : public gr_sync_block
+{
+ friend
+ audio_windows_sink_sptr
+ audio_windows_make_sink (int sampling_freq, const std::string device_name);
+
+ int d_sampling_freq;
+ std::string d_device_name;
+ int d_fd;
+ short *d_buffer;
+ int d_chunk_size;
+ HWAVEOUT d_h_waveout;
+ HGLOBAL d_h_wave_hdr;
+ LPWAVEHDR d_lp_wave_hdr;
+ HANDLE d_wave_write_event;
+
+protected:
+ int
+ string_to_int (const std::string & s);
+ audio_windows_sink (int sampling_freq, const std::string device_name = "");
+ int
+ open_waveout_device (void);
+ int
+ write_waveout (HPSTR lp_data, DWORD dw_data_size);
+
+public:
+ ~audio_windows_sink ();
+
+ int
+ work (int noutput_items,
+ gr_vector_const_void_star & input_items,
+ gr_vector_void_star & output_items);
+};
+
+#endif /* INCLUDED_AUDIO_WINDOWS_SINK_H */
diff --git a/gr-audio-windows/src/audio_windows_source.cc b/gr-audio-windows/src/audio_windows_source.cc
new file mode 100644
index 000000000..8879e3b2d
--- /dev/null
+++ b/gr-audio-windows/src/audio_windows_source.cc
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_windows_source.h>
+#include <gr_io_signature.h>
+//include <sys/soundcard.h>
+//include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+static const double CHUNK_TIME = 0.005; // 5 ms
+
+// FIXME these should query some kind of user preference
+
+static std::string
+default_device_name ()
+{
+ return "/dev/dsp";
+}
+
+audio_windows_source::audio_windows_source (int sampling_freq, const std::string device_name)
+ : gr_sync_block ("audio_windows_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 2, sizeof (float))),
+ d_sampling_freq (sampling_freq),
+ d_device_name (device_name.empty ()? default_device_name () : device_name),
+ d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+ //FIXME TODO implement me
+#if 0
+ if ((d_fd = open (d_device_name.c_str (), O_RDONLY)) < 0)
+ {
+ fprintf (stderr, "audio_windows_source: ");
+ perror (d_device_name.c_str ());
+ throw
+ std::runtime_error ("audio_windows_source");
+ }
+
+ d_chunk_size = (int) (d_sampling_freq * CHUNK_TIME);
+ set_output_multiple (d_chunk_size);
+
+ d_buffer = new short[d_chunk_size * 2];
+
+ int format = AFMT_S16_NE;
+ int orig_format = format;
+ if (ioctl (d_fd, SNDCTL_DSP_SETFMT, &format) < 0)
+ {
+ std::
+ cerr << "audio_windows_source: " << d_device_name <<
+ " ioctl failed\n";
+ perror (d_device_name.c_str ());
+ throw
+ std::runtime_error ("audio_windows_source");
+ }
+
+ if (format != orig_format)
+ {
+ fprintf (stderr, "audio_windows_source: unable to support format %d\n",
+ orig_format);
+ fprintf (stderr, " card requested %d instead.\n", format);
+ }
+
+ // set to stereo no matter what. Some hardware only does stereo
+ int channels = 2;
+ if (ioctl (d_fd, SNDCTL_DSP_CHANNELS, &channels) < 0 || channels != 2)
+ {
+ perror ("audio_windows_source: could not set STEREO mode");
+ throw
+ std::runtime_error ("audio_windows_source");
+ }
+
+ // set sampling freq
+ int sf = sampling_freq;
+ if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0)
+ {
+ std::cerr << "audio_windows_source: "
+ << d_device_name << ": invalid sampling_freq "
+ << sampling_freq << "\n";
+ sampling_freq = 8000;
+ if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0)
+ {
+ std::
+ cerr <<
+ "audio_windows_source: failed to set sampling_freq to 8000\n";
+ throw
+ std::runtime_error ("audio_windows_source");
+ }
+ }
+#endif
+}
+
+audio_windows_source::~audio_windows_source ()
+{
+ /*close (d_fd);
+ delete [] d_buffer;
+ */
+}
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq, const std::string dev)
+{
+ return audio_windows_source_sptr (new
+ audio_windows_source (sampling_freq,
+ dev));
+}
+
+
+int
+audio_windows_source::work (int noutput_items,
+ gr_vector_const_void_star & input_items,
+ gr_vector_void_star & output_items)
+{
+ //FIXME TODO implement me
+#if 0
+ float *f0 = (float *) output_items[0];
+ float *f1 = (float *) output_items[1]; // will be invalid if this is mono output
+
+ const int shorts_per_item = 2; // L + R
+ const int bytes_per_item = shorts_per_item * sizeof (short);
+
+ // To minimize latency, never return more than CHUNK_TIME
+ // worth of samples per call to work.
+ // FIXME, we need an API to set this value
+
+ noutput_items = std::min (noutput_items, d_chunk_size);
+
+ int base = 0;
+ int ntogo = noutput_items;
+
+ while (ntogo > 0)
+ {
+ int nbytes = std::min (ntogo, d_chunk_size) * bytes_per_item;
+ int result_nbytes = read (d_fd, d_buffer, nbytes);
+
+ if (result_nbytes < 0)
+ {
+ perror ("audio_windows_source");
+ return -1; // say we're done
+ }
+
+ if ((result_nbytes & (bytes_per_item - 1)) != 0)
+ {
+ fprintf (stderr, "audio_windows_source: internal error.\n");
+ throw std::runtime_error ("internal error");
+ }
+
+ int result_nitems = result_nbytes / bytes_per_item;
+
+ // now unpack samples into output streams
+
+ switch (output_items.size ())
+ {
+ case 1: // mono output
+ for (int i = 0; i < result_nitems; i++)
+ {
+ f0[base + i] = d_buffer[2 * i + 0] * (1.0 / 32767);
+ }
+ break;
+
+ case 2: // stereo output
+ for (int i = 0; i < result_nitems; i++)
+ {
+ f0[base + i] = d_buffer[2 * i + 0] * (1.0 / 32767);
+ f1[base + i] = d_buffer[2 * i + 1] * (1.0 / 32767);
+ }
+ break;
+
+ default:
+ assert (0);
+ }
+
+ ntogo -= result_nitems;
+ base += result_nitems;
+ }
+
+ return noutput_items - ntogo;
+#endif
+ return -1; // EOF
+}
diff --git a/gr-audio-windows/src/audio_windows_source.h b/gr-audio-windows/src/audio_windows_source.h
new file mode 100644
index 000000000..718ac2f9c
--- /dev/null
+++ b/gr-audio-windows/src/audio_windows_source.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_AUDIO_WINDOWS_SOURCE_H
+#define INCLUDED_AUDIO_WINDOWS_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_windows_source;
+typedef boost::shared_ptr <audio_windows_source> audio_windows_source_sptr;
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq, const std::string dev = "");
+
+/*!
+ * \brief audio source using winmm mmsystem (win32 only)
+ *
+ * Output signature is one or two streams of floats.
+ * Output samples will be in the range [-1,1].
+ */
+
+class audio_windows_source : public gr_sync_block
+{
+ friend
+ audio_windows_source_sptr
+ audio_windows_make_source (int sampling_freq,
+ const std::string device_name);
+
+ int d_sampling_freq;
+ std::string d_device_name;
+ int d_fd;
+ short *d_buffer;
+ int d_chunk_size;
+
+protected:
+ audio_windows_source (int sampling_freq, const std::string device_name = "");
+
+public:
+ ~audio_windows_source ();
+
+ int
+ work (int noutput_items,
+ gr_vector_const_void_star & input_items,
+ gr_vector_void_star & output_items);
+};
+
+#endif /* INCLUDED_AUDIO_WINDOWS_SOURCE_H */
diff --git a/gr-audio-windows/src/qa_audio_windows.py b/gr-audio-windows/src/qa_audio_windows.py
new file mode 100755
index 000000000..e7663a8b5
--- /dev/null
+++ b/gr-audio-windows/src/qa_audio_windows.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import audio_windows
+
+class qa_oss (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.fg = gr.flow_graph ()
+
+ def tearDown (self):
+ self.fg = None
+
+ def test_000_nop (self):
+ """Just see if we can import the module...
+ They may not have audio drivers, soundcard, etc. Don't try to run anything"""
+ pass
+
+if __name__ == '__main__':
+ gr_unittest.main ()
diff --git a/gr-audio-windows/src/run_tests.in b/gr-audio-windows/src/run_tests.in
new file mode 100755
index 000000000..6eb596383
--- /dev/null
+++ b/gr-audio-windows/src/run_tests.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# All this strange PYTHONPATH manipulation is required to run our
+# tests using our just built shared library and swig-generated python
+# code prior to installation.
+
+# build tree == src tree unless you're doing a VPATH build.
+# If you don't know what a VPATH build is, you're not doing one. Relax...
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+# Where to look in the build tree for our shared library
+libbld=@abs_top_builddir@/gr-audio-windows/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-windows/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-windows/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck. We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# This is the simple part...
+# Run everything that matches qa_*.py and return the final result.
+#
+
+ok=yes
+for file in @srcdir@/qa_*.py
+do
+ if ! $file
+ then
+ ok=no
+ fi
+done
+
+if [ $ok = yes ]
+then
+ exit 0
+else
+ exit 1
+fi