ekiga r6098 - in trunk: . lib/engine lib/engine/audioinput lib/engine/audioinput/null lib/engine/audioinput/ptlib lib/engine/audioinput/skel lib/engine/audiooutput lib/engine/audiooutput/null lib/engine/audiooutput/ptlib lib/engine/audiooutput/skel src



Author: mschneid
Date: Sun Mar 30 19:46:13 2008
New Revision: 6098
URL: http://svn.gnome.org/viewvc/ekiga?rev=6098&view=rev

Log:
First shot at the audio input and audio output engine. Not activated yet.
Both cores feature both a PTLIB and a NULL implementation. The NULL device
is used for fallback in case a device returns an error. The Audio output core
makes use of a primary device for interactive audio and a secondary device for
sound effects. Also, the primary device can be used for sound effects.
The output core also relies on a scheduler class, which is a thread that schedules
sound events and plays them in the background. This scheduler makes use of a sound
event queue, to which events can be added or removed in a thread-safe fashion. It also
schedules recurring sound events like ringing.



Added:
   trunk/lib/engine/audioinput/
   trunk/lib/engine/audioinput/Makefile.am
   trunk/lib/engine/audioinput/null/
   trunk/lib/engine/audioinput/null/Makefile.am
   trunk/lib/engine/audioinput/null/audioinput-main-null.cpp
   trunk/lib/engine/audioinput/null/audioinput-main-null.h
   trunk/lib/engine/audioinput/null/audioinput-manager-null.cpp
   trunk/lib/engine/audioinput/null/audioinput-manager-null.h
   trunk/lib/engine/audioinput/ptlib/
   trunk/lib/engine/audioinput/ptlib/Makefile.am
   trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.cpp
   trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.h
   trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.cpp
   trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.h
   trunk/lib/engine/audioinput/skel/
   trunk/lib/engine/audioinput/skel/Makefile.am
   trunk/lib/engine/audioinput/skel/audioinput-core.cpp
   trunk/lib/engine/audioinput/skel/audioinput-core.h
   trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.cpp
   trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.h
   trunk/lib/engine/audioinput/skel/audioinput-info.h
   trunk/lib/engine/audioinput/skel/audioinput-manager.h
   trunk/lib/engine/audiooutput/
   trunk/lib/engine/audiooutput/Makefile.am
   trunk/lib/engine/audiooutput/null/
   trunk/lib/engine/audiooutput/null/Makefile.am
   trunk/lib/engine/audiooutput/null/audiooutput-main-null.cpp
   trunk/lib/engine/audiooutput/null/audiooutput-main-null.h
   trunk/lib/engine/audiooutput/null/audiooutput-manager-null.cpp
   trunk/lib/engine/audiooutput/null/audiooutput-manager-null.h
   trunk/lib/engine/audiooutput/ptlib/
   trunk/lib/engine/audiooutput/ptlib/Makefile.am
   trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.cpp
   trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.h
   trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.cpp
   trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.h
   trunk/lib/engine/audiooutput/skel/
   trunk/lib/engine/audiooutput/skel/Makefile.am
   trunk/lib/engine/audiooutput/skel/audiooutput-core.cpp
   trunk/lib/engine/audiooutput/skel/audiooutput-core.h
   trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.cpp
   trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.h
   trunk/lib/engine/audiooutput/skel/audiooutput-info.h
   trunk/lib/engine/audiooutput/skel/audiooutput-manager.h
   trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.cpp
   trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.h
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/lib/engine/Makefile.am
   trunk/lib/engine/engine.cpp
   trunk/src/Makefile.am

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Sun Mar 30 19:46:13 2008
@@ -662,7 +662,8 @@
 AC_SUBST(gnomedatadir)
 AC_SUBST(gnomeconfdir)
 
- 
+AC_DEFINE_UNQUOTED(DATA_DIR, "${ac_default_prefix}/${DATADIRNAME}",[fix])
+
 dnl ###########################################################################
 dnl  Output the different Makefiles
 dnl ###########################################################################
@@ -705,6 +706,14 @@
 lib/engine/vidinput/skel/Makefile
 lib/engine/vidinput/mlogo/Makefile
 lib/engine/vidinput/ptlib/Makefile
+lib/engine/audioinput/Makefile
+lib/engine/audioinput/skel/Makefile
+lib/engine/audioinput/null/Makefile
+lib/engine/audioinput/ptlib/Makefile
+lib/engine/audiooutput/Makefile
+lib/engine/audiooutput/skel/Makefile
+lib/engine/audiooutput/null/Makefile
+lib/engine/audiooutput/ptlib/Makefile
 lib/engine/hal/Makefile
 lib/engine/hal/skel/Makefile
 lib/engine/hal/dbus/Makefile

Modified: trunk/lib/engine/Makefile.am
==============================================================================
--- trunk/lib/engine/Makefile.am	(original)
+++ trunk/lib/engine/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -1,4 +1,4 @@
-SUBDIRS = framework addressbook presence gui protocol display vidinput hal components
+SUBDIRS = framework addressbook presence gui protocol display vidinput audioinput audiooutput hal components
 
 noinst_LTLIBRARIES = libekiga_engine.la
 
@@ -18,6 +18,8 @@
 	-I$(top_srcdir)/lib/engine/presence/local-roster		\
 	-I$(top_srcdir)/lib/engine/display/skel				\
 	-I$(top_srcdir)/lib/engine/vidinput/skel			\
+	-I$(top_srcdir)/lib/engine/audioinput/skel			\
+	-I$(top_srcdir)/lib/engine/audiooutput/skel			\
 	-I$(top_srcdir)/lib/engine/hal/skel				\
 	-I$(top_srcdir)/lib/engine/components/gmconf-personal-details
 
@@ -37,11 +39,15 @@
 		
 # Default Input Devices
 INCLUDES +=                                             \
-	-I$(top_srcdir)/lib/engine/vidinput/mlogo
+	-I$(top_srcdir)/lib/engine/vidinput/mlogo	\
+	-I$(top_srcdir)/lib/engine/audioinput/null      \
+	-I$(top_srcdir)/lib/engine/audiooutput/null
 
 # Default PTLIB Input Devices
 INCLUDES +=                                             \
-	-I$(top_srcdir)/lib/engine/vidinput/ptlib
+	-I$(top_srcdir)/lib/engine/vidinput/ptlib       \
+	-I$(top_srcdir)/lib/engine/audioinput/ptlib     \
+	-I$(top_srcdir)/lib/engine/audiooutput/ptlib
 
 # DBus / HALd
 if HAVE_DBUS
@@ -66,17 +72,23 @@
 	$(top_builddir)/lib/engine/presence/local-roster/liblocal-roster.la 				\
 	$(top_builddir)/lib/engine/display/skel/libgmdisplay.la						\
 	$(top_builddir)/lib/engine/vidinput/skel/libgmvidinput.la					\
+	$(top_builddir)/lib/engine/audioinput/skel/libgmaudioinput.la					\
+	$(top_builddir)/lib/engine/audiooutput/skel/libgmaudiooutput.la					\
 	$(top_builddir)/lib/engine/hal/skel/libgmhal.la					\
 	$(top_builddir)/lib/engine/components/gmconf-personal-details/libgmconfpersonaldetails.la	\
 	$(AM_LIBS)
 
 # Default Input Devices
 libekiga_engine_la_LIBADD += \
-	$(top_builddir)/lib/engine/vidinput/mlogo/libgmvidinput-mlogo.la
+	$(top_builddir)/lib/engine/vidinput/mlogo/libgmvidinput-mlogo.la \
+	$(top_builddir)/lib/engine/audioinput/null/libgmaudioinput-null.la \
+	$(top_builddir)/lib/engine/audiooutput/null/libgmaudiooutput-null.la
 
 # PTLIB Input Devices
 libekiga_engine_la_LIBADD += \
-	$(top_builddir)/lib/engine/vidinput/ptlib/libgmvidinput-ptlib.la
+	$(top_builddir)/lib/engine/vidinput/ptlib/libgmvidinput-ptlib.la \
+	$(top_builddir)/lib/engine/audioinput/ptlib/libgmaudioinput-ptlib.la \
+	$(top_builddir)/lib/engine/audiooutput/ptlib/libgmaudiooutput-ptlib.la
 
 # DBus/HALd
 if HAVE_DBUS

Added: trunk/lib/engine/audioinput/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1 @@
+SUBDIRS = skel null ptlib

Added: trunk/lib/engine/audioinput/null/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/null/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,22 @@
+noinst_LTLIBRARIES = libgmaudioinput-null.la
+
+audioinput_dir = $(top_srcdir)/lib/engine/audioinput/null
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/audioinput/skel \
+	-I$(top_srcdir)/lib/engine/audioinput/null \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+libgmaudioinput_null_la_SOURCES = \
+	$(audioinput_dir)/audioinput-manager-null.h \
+	$(audioinput_dir)/audioinput-manager-null.cpp \
+	$(audioinput_dir)/audioinput-main-null.h \
+	$(audioinput_dir)/audioinput-main-null.cpp 
+
+libgmaudioinput_null_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audioinput/null/audioinput-main-null.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/null/audioinput-main-null.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,63 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audionput-main-null.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the NULLaudioinput manager 
+ *                          into the main program
+ *
+ */
+
+#include "audioinput-main-null.h"
+#include "audioinput-core.h"
+#include "audioinput-manager-null.h"
+
+bool
+audioinput_null_init (Ekiga::ServiceCore &core,
+	    int */*argc*/,
+	    char **/*argv*/[])
+{
+  bool result = false;
+  Ekiga::AudioInputCore *audioinput_core = NULL;
+
+  audioinput_core
+    = dynamic_cast<Ekiga::AudioInputCore*>(core.get ("audioinput-core"));
+
+  if (audioinput_core != NULL) {
+
+    GMAudioInputManager_null *audioinput_manager = new GMAudioInputManager_null(core);
+
+    audioinput_core->add_manager (*audioinput_manager);
+    result = true;
+  }
+
+  return result;
+}

Added: trunk/lib/engine/audioinput/null/audioinput-main-null.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/null/audioinput-main-null.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,48 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-main-ptlib.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the NULL audioinput manager 
+ *                          into the main program
+ *
+ */
+
+#ifndef __AUDIOINPUT_MAIN_NULL_H__
+#define __AUDIOINPUT_MAIN_NULL_H__
+
+#include "services.h"
+
+bool audioinput_null_init (Ekiga::ServiceCore &core,
+  	   	            int *argc,
+		            char **argv[]);
+
+#endif

Added: trunk/lib/engine/audioinput/null/audioinput-manager-null.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/null/audioinput-manager-null.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,120 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-null.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+#include "audioinput-manager-null.h"
+
+#define DEVICE_TYPE "NULL"
+#define DEVICE_SOURCE "NULL"
+#define DEVICE_DEVICE "NULL"
+
+GMAudioInputManager_null::GMAudioInputManager_null (Ekiga::ServiceCore & _core)
+:    core (_core), runtime (*(dynamic_cast<Ekiga::Runtime *> (_core.get ("runtime"))))
+{
+  current_state.opened = false;
+}
+
+void GMAudioInputManager_null::get_audioinput_devices(std::vector <Ekiga::AudioInputDevice> & audioinput_devices)
+{
+  Ekiga::AudioInputDevice audioinput_device;
+  audioinput_device.type   = DEVICE_TYPE;
+  audioinput_device.source = DEVICE_SOURCE;
+  audioinput_device.device = DEVICE_DEVICE;
+  audioinput_devices.push_back(audioinput_device);
+}
+
+bool GMAudioInputManager_null::set_audioinput_device (const Ekiga::AudioInputDevice & audioinput_device)
+{
+  if ( ( audioinput_device.type   == DEVICE_TYPE ) &&
+       ( audioinput_device.source == DEVICE_SOURCE) &&
+       ( audioinput_device.device == DEVICE_DEVICE) ) {
+
+    PTRACE(4, "GMAudioInputManager_null\tSetting null device");
+    current_state.audioinput_device = audioinput_device;
+    return true;
+  }
+  return false;
+}
+
+bool GMAudioInputManager_null::open (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  Ekiga::AudioInputConfig audioinput_config;
+
+  PTRACE(0, "GMAudioInputManager_null\tOpening Device " << current_state.audioinput_device.source << "/" <<  current_state.audioinput_device.device);
+  PTRACE(0, "GMAudioInputManager_null\tOpening Device with " << channels << "-" << samplerate << "/" << bits_per_sample);
+
+  current_state.channels        = channels;
+  current_state.samplerate      = samplerate;
+  current_state.bits_per_sample = bits_per_sample;
+  current_state.opened = true;
+
+  m_Pacing.Restart();
+
+  audioinput_config.volume = 0;
+  audioinput_config.modifyable = false;
+
+  runtime.run_in_main (sigc::bind (audioinputdevice_opened.make_slot (), current_state.audioinput_device, audioinput_config));
+
+  return true;
+}
+
+void GMAudioInputManager_null::close()
+{
+  current_state.opened = false;
+  runtime.run_in_main (sigc::bind (audioinputdevice_closed.make_slot (), current_state.audioinput_device));
+}
+
+
+bool GMAudioInputManager_null::get_frame_data (char *data, 
+                                                unsigned size, unsigned & bytes_read)
+{
+  if (!current_state.opened) {
+    PTRACE(1, "GMAudioInputManager_null\tTrying to get frame from closed device");
+    return true;
+  }
+
+  memset (data, 0, size);
+
+  bytes_read = size;
+
+  m_Pacing.Delay(size * 8 / current_state.bits_per_sample * 1000 / current_state.samplerate);
+  
+  return true;
+}
+
+bool GMAudioInputManager_null::has_device(const std::string & /*source*/, const std::string & /*device*/, Ekiga::AudioInputDevice & /*audioinput_device*/)
+{
+  return false;
+}

Added: trunk/lib/engine/audioinput/null/audioinput-manager-null.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/null/audioinput-manager-null.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,100 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-null.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+
+#ifndef __AUDIOINPUT_MANAGER_NULL_H__
+#define __AUDIOINPUT_MANAGER_NULL_H__
+
+#include "audioinput-info.h"
+#include "audioinput-manager.h"
+#include "runtime.h"
+
+#include "ptbuildopts.h"
+#include <ptclib/delaychan.h>
+
+/**
+ * @addtogroup audioinput
+ * @{
+ */
+
+  class GMAudioInputManager_null
+   : public Ekiga::AudioInputManager
+    {
+  public:
+
+      /* The constructor
+       */
+      GMAudioInputManager_null (Ekiga::ServiceCore & core);
+      /* The destructor
+       */
+      ~GMAudioInputManager_null () {}
+
+
+      /*                 
+       * DISPLAY MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+      virtual bool set_audioinput_device (const Ekiga::AudioInputDevice & audioinput_device);
+		    
+      virtual void get_audioinput_devices(std::vector <Ekiga::AudioInputDevice> & audioinput_devices);
+
+      virtual bool open (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      virtual void close();
+
+      virtual bool get_frame_data (char *data, 
+                                   unsigned size,
+                                   unsigned & bytes_read);
+
+
+      virtual bool has_device     (const std::string & source, const std::string & device, Ekiga::AudioInputDevice & audioinput_device);
+      
+  protected:
+      Ekiga::ServiceCore & core;
+      Ekiga::Runtime & runtime;
+
+      PAdaptiveDelay m_Pacing;
+  };
+/**
+ * @}
+ */
+
+
+#endif

Added: trunk/lib/engine/audioinput/ptlib/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/ptlib/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,22 @@
+noinst_LTLIBRARIES = libgmaudioinput-ptlib.la
+
+audioinput_dir = $(top_srcdir)/lib/engine/audioinput/ptlib
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/audioinput/skel \
+	-I$(top_srcdir)/lib/engine/audioinput/ptlib \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+libgmaudioinput_ptlib_la_SOURCES = \
+	$(audioinput_dir)/audioinput-manager-ptlib.h \
+	$(audioinput_dir)/audioinput-manager-ptlib.cpp \
+	$(audioinput_dir)/audioinput-main-ptlib.h \
+	$(audioinput_dir)/audioinput-main-ptlib.cpp 
+
+libgmaudioinput_ptlib_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,63 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audionput-main-ptlib.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the PTLIB audioinput manager 
+ *                          into the main program
+ *
+ */
+
+#include "audioinput-main-ptlib.h"
+#include "audioinput-core.h"
+#include "audioinput-manager-ptlib.h"
+
+bool
+audioinput_ptlib_init (Ekiga::ServiceCore &core,
+	    int */*argc*/,
+	    char **/*argv*/[])
+{
+  bool result = false;
+  Ekiga::AudioInputCore *audioinput_core = NULL;
+
+  audioinput_core
+    = dynamic_cast<Ekiga::AudioInputCore*>(core.get ("audioinput-core"));
+
+  if (audioinput_core != NULL) {
+
+    GMAudioInputManager_ptlib *audioinput_manager = new GMAudioInputManager_ptlib(core);
+
+    audioinput_core->add_manager (*audioinput_manager);
+    result = true;
+  }
+
+  return result;
+}

Added: trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/ptlib/audioinput-main-ptlib.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,48 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-main-ptlib.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the PTLIB audioinput manager 
+ *                          into the main program
+ *
+ */
+
+#ifndef __AUDIOINPUT_MAIN_PTLIB_H__
+#define __AUDIOINPUT_MAIN_PTLIB_H__
+
+#include "services.h"
+
+bool audioinput_ptlib_init (Ekiga::ServiceCore &core,
+  	   	            int *argc,
+		            char **argv[]);
+
+#endif

Added: trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,201 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-ptlib.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+#include "audioinput-manager-ptlib.h"
+#include "ptbuildopts.h"
+#include "ptlib.h"
+
+#define DEVICE_TYPE "PTLIB"
+
+GMAudioInputManager_ptlib::GMAudioInputManager_ptlib (Ekiga::ServiceCore & _core)
+:    core (_core), runtime (*(dynamic_cast<Ekiga::Runtime *> (_core.get ("runtime"))))
+{
+  current_state.opened = false;
+  input_device = NULL;
+  expectedFrameSize = 0;
+}
+
+void GMAudioInputManager_ptlib::get_audioinput_devices(std::vector <Ekiga::AudioInputDevice> & audioinput_devices)
+{
+  PStringArray audio_sources;
+  PStringArray audio_devices;
+  char **sources_array;
+  char **devices_array;
+
+  Ekiga::AudioInputDevice audioinput_device;
+  audioinput_device.type   = DEVICE_TYPE;
+
+  audio_sources = PSoundChannel::GetDriverNames ();
+  sources_array = audio_sources.ToCharArray ();
+  for (PINDEX i = 0; sources_array[i] != NULL; i++) {
+
+    audioinput_device.source = sources_array[i];
+
+    if (audioinput_device.source != "EKIGA") {
+      audio_devices = PSoundChannel::GetDeviceNames (audioinput_device.source, PSoundChannel::Recorder);
+      devices_array = audio_devices.ToCharArray ();
+
+      for (PINDEX j = 0; devices_array[j] != NULL; j++) {
+
+        audioinput_device.device = devices_array[j];
+        audioinput_devices.push_back(audioinput_device);
+      }
+      free (devices_array);
+    }
+  }
+  free (sources_array);
+}
+
+bool GMAudioInputManager_ptlib::set_audioinput_device (const Ekiga::AudioInputDevice & audioinput_device)
+{
+  if ( audioinput_device.type == DEVICE_TYPE ) {
+
+    PTRACE(0, "GMAudioInputManager_ptlib\tSetting Device " << audioinput_device.source << "/" <<  audioinput_device.device);
+    current_state.audioinput_device = audioinput_device;  
+    return true;
+  }
+
+  return false;
+}
+
+bool GMAudioInputManager_ptlib::open (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  unsigned volume;
+  Ekiga::AudioInputConfig audioinput_config;
+
+  PTRACE(0, "GMAudioInputManager_ptlib\tOpening Device " << current_state.audioinput_device.source << "/" <<  current_state.audioinput_device.device);
+  PTRACE(0, "GMAudioInputManager_ptlib\tOpening Device with " << channels << "-" << samplerate << "/" << bits_per_sample);
+
+  current_state.channels        = channels;
+  current_state.samplerate      = samplerate;
+  current_state.bits_per_sample = bits_per_sample;
+
+  input_device = PSoundChannel::CreateOpenedChannel (current_state.audioinput_device.source, 
+                                                     current_state.audioinput_device.device,
+                                                     PSoundChannel::Recorder,
+                                                     channels,
+                                                     samplerate,
+                                                     bits_per_sample);
+ 
+  Ekiga::AudioInputErrorCodes error_code = Ekiga::AUDIO_ERR_NONE;
+  if (!input_device)
+    error_code = Ekiga::AUDIO_ERR_DEVICE;
+
+  if (error_code != Ekiga::AUDIO_ERR_NONE) {
+    PTRACE(1, "GMAudioInputManager_ptlib\tEncountered error " << error_code << " while opening device ");
+    runtime.run_in_main (sigc::bind (audioinputdevice_error.make_slot (), current_state.audioinput_device, error_code));
+    return false;
+  }
+
+  input_device->GetVolume (volume);
+  current_state.opened = true;
+
+  audioinput_config.volume = volume;
+  audioinput_config.modifyable = true;
+
+  runtime.run_in_main (sigc::bind (audioinputdevice_opened.make_slot (), current_state.audioinput_device, audioinput_config));
+
+  return true;
+}
+
+void GMAudioInputManager_ptlib::close()
+{
+  PTRACE(0, "GMAudioInputManager_ptlib\tClosing device " << current_state.audioinput_device.source << "/" <<  current_state.audioinput_device.device);
+  if (input_device) {
+     delete input_device;
+     input_device = NULL;
+  }
+  current_state.opened = false;
+  runtime.run_in_main (sigc::bind (audioinputdevice_closed.make_slot (), current_state.audioinput_device));
+}
+
+void GMAudioInputManager_ptlib::set_buffer_size (unsigned buffer_size, unsigned num_buffers)
+{
+  PTRACE(0, "GMAudioInputManager_ptlib\tSetting buffer size to " << buffer_size << "/" <<  num_buffers);
+
+  if (input_device)
+    input_device->SetBuffers (buffer_size, num_buffers);
+}
+
+
+bool GMAudioInputManager_ptlib::get_frame_data (char *data, 
+                                                unsigned size,
+						unsigned & bytes_read)
+{
+  bool ret = false;
+  bytes_read = 0;
+
+  if (!current_state.opened) {
+    PTRACE(1, "GMAudioInputManager_ptlib\tTrying to get frame from closed device");
+    return false;
+  }
+
+  if (input_device) {
+    ret = input_device->Read ((void*)data, size);
+    if (ret) {
+      bytes_read = input_device->GetLastReadCount();
+    }
+    else {
+      PTRACE(1, "GMAudioInputManager_ptlib\tEncountered error while trying to read data");
+      runtime.run_in_main (sigc::bind (audioinputdevice_error.make_slot (), current_state.audioinput_device, Ekiga::AUDIO_ERR_READ));
+    }
+  }
+  return ret;
+}
+
+void GMAudioInputManager_ptlib::set_volume (unsigned volume)
+{
+  PTRACE(0, "GMAudioInputManager_ptlib\tSetting volume to " << volume);
+  if (input_device)
+    input_device->SetVolume(volume);
+}
+
+bool GMAudioInputManager_ptlib::has_device(const std::string & source, const std::string & device, Ekiga::AudioInputDevice & audioinput_device)
+{
+  if (source == "alsa") {
+    audioinput_device.type = DEVICE_TYPE;
+    audioinput_device.source = "ALSA";
+    audioinput_device.device = device;    
+    return true;
+  }
+/*  if (source == "oss") {
+    audioinput_device.type = DEVICE_TYPE;
+    audioinput_device.source = "OSS";
+    audioinput_device.device = device;    
+    return true;
+  }*/
+  return false;
+}

Added: trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/ptlib/audioinput-manager-ptlib.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,102 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-ptlib.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+
+#ifndef __AUDIOINPUT_MANAGER_PTLIB_H__
+#define __AUDIOINPUT_MANAGER_PTLIB_H__
+
+#include "audioinput-manager.h"
+#include "runtime.h"
+
+#include "ptbuildopts.h"
+#include <ptlib/sound.h>
+/**
+ * @addtogroup audioinput
+ * @{
+ */
+
+  class GMAudioInputManager_ptlib
+   : public Ekiga::AudioInputManager
+    {
+  public:
+
+      /* The constructor
+       */
+      GMAudioInputManager_ptlib (Ekiga::ServiceCore & core);
+      /* The destructor
+       */
+      ~GMAudioInputManager_ptlib () {}
+
+
+      /*                 
+       * DISPLAY MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+      virtual bool set_audioinput_device (const Ekiga::AudioInputDevice & audioinput_device);
+		    
+      virtual void get_audioinput_devices(std::vector <Ekiga::AudioInputDevice> & audioinput_devices);
+
+      virtual bool open (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      virtual void close();
+
+      virtual void set_buffer_size (unsigned buffer_size, unsigned num_buffers);
+
+      virtual bool get_frame_data (char *data, 
+                                   unsigned size,
+				   unsigned & bytes_read);
+
+      virtual void set_volume     (unsigned /* volume     */ );
+
+      virtual bool has_device     (const std::string & source, const std::string & device, Ekiga::AudioInputDevice & audioinput_device);
+      
+  protected:
+      Ekiga::ServiceCore & core;
+      Ekiga::Runtime & runtime;
+      unsigned expectedFrameSize;
+
+      PSoundChannel *input_device;
+  };
+/**
+ * @}
+ */
+
+
+#endif

Added: trunk/lib/engine/audioinput/skel/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,23 @@
+noinst_LTLIBRARIES = libgmaudioinput.la
+
+audioinput_dir = $(top_srcdir)/lib/engine/audioinput/skel
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/audioinput/skel \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+libgmaudioinput_la_SOURCES = \
+	$(audioinput_dir)/audioinput-manager.h	\
+	$(audioinput_dir)/audioinput-info.h	\
+	$(audioinput_dir)/audioinput-core.h	\
+	$(audioinput_dir)/audioinput-core.cpp       \
+	$(audioinput_dir)/audioinput-gmconf-bridge.h \
+	$(audioinput_dir)/audioinput-gmconf-bridge.cpp
+
+libgmaudioinput_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audioinput/skel/audioinput-core.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-core.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,502 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-core.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          An audioinput core manages AudioInputManagers.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+
+#include "audioinput-core.h"
+#include "audioinput-manager.h"
+
+#define FALLBACK_DEVICE_TYPE "NULL"
+#define FALLBACK_DEVICE_SOURCE "NULL"
+#define FALLBACK_DEVICE_DEVICE "NULL"
+
+using namespace Ekiga;
+
+AudioPreviewManager::AudioPreviewManager (AudioInputCore& _audio_input_core, AudioOutputCore& _audio_output_core)
+: PThread (1000, NoAutoDeleteThread, HighestPriority, "PreviewManager"),
+    audio_input_core (_audio_input_core),
+  audio_output_core (_audio_output_core)
+{
+/*  frame = NULL;
+  // Since windows does not like to restart a thread that 
+  // was never started, we do so here
+  this->Resume ();
+  PWaitAndSignal m(quit_mutex);*/
+}
+
+AudioPreviewManager::~AudioPreviewManager ()
+{
+/*  if (!stop_thread)
+    stop();*/
+}
+/*
+void PreviewManager::start (unsigned width, unsigned height)
+{
+  PTRACE(0, "PreviewManager\tStarting Preview");
+  stop_thread = false;
+  frame = (char*) malloc (unsigned (width * height * 3 / 2));
+
+  display_core.start();
+  this->Restart ();
+  thread_sync_point.Wait ();
+}
+
+void PreviewManager::stop ()
+{
+  PTRACE(0, "PreviewManager\tStopping Preview");
+  stop_thread = true;
+
+  // Wait for the Main () method to be terminated 
+  PWaitAndSignal m(quit_mutex);
+
+  if (frame) {
+    free (frame);
+    frame = NULL;
+  }  
+  display_core.stop();
+}
+*/
+void AudioPreviewManager::Main ()
+{
+/*  PWaitAndSignal m(quit_mutex);
+  thread_sync_point.Signal ();
+
+  if (!frame)
+    return;
+    
+  unsigned width = 176;
+  unsigned height = 144;;
+  while (!stop_thread) {
+
+    audioinput_core.get_frame_data(width, height, frame);
+    display_core.set_frame_data(width, height, frame, true, 1);
+
+    // We have to sleep some time outside the mutex lock
+    // to give other threads time to get the mutex
+    // It will be taken into account by PAdaptiveDelay
+    Current()->Sleep (5);
+  }*/
+}
+
+AudioInputCore::AudioInputCore (Ekiga::Runtime & _runtime, AudioOutputCore& _audio_output_core)
+:  runtime (_runtime),
+   preview_manager(*this, _audio_output_core)
+
+{
+  PWaitAndSignal m_var(var_mutex);
+  PWaitAndSignal m_vol(vol_mutex);
+
+  preview_config.active = false;
+  preview_config.channels = 0;
+  preview_config.samplerate = 0;
+  preview_config.bits_per_sample = 0;
+  preview_config.volume = 0;
+  preview_config.buffer_size = 0;
+  preview_config.num_buffers = 0;
+  new_preview_volume = 0;
+
+  stream_config.active = false;
+  stream_config.channels = 0;
+  stream_config.samplerate = 0;
+  stream_config.bits_per_sample = 0;
+  stream_config.volume = 0;
+  stream_config.buffer_size = 0;
+  stream_config.num_buffers = 0;
+  new_stream_volume = 0;
+
+  current_manager = NULL;
+  audioinput_core_conf_bridge = NULL;
+  average_level = 0;
+  calculate_average = false;
+}
+
+AudioInputCore::~AudioInputCore ()
+{
+#ifdef __GNUC__
+  std::cout << __PRETTY_FUNCTION__ << std::endl;
+#endif
+
+  PWaitAndSignal m(var_mutex);
+
+  if (audioinput_core_conf_bridge)
+    delete audioinput_core_conf_bridge;
+}
+
+void AudioInputCore::setup_conf_bridge ()
+{
+  PWaitAndSignal m(var_mutex);
+
+  audioinput_core_conf_bridge = new AudioInputCoreConfBridge (*this);
+}
+
+void AudioInputCore::add_manager (AudioInputManager &manager)
+{
+  managers.insert (&manager);
+  manager_added.emit (manager);
+
+  manager.audioinputdevice_error.connect   (sigc::bind (sigc::mem_fun (this, &AudioInputCore::on_audioinputdevice_error), &manager));
+  manager.audioinputdevice_opened.connect  (sigc::bind (sigc::mem_fun (this, &AudioInputCore::on_audioinputdevice_opened), &manager));
+  manager.audioinputdevice_closed.connect  (sigc::bind (sigc::mem_fun (this, &AudioInputCore::on_audioinputdevice_closed), &manager));
+}
+
+
+void AudioInputCore::visit_managers (sigc::slot<bool, AudioInputManager &> visitor)
+{
+  PWaitAndSignal m(var_mutex);
+  bool go_on = true;
+  
+  for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
+       iter != managers.end () && go_on;
+       iter++)
+      go_on = visitor (*(*iter));
+}		      
+
+void AudioInputCore::get_audioinput_devices (std::vector <AudioInputDevice> & audioinput_devices)
+{
+  PWaitAndSignal m(var_mutex);
+
+  audioinput_devices.clear();
+  
+  for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++)
+    (*iter)->get_audioinput_devices (audioinput_devices);
+
+  if (PTrace::CanTrace(4)) {
+     for (std::vector<AudioInputDevice>::iterator iter = audioinput_devices.begin ();
+         iter != audioinput_devices.end ();
+         iter++) {
+      PTRACE(0, "AudioInputCore\tDetected Device: " << iter->type << "/" << iter->source << "/" << iter->device);
+    }
+  }
+
+}
+
+void AudioInputCore::set_audioinput_device(const AudioInputDevice & audioinput_device)
+{
+  PWaitAndSignal m(var_mutex);
+  PTRACE(0, "AudioInputCore\tSetting device: " << audioinput_device.type << "/" << audioinput_device.source << "/" << audioinput_device.device);
+
+  if (preview_config.active)
+    preview_manager.stop();
+
+  if (preview_config.active || stream_config.active)
+    internal_close();
+
+  internal_set_device (audioinput_device);
+
+  if (preview_config.active) {
+    internal_open(preview_config.channels, preview_config.samplerate, preview_config.bits_per_sample);
+
+    if ((preview_config.buffer_size > 0) && (preview_config.num_buffers > 0 ) ) {
+      if (current_manager)
+        current_manager->set_buffer_size (preview_config.buffer_size, preview_config.num_buffers);
+    }
+//    preview_manager.start();
+  }
+
+  if (stream_config.active) {
+    internal_open(stream_config.channels, stream_config.samplerate, stream_config.bits_per_sample);
+
+    if ((stream_config.buffer_size > 0) && (stream_config.num_buffers > 0 ) ) {
+      if (current_manager)
+        current_manager->set_buffer_size (stream_config.buffer_size, stream_config.num_buffers);
+    }
+  }
+
+  desired_device  = audioinput_device;
+}
+
+
+void AudioInputCore::start_preview (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  PWaitAndSignal m(var_mutex);
+
+  PTRACE(0, "AudioInputCore\tStarting preview " << channels << "x" << samplerate << "/" << bits_per_sample);
+
+  if (preview_config.active || stream_config.active) {
+    PTRACE(0, "AudioInputCore\tTrying to start preview in wrong state");
+  }
+
+  internal_open(channels, samplerate, bits_per_sample);
+
+  preview_config.active = true;
+  preview_config.channels = channels;
+  preview_config.samplerate = samplerate;
+  preview_config.bits_per_sample = bits_per_sample;
+  preview_config.buffer_size = 320; //FIXME: verify
+  preview_config.num_buffers = 5;
+
+  if (current_manager)
+    current_manager->set_buffer_size(preview_config.buffer_size, preview_config.num_buffers);
+//    preview_manager.start(preview_config.channels,preview_config.samplerate);
+
+  average_level = 0;
+}
+
+void AudioInputCore::stop_preview ()
+{
+  PWaitAndSignal m(var_mutex);
+
+  PTRACE(0, "AudioInputCore\tStopping Preview");
+
+  if (!preview_config.active || stream_config.active) {
+    PTRACE(0, "AudioInputCore\tTrying to stop preview in wrong state");
+  }
+
+//     preview_manager.stop();
+  internal_close();
+
+  preview_config.active = false;
+}
+
+
+void AudioInputCore::set_stream_buffer_size (unsigned buffer_size, unsigned num_buffers)
+{
+  PWaitAndSignal m(var_mutex);
+
+  PTRACE(0, "AudioInputCore\tSetting stream buffer size " << num_buffers << "/" << buffer_size);
+
+  if (current_manager)
+    current_manager->set_buffer_size(buffer_size, num_buffers);
+
+  stream_config.buffer_size = buffer_size;
+  stream_config.num_buffers = num_buffers;
+}
+
+void AudioInputCore::start_stream (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  PWaitAndSignal m(var_mutex);
+
+  PTRACE(0, "AudioInputCore\tStarting stream " << channels << "x" << samplerate << "/" << bits_per_sample);
+
+  if (preview_config.active || stream_config.active) {
+    PTRACE(0, "AudioInputCore\tTrying to start stream in wrong state");
+  }
+
+  internal_open(channels, samplerate, bits_per_sample);
+
+  stream_config.active = true;
+  stream_config.channels = channels;
+  stream_config.samplerate = samplerate;
+  stream_config.bits_per_sample = bits_per_sample;
+
+  average_level = 0;
+}
+
+void AudioInputCore::stop_stream ()
+{
+  PWaitAndSignal m(var_mutex);
+
+  PTRACE(0, "AudioInputCore\tStopping Stream");
+
+  if (preview_config.active || !stream_config.active) {
+    PTRACE(0, "AudioInputCore\tTrying to stop stream in wrong state");
+    return;
+  }
+
+  internal_close();
+
+  stream_config.active = false;
+  average_level = 0;
+}
+
+void AudioInputCore::get_frame_data (char *data,
+                                     unsigned size,
+				     unsigned & bytes_read)
+{
+  PWaitAndSignal m_var(var_mutex);
+
+  if (current_manager) {
+    if (!current_manager->get_frame_data(data, size, bytes_read)) {
+      internal_close();
+      internal_set_fallback();
+      internal_open(stream_config.channels, stream_config.samplerate, stream_config.bits_per_sample);
+      if (current_manager)
+        current_manager->get_frame_data(data, size, bytes_read); // the default device must always return true
+    }
+    
+    
+    PWaitAndSignal m_vol(vol_mutex);
+    if ((preview_config.active) && (new_preview_volume != preview_config.volume)) {
+      current_manager->set_volume (new_preview_volume);
+      preview_config.volume = new_preview_volume;
+    }
+
+    if ((stream_config.active) && (new_stream_volume != stream_config.volume)) {
+      current_manager->set_volume (new_stream_volume);
+      stream_config.volume = new_stream_volume;
+    }
+  }
+
+  if (calculate_average) 
+    calculate_average_level((const short*) data, bytes_read);
+}
+
+void AudioInputCore::set_volume (unsigned volume)
+{
+  PWaitAndSignal m(vol_mutex);
+
+  if (preview_config.active)
+    new_preview_volume = volume;
+
+  if (stream_config.active)
+    new_stream_volume = volume;
+}
+
+
+void AudioInputCore::on_audioinputdevice_error (AudioInputDevice audioinput_device, AudioInputErrorCodes error_code, AudioInputManager *manager)
+{
+  audioinputdevice_error.emit (*manager, audioinput_device, error_code);
+}
+
+
+void AudioInputCore::on_audioinputdevice_opened (AudioInputDevice audioinput_device,
+                                             AudioInputConfig audioinput_config, 
+                                             AudioInputManager *manager)
+{
+  audioinputdevice_opened.emit (*manager, audioinput_device, audioinput_config);
+}
+
+void AudioInputCore::on_audioinputdevice_closed (AudioInputDevice audioinput_device, AudioInputManager *manager)
+{
+  audioinputdevice_closed.emit (*manager, audioinput_device);
+}
+
+void AudioInputCore::internal_open (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  PTRACE(0, "AudioInputCore\tOpening device with " << channels << "-" << samplerate << "/" << bits_per_sample );
+
+  if (current_manager && !current_manager->open(channels, samplerate, bits_per_sample)) {
+
+    internal_set_fallback();
+
+    if (current_manager)
+      current_manager->open(channels, samplerate, bits_per_sample);
+  }
+}
+
+void AudioInputCore::internal_set_device (const AudioInputDevice & audioinput_device)
+{
+  current_manager = NULL;
+  for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->set_audioinput_device (audioinput_device)) {
+       current_manager = (*iter);
+     }
+  }
+
+  // If the desired manager could not be found,
+  // we se the default device. The default device
+  // MUST ALWAYS be loaded and openable
+  if (current_manager) {
+    current_device  = audioinput_device;
+  }
+  else {
+
+    PTRACE(1, "AudioInputCore\tTried to set unexisting device " << audioinput_device.type << "/" << audioinput_device.source << "/" << audioinput_device.device);
+    internal_set_fallback();
+  }
+}
+
+void AudioInputCore::internal_close()
+{
+  PTRACE(0, "AudioInputCore\tClosing current device");
+  if (current_manager)
+    current_manager->close();
+}
+
+void AudioInputCore::calculate_average_level (const short *buffer, unsigned size)
+{
+  int sum = 0;
+  unsigned csize = 0;
+  
+  while (csize < (size>>1) ) {
+
+    if (*buffer < 0)
+      sum -= *buffer++;
+    else
+      sum += *buffer++;
+
+    csize++;
+  }
+	  
+  average_level = log10 (9.0*sum/size/32767+1)*1.0;
+}
+
+void AudioInputCore::internal_set_fallback()
+{
+    PTRACE(1, "AudioInputCore\tFalling back to " << FALLBACK_DEVICE_TYPE << "/" << FALLBACK_DEVICE_SOURCE << "/" << FALLBACK_DEVICE_DEVICE);
+    current_device.type = FALLBACK_DEVICE_TYPE;
+    current_device.source = FALLBACK_DEVICE_SOURCE;
+    current_device.device = FALLBACK_DEVICE_DEVICE;
+    internal_set_device (current_device);
+}
+
+void AudioInputCore::add_device (std::string & source, std::string & device, HalManager* /*manager*/)
+{
+  PTRACE(0, "AudioInputCore\tAdding Device");
+  AudioInputDevice audioinput_device;
+  for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->has_device (source, device, audioinput_device)) {
+     
+       if ( ( desired_device.type   == audioinput_device.type   ) &&
+            ( desired_device.source == audioinput_device.source ) &&
+            ( desired_device.device == audioinput_device.device ) ) {
+         set_audioinput_device(desired_device);
+       }
+
+       runtime.run_in_main (sigc::bind (audioinputdevice_added.make_slot (), audioinput_device));
+     }
+  }
+}
+
+void AudioInputCore::remove_device (std::string & source, std::string & device, HalManager* /*manager*/)
+{
+  PTRACE(0, "AudioInputCore\tRemoving Device");
+  AudioInputDevice audioinput_device;
+  for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->has_device (source, device, audioinput_device)) {
+       runtime.run_in_main (sigc::bind (audioinputdevice_removed.make_slot (), audioinput_device));
+     }
+  }
+}

Added: trunk/lib/engine/audioinput/skel/audioinput-core.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-core.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,225 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+#ifndef __AUDIOINPUT_CORE_H__
+#define __AUDIOINPUT_CORE_H__
+
+#include "services.h"
+#include "runtime.h"
+#include "audiooutput-core.h"
+#include "hal-core.h"
+#include "audioinput-gmconf-bridge.h"
+#include "audioinput-info.h"
+
+#include <sigc++/sigc++.h>
+#include <glib.h>
+#include <set>
+
+#include "ptbuildopts.h"
+#include "ptlib.h"
+
+namespace Ekiga
+{
+  typedef struct AudioDeviceConfig {
+    bool active;
+    unsigned channels;
+    unsigned samplerate;
+    unsigned bits_per_sample;
+    unsigned buffer_size;
+    unsigned num_buffers;
+    unsigned volume;
+  };
+
+  class AudioInputManager;
+  class AudioInputCore;
+				      
+  class AudioPreviewManager : public PThread
+  {
+    PCLASSINFO(AudioPreviewManager, PThread);
+  
+  public:
+    AudioPreviewManager(AudioInputCore& _audio_input_core, AudioOutputCore& _audio_output_core);
+    ~AudioPreviewManager();
+    virtual void start(){};
+    virtual void stop(){};
+  
+  protected:
+    void Main (void);
+    bool stop_thread;
+    char* frame;
+    PMutex quit_mutex;     /* To exit */
+    PSyncPoint thread_sync_point;
+    AudioInputCore& audio_input_core;
+    AudioOutputCore& audio_output_core;
+  };
+
+/**
+ * @defgroup audioinput Audio AudioInput
+ * @{
+ */
+
+
+
+  /** Core object for the audio auioinput support
+   */
+  class AudioInputCore
+    : public Service
+    {
+
+  public:
+
+      /* The constructor
+      */
+      AudioInputCore (Ekiga::Runtime & _runtime, AudioOutputCore& _audio_output_core);
+
+      /* The destructor
+      */
+      ~AudioInputCore ();
+
+      void setup_conf_bridge();
+
+      /*** Service Implementation ***/
+
+      /** Returns the name of the service.
+       * @return The service name.
+       */
+      const std::string get_name () const
+        { return "audioinput-core"; }
+
+
+      /** Returns the description of the service.
+       * @return The service description.
+       */
+      const std::string get_description () const
+        { return "\tAudioInput Core managing AudioInput Manager objects"; }
+
+
+      /** Adds a AudioInputManager to the AudioInputCore service.
+       * @param The manager to be added.
+       */
+       void add_manager (AudioInputManager &manager);
+
+      /** Triggers a callback for all Ekiga::AudioInputManager sources of the
+       * AudioInputCore service.
+       */
+       void visit_managers (sigc::slot<bool, AudioInputManager &> visitor);
+
+      /** This signal is emitted when a Ekiga::AudioInputManager has been
+       * added to the AudioInputCore Service.
+       */
+       sigc::signal<void, AudioInputManager &> manager_added;
+
+
+      void get_audioinput_devices(std::vector <AudioInputDevice> & audioinput_devices);
+
+      void set_audioinput_device(const AudioInputDevice & audioinput_device);
+      
+      /*** VidInput Management ***/                 
+
+      void start_preview (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      void stop_preview ();
+
+      void set_stream_buffer_size (unsigned buffer_size, unsigned num_buffers);
+
+      void start_stream (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      void stop_stream ();
+
+      void get_frame_data (char *data, unsigned size, unsigned & bytes_read);
+
+      void set_volume (unsigned volume);
+
+      void start_average_collection () { calculate_average = true; }
+
+      void stop_average_collection () { calculate_average = false; }
+
+      float get_average_level () { return average_level; }
+
+      void add_device (std::string & source, std::string & device, HalManager* manager);
+      void remove_device (std::string & source, std::string & device, HalManager* manager);
+
+      /*** VidInput Related Signals ***/
+      
+      /** See audioinput-manager.h for the API
+       */
+      sigc::signal<void, AudioInputManager &, AudioInputDevice &, AudioInputErrorCodes> audioinputdevice_error;
+      sigc::signal<void, AudioInputDevice> audioinputdevice_added;
+      sigc::signal<void, AudioInputDevice> audioinputdevice_removed;
+      sigc::signal<void, AudioInputManager &, AudioInputDevice &, AudioInputConfig&> audioinputdevice_opened;
+      sigc::signal<void, AudioInputManager &, AudioInputDevice &> audioinputdevice_closed;
+
+  private:
+      void on_audioinputdevice_error (AudioInputDevice audioinput_device, AudioInputErrorCodes error_code, AudioInputManager *manager);
+      void on_audioinputdevice_opened (AudioInputDevice audioinput_device,  
+                                       AudioInputConfig vidinput_config, 
+                                       AudioInputManager *manager);
+      void on_audioinputdevice_closed (AudioInputDevice audioinput_device, AudioInputManager *manager);
+
+      void internal_open (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+      void internal_close();
+      void internal_set_device (const AudioInputDevice & audioinput_device);
+      void internal_set_fallback();
+      void calculate_average_level (const short *buffer, unsigned size);
+
+      Ekiga::Runtime & runtime;
+	    
+      std::set<AudioInputManager *> managers;
+
+      AudioDeviceConfig preview_config;
+      AudioDeviceConfig stream_config;
+      unsigned new_preview_volume;
+      unsigned new_stream_volume;
+
+      AudioInputManager* current_manager;
+      AudioInputDevice desired_device;
+      AudioInputDevice current_device;
+
+      PMutex var_mutex;      /* To protect variables that are read and written */
+      PMutex vol_mutex;      /* To protect variables that are read and written */
+
+      AudioPreviewManager preview_manager;
+      AudioInputCoreConfBridge* audioinput_core_conf_bridge;
+
+      float average_level;
+      bool calculate_average;
+    };
+/**
+ * @}
+ */
+};
+
+#endif

Added: trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,77 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-core.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+#include "config.h"
+
+#include "audioinput-gmconf-bridge.h"
+#include "audioinput-core.h"
+
+#define AUDIO_DEVICES_KEY "/apps/" PACKAGE_NAME "/devices/audio/"
+#define AUDIO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/audio/"
+
+using namespace Ekiga;
+
+AudioInputCoreConfBridge::AudioInputCoreConfBridge (Ekiga::Service & _service)
+ : Ekiga::ConfBridge (_service)
+{
+  Ekiga::ConfKeys keys;
+  property_changed.connect (sigc::mem_fun (this, &AudioInputCoreConfBridge::on_property_changed));
+
+  keys.push_back (AUDIO_DEVICES_KEY "input_device"); 
+  keys.push_back (AUDIO_DEVICES_KEY "plugin"); 
+  load (keys);
+}
+
+void AudioInputCoreConfBridge::on_property_changed (std::string key, GmConfEntry *entry)
+{
+  AudioInputCore & audioinput_core = (AudioInputCore &) service;
+
+  if (key == AUDIO_DEVICES_KEY "input_device") {
+
+    PTRACE(4, "AudioInputCoreConfBridge\tUpdating device");
+    std::string config_string = gm_conf_entry_get_string (entry);
+    AudioInputDevice audioinput_device;
+
+    unsigned type_sep = config_string.find_first_of("/");
+    unsigned source_sep = config_string.find_first_of("/", type_sep + 1);
+
+    audioinput_device.type   = config_string.substr ( 0, type_sep );
+    audioinput_device.source = config_string.substr ( type_sep + 1, source_sep - type_sep - 1);
+    audioinput_device.device = config_string.substr ( source_sep + 1, config_string.size() - source_sep );
+    audioinput_core.set_audioinput_device (audioinput_device);
+  }
+}
+

Added: trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-gmconf-bridge.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,57 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+#ifndef __AUDIOINPUT_GMCONF_BRIDGE_H__
+#define __AUDIOINPUT_GMCONF_BRIDGE_H__
+
+#include "services.h"
+#include "gmconf-bridge.h"
+
+namespace Ekiga
+{
+  class AudioInputCoreConfBridge
+    : public Ekiga::ConfBridge
+  {
+  public:
+
+    AudioInputCoreConfBridge (Ekiga::Service & service);
+
+    void on_property_changed (std::string key, GmConfEntry *value);
+  };
+
+};
+
+#endif

Added: trunk/lib/engine/audioinput/skel/audioinput-info.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-info.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,61 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                          audioinput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a vidinput core.
+ *                          A vidinput core manages VidInputManagers.
+ *
+ */
+
+#ifndef __AUDIOINPUT_INFO_H__
+#define __AUDIOINPUT_INFO_H__
+#include <string>
+namespace Ekiga
+{
+  typedef struct AudioInputDevice {
+    std::string type;
+    std::string source;
+    std::string device;
+  };
+
+  typedef struct AudioInputConfig {
+    unsigned volume;
+    bool modifyable;
+  };
+
+  enum AudioInputErrorCodes {
+    AUDIO_ERR_NONE = 0,
+    AUDIO_ERR_DEVICE, 
+    AUDIO_ERR_READ
+  };
+				      
+};
+
+#endif

Added: trunk/lib/engine/audioinput/skel/audioinput-manager.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audioinput/skel/audioinput-manager.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,114 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of an audioinput manager
+ *                          implementation backend.
+ *
+ */
+
+
+#ifndef __AUDIOINPUT_MANAGER_H__
+#define __AUDIOINPUT_MANAGER_H__
+
+#include "audioinput-core.h"
+
+namespace Ekiga
+{
+
+/**
+ * @addtogroup vidinput
+ * @{
+ */
+
+  typedef struct ManagerState {
+    bool opened;
+    unsigned channels;
+    unsigned samplerate;
+    unsigned bits_per_sample;
+    AudioInputDevice audioinput_device;
+  };
+  
+
+  class AudioInputManager
+    {
+
+  public:
+
+      /* The constructor
+       */
+      AudioInputManager () {}
+
+      /* The destructor
+       */
+      ~AudioInputManager () {}
+
+
+      /*                 
+       * AUDIOINPUT MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+
+      virtual void get_audioinput_devices (std::vector <AudioInputDevice> & audioinput_devices) = 0;
+
+      virtual bool set_audioinput_device (const AudioInputDevice & audioinput_device) = 0;
+
+      virtual bool open (unsigned channels, unsigned samplerate, unsigned bits_per_sample) = 0;
+
+      virtual void set_buffer_size (unsigned /*buffer_size*/, unsigned /*num_buffers*/) {};
+
+      virtual bool get_frame_data (char *data, 
+                                   unsigned size,
+				   unsigned & bytes_read) = 0;
+
+      virtual void close() {};
+
+      virtual void set_volume     (unsigned /* volume     */ ) {};
+
+      virtual bool has_device     (const std::string & source, const std::string & device, AudioInputDevice & audioinput_device) = 0;
+
+      sigc::signal<void, AudioInputDevice, AudioInputErrorCodes> audioinputdevice_error;
+      sigc::signal<void, AudioInputDevice, AudioInputConfig> audioinputdevice_opened;
+      sigc::signal<void, AudioInputDevice> audioinputdevice_closed;
+
+  protected:  
+      ManagerState current_state;
+  };
+/**
+ * @}
+ */
+
+};
+
+#endif

Added: trunk/lib/engine/audiooutput/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1 @@
+SUBDIRS = skel null ptlib

Added: trunk/lib/engine/audiooutput/null/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/null/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,21 @@
+noinst_LTLIBRARIES = libgmaudiooutput-null.la
+
+audiooutput_dir = $(top_srcdir)/lib/engine/audiooutput/null
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/audiooutput/null \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+libgmaudiooutput_null_la_SOURCES = \
+	$(audiooutput_dir)/audiooutput-manager-null.h \
+	$(audiooutput_dir)/audiooutput-manager-null.cpp \
+	$(audiooutput_dir)/audiooutput-main-null.h \
+	$(audiooutput_dir)/audiooutput-main-null.cpp 
+
+libgmaudiooutput_null_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audiooutput/null/audiooutput-main-null.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/null/audiooutput-main-null.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,63 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audionput-main-null.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the PTLIB audiooutput manager 
+ *                          into the main program
+ *
+ */
+
+#include "audiooutput-main-null.h"
+#include "audiooutput-core.h"
+#include "audiooutput-manager-null.h"
+
+bool
+audiooutput_null_init (Ekiga::ServiceCore &core,
+	    int */*argc*/,
+	    char **/*argv*/[])
+{
+  bool result = false;
+  Ekiga::AudioOutputCore *audiooutput_core = NULL;
+
+  audiooutput_core
+    = dynamic_cast<Ekiga::AudioOutputCore*>(core.get ("audiooutput-core"));
+
+  if (audiooutput_core != NULL) {
+
+    GMAudioOutputManager_null *audiooutput_manager = new GMAudioOutputManager_null(core);
+
+    audiooutput_core->add_manager (*audiooutput_manager);
+    result = true;
+  }
+
+  return result;
+}

Added: trunk/lib/engine/audiooutput/null/audiooutput-main-null.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/null/audiooutput-main-null.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,48 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-main-null.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the NULL audiooutput manager 
+ *                          into the main program
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_MAIN_NULL_H__
+#define __AUDIOOUTPUT_MAIN_NULL_H__
+
+#include "services.h"
+
+bool audiooutput_null_init (Ekiga::ServiceCore &core,
+  	   	            int *argc,
+		            char **argv[]);
+
+#endif

Added: trunk/lib/engine/audiooutput/null/audiooutput-manager-null.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/null/audiooutput-manager-null.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,121 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-manager-null.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audiooutput core.
+ *                          A audiooutput core manages AudioOutputManagers.
+ *
+ */
+
+#include "audiooutput-manager-null.h"
+
+#define DEVICE_TYPE   "NULL"
+#define DEVICE_SOURCE "NULL"
+#define DEVICE_DEVICE "NULL"
+
+GMAudioOutputManager_null::GMAudioOutputManager_null (Ekiga::ServiceCore & _core)
+:    core (_core), runtime (*(dynamic_cast<Ekiga::Runtime *> (_core.get ("runtime"))))
+{
+  current_state[Ekiga::primary].opened = false;
+  current_state[Ekiga::secondary].opened = false;
+}
+
+void GMAudioOutputManager_null::get_audiooutput_devices(std::vector <Ekiga::AudioOutputDevice> & audiooutput_devices)
+{
+  Ekiga::AudioOutputDevice audiooutput_device;
+  audiooutput_device.type   = DEVICE_TYPE;
+  audiooutput_device.source = DEVICE_SOURCE;
+  audiooutput_device.device = DEVICE_DEVICE;
+  audiooutput_devices.push_back(audiooutput_device);
+}
+
+
+bool GMAudioOutputManager_null::set_audiooutput_device (Ekiga::AudioOutputPrimarySecondary primarySecondary, const Ekiga::AudioOutputDevice & audiooutput_device)
+{
+  if ( ( audiooutput_device.type   == DEVICE_TYPE ) &&
+       ( audiooutput_device.source == DEVICE_SOURCE) &&
+       ( audiooutput_device.device == DEVICE_DEVICE) ) {
+
+    PTRACE(4, "GMAudioOutputManager_null\tSetting null device");
+    current_state[primarySecondary].audiooutput_device = audiooutput_device;
+    return true;
+  }
+  return false;
+}
+
+bool GMAudioOutputManager_null::open (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  Ekiga::AudioOutputConfig audiooutput_config;
+
+  PTRACE(0, "GMAudioOutputManager_null\tOpening Device[" << primarySecondary << "] " << current_state[primarySecondary].audiooutput_device.source << "/" <<  current_state[primarySecondary].audiooutput_device.device);
+  PTRACE(0, "GMAudioOutputManager_null\tOpening Device with " << channels << "-" << samplerate << "/" << bits_per_sample);
+
+  current_state[primarySecondary].channels        = channels;
+  current_state[primarySecondary].samplerate      = samplerate;
+  current_state[primarySecondary].bits_per_sample = bits_per_sample;
+  current_state[primarySecondary].opened = true;
+
+  m_Pacing[primarySecondary].Restart();
+
+  audiooutput_config.volume = 0;
+  audiooutput_config.modifyable = false;
+
+  runtime.run_in_main (sigc::bind (audiooutputdevice_opened.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device, audiooutput_config));
+
+  return true;
+}
+
+void GMAudioOutputManager_null::close(Ekiga::AudioOutputPrimarySecondary primarySecondary)
+{
+  current_state[primarySecondary].opened = false;
+  runtime.run_in_main (sigc::bind (audiooutputdevice_closed.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device));
+}
+
+
+bool GMAudioOutputManager_null::set_frame_data (Ekiga::AudioOutputPrimarySecondary primarySecondary, 
+                     char */*data*/, 
+                     unsigned size,
+		     unsigned & written)
+{
+  if (!current_state[primarySecondary].opened) {
+    PTRACE(1, "GMAudioOutputManager_null\tTrying to get frame from closed device[" << primarySecondary << "]");
+    return true;
+  }
+
+  written = size;
+
+  m_Pacing[primarySecondary].Delay(size * 8 / current_state[primarySecondary].bits_per_sample * 1000 / current_state[primarySecondary].samplerate);
+  return true;
+}
+
+bool GMAudioOutputManager_null::has_device(const std::string & /*sink*/, const std::string & /*device*/, Ekiga::AudioOutputDevice & /*audiooutput_device*/)
+{
+  return false;
+}

Added: trunk/lib/engine/audiooutput/null/audiooutput-manager-null.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/null/audiooutput-manager-null.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,100 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-null.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+
+#ifndef __AUDIOOUTPUT_MANAGER_NULL_H__
+#define __AUDIOOUTPUT_MANAGER_NULL_H__
+
+#include "audiooutput-manager.h"
+#include "runtime.h"
+
+#include "ptbuildopts.h"
+#include <ptclib/delaychan.h>
+
+/**
+ * @addtogroup audioinput
+ * @{
+ */
+
+  class GMAudioOutputManager_null
+   : public Ekiga::AudioOutputManager
+    {
+  public:
+
+      /* The constructor
+       */
+       GMAudioOutputManager_null (Ekiga::ServiceCore & core);
+      /* The destructor
+       */
+      ~GMAudioOutputManager_null () {}
+
+
+      /*                 
+       * DISPLAY MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+
+      virtual void get_audiooutput_devices (std::vector <Ekiga::AudioOutputDevice> & audiooutput_devices);
+
+      virtual bool set_audiooutput_device (Ekiga::AudioOutputPrimarySecondary primarySecondary, const Ekiga::AudioOutputDevice & audiooutput_device);
+
+      virtual bool open (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      virtual void close(Ekiga::AudioOutputPrimarySecondary primarySecondary);
+
+      virtual bool set_frame_data (Ekiga::AudioOutputPrimarySecondary primarySecondary, 
+                                   char *data, 
+                                   unsigned size,
+				   unsigned & written);
+      virtual bool has_device     (const std::string & sink, const std::string & device, Ekiga::AudioOutputDevice & audiooutput_device);
+
+    protected:
+      Ekiga::ServiceCore & core;
+      Ekiga::Runtime & runtime;
+
+      PAdaptiveDelay m_Pacing[2];
+
+  };
+/**
+ * @}
+ */
+
+
+#endif

Added: trunk/lib/engine/audiooutput/ptlib/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/ptlib/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,21 @@
+noinst_LTLIBRARIES = libgmaudiooutput-ptlib.la
+
+audiooutput_dir = $(top_srcdir)/lib/engine/audiooutput/ptlib
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/audiooutput/ptlib \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+libgmaudiooutput_ptlib_la_SOURCES = \
+	$(audiooutput_dir)/audiooutput-manager-ptlib.h \
+	$(audiooutput_dir)/audiooutput-manager-ptlib.cpp \
+	$(audiooutput_dir)/audiooutput-main-ptlib.h \
+	$(audiooutput_dir)/audiooutput-main-ptlib.cpp 
+
+libgmaudiooutput_ptlib_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,63 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audionput-main-ptlib.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the PTLIB audiooutput manager 
+ *                          into the main program
+ *
+ */
+
+#include "audiooutput-main-ptlib.h"
+#include "audiooutput-core.h"
+#include "audiooutput-manager-ptlib.h"
+
+bool
+audiooutput_ptlib_init (Ekiga::ServiceCore &core,
+	    int */*argc*/,
+	    char **/*argv*/[])
+{
+  bool result = false;
+  Ekiga::AudioOutputCore *audiooutput_core = NULL;
+
+  audiooutput_core
+    = dynamic_cast<Ekiga::AudioOutputCore*>(core.get ("audiooutput-core"));
+
+  if (audiooutput_core != NULL) {
+
+    GMAudioOutputManager_ptlib *audiooutput_manager = new GMAudioOutputManager_ptlib(core);
+
+    audiooutput_core->add_manager (*audiooutput_manager);
+    result = true;
+  }
+
+  return result;
+}

Added: trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/ptlib/audiooutput-main-ptlib.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,48 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-main-ptlib.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : code to hook the PTLIB audiooutput manager 
+ *                          into the main program
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_MAIN_PTLIB_H__
+#define __AUDIOOUTPUT_MAIN_PTLIB_H__
+
+#include "services.h"
+
+bool audiooutput_ptlib_init (Ekiga::ServiceCore &core,
+  	   	            int *argc,
+		            char **argv[]);
+
+#endif

Added: trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,204 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-manager-ptlib.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audiooutput core.
+ *                          A audioinput core manages AudioOutputManagers.
+ *
+ */
+
+#include "audiooutput-manager-ptlib.h"
+#include "ptbuildopts.h"
+#include "ptlib.h"
+
+#define DEVICE_TYPE "PTLIB"
+
+GMAudioOutputManager_ptlib::GMAudioOutputManager_ptlib (Ekiga::ServiceCore & _core)
+:    core (_core), runtime (*(dynamic_cast<Ekiga::Runtime *> (_core.get ("runtime"))))
+{
+  current_state[Ekiga::primary].opened = false;
+  current_state[Ekiga::secondary].opened = false;
+  output_device[Ekiga::primary] = NULL;
+  output_device[Ekiga::secondary] = NULL;
+}
+
+void GMAudioOutputManager_ptlib::get_audiooutput_devices(std::vector <Ekiga::AudioOutputDevice> & audiooutput_devices)
+{
+  PStringArray audio_sources;
+  PStringArray audio_devices;
+  char **sources_array;
+  char **devices_array;
+
+  Ekiga::AudioOutputDevice audiooutput_device;
+  audiooutput_device.type   = DEVICE_TYPE;
+
+  audio_sources = PSoundChannel::GetDriverNames ();
+  sources_array = audio_sources.ToCharArray ();
+  for (PINDEX i = 0; sources_array[i] != NULL; i++) {
+
+    audiooutput_device.source = sources_array[i];
+
+    if (audiooutput_device.source != "EKIGA") {
+      audio_devices = PSoundChannel::GetDeviceNames (audiooutput_device.source, PSoundChannel::Player);
+      devices_array = audio_devices.ToCharArray ();
+
+      for (PINDEX j = 0; devices_array[j] != NULL; j++) {
+
+        audiooutput_device.device = devices_array[j];
+        audiooutput_devices.push_back(audiooutput_device);
+      }
+      free (devices_array);
+    }
+  }
+  free (sources_array);
+}
+
+bool GMAudioOutputManager_ptlib::set_audiooutput_device (Ekiga::AudioOutputPrimarySecondary primarySecondary, const Ekiga::AudioOutputDevice & audiooutput_device)
+{
+  if ( audiooutput_device.type == DEVICE_TYPE ) {
+
+    PTRACE(0, "GMAudioOutputManager_ptlib\tSetting Device[" << primarySecondary << "] " << audiooutput_device.source << "/" <<  audiooutput_device.device);
+    current_state[primarySecondary].audiooutput_device = audiooutput_device;  
+    return true;
+  }
+
+  return false;
+}
+
+bool GMAudioOutputManager_ptlib::open (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  unsigned volume;
+  Ekiga::AudioOutputConfig audiooutput_config;
+
+  PTRACE(0, "GMAudioOutputManager_ptlib\tOpening Device " << current_state[primarySecondary].audiooutput_device.source << "/" <<  current_state[primarySecondary].audiooutput_device.device);
+  PTRACE(0, "GMAudioOutputManager_ptlib\tOpening Device with " << channels << "-" << samplerate << "/" << bits_per_sample);
+
+  current_state[primarySecondary].channels        = channels;
+  current_state[primarySecondary].samplerate      = samplerate;
+  current_state[primarySecondary].bits_per_sample = bits_per_sample;
+
+  output_device[primarySecondary] = PSoundChannel::CreateOpenedChannel (current_state[primarySecondary].audiooutput_device.source, 
+                                                     current_state[primarySecondary].audiooutput_device.device,
+                                                     PSoundChannel::Player,
+                                                     channels,
+                                                     samplerate,
+                                                     bits_per_sample);
+ 
+  Ekiga::AudioOutputErrorCodes error_code = Ekiga::_AUDIO_ERR_NONE;
+  if (!output_device[primarySecondary])
+    error_code = Ekiga::_AUDIO_ERR_DEVICE;
+
+  if (error_code != Ekiga::_AUDIO_ERR_NONE) {
+    PTRACE(1, "GMAudioOutputManager_ptlib\tEncountered error " << error_code << " while opening device[" << primarySecondary << "]");
+    runtime.run_in_main (sigc::bind (audiooutputdevice_error.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device, error_code));
+    return false;
+  }
+
+  output_device[primarySecondary]->GetVolume (volume);
+  current_state[primarySecondary].opened = true;
+
+  audiooutput_config.volume = volume;
+  audiooutput_config.modifyable = true;
+
+  runtime.run_in_main (sigc::bind (audiooutputdevice_opened.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device, audiooutput_config));
+
+  return true;
+}
+
+void GMAudioOutputManager_ptlib::close(Ekiga::AudioOutputPrimarySecondary primarySecondary)
+{
+  PTRACE(0, "GMAudioOutputManager_ptlib\tClosing device[" << primarySecondary << "] " << current_state[primarySecondary].audiooutput_device.source << "/" <<  current_state[primarySecondary].audiooutput_device.device);
+  if (output_device[primarySecondary]) {
+     delete output_device[primarySecondary];
+     output_device[primarySecondary] = NULL;
+  }
+  current_state[primarySecondary].opened = false;
+  runtime.run_in_main (sigc::bind (audiooutputdevice_closed.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device));
+}
+
+void GMAudioOutputManager_ptlib::set_buffer_size (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned buffer_size, unsigned num_buffers)
+{
+  PTRACE(0, "GMAudioOutputManager_ptlib\tSetting buffer size of device[" << primarySecondary << "] " << buffer_size << "/" <<  num_buffers);
+
+  if (output_device[primarySecondary])
+    output_device[primarySecondary]->SetBuffers (buffer_size, num_buffers);
+}
+
+
+bool GMAudioOutputManager_ptlib::set_frame_data (Ekiga::AudioOutputPrimarySecondary primarySecondary, 
+                                   char *data, 
+                                   unsigned size,
+				   unsigned & written)
+{
+  bool ret = false;
+  written = 0;
+
+  if (!current_state[primarySecondary].opened) {
+    PTRACE(1, "GMAudioOutputManager_ptlib\tTrying to get frame from closed device[" << primarySecondary << "]");
+    return false;
+  }
+
+  if (output_device[primarySecondary]) {
+    ret = output_device[primarySecondary]->Write ((void*)data, size);
+    if (ret) {
+      written = output_device[primarySecondary]->GetLastWriteCount();
+    }
+    else {
+      PTRACE(1, "GMAudioOutputManager_ptlib\tEncountered error while trying to write data");
+      runtime.run_in_main (sigc::bind (audiooutputdevice_error.make_slot (), primarySecondary, current_state[primarySecondary].audiooutput_device, Ekiga::_AUDIO_ERR_WRITE));
+
+    }
+  }
+  return ret;
+}
+
+void GMAudioOutputManager_ptlib::set_volume (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned volume )
+{
+  PTRACE(0, "GMAudioOutputManager_ptlib\tSetting volume of device [" << primarySecondary << "] to " << volume);
+  if (output_device[primarySecondary])
+    output_device[primarySecondary]->SetVolume(volume);
+}
+
+bool GMAudioOutputManager_ptlib::has_device(const std::string & sink, const std::string & device, Ekiga::AudioOutputDevice & audiooutput_device)
+{
+  if (sink == "alsa") {
+    audiooutput_device.type = DEVICE_TYPE;
+    audiooutput_device.source = "ALSA";
+    audiooutput_device.device = device;
+    return true;
+  }
+/*  if (source == "oss") {
+    audiooutput_device.type = DEVICE_TYPE;
+    audiooutput_device.source = "OSS";
+    audiooutput_device.device = device;
+    return true;
+  }*/
+  return false;
+}

Added: trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/ptlib/audiooutput-manager-ptlib.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,103 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager-ptlib.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audioinput core.
+ *                          A audioinput core manages AudioInputManagers.
+ *
+ */
+
+
+#ifndef __AUDIOINPUT_MANAGER_PTLIB_H__
+#define __AUDIOINPUT_MANAGER_PTLIB_H__
+
+#include "audiooutput-manager.h"
+#include "runtime.h"
+
+#include "ptbuildopts.h"
+#include <ptlib/sound.h>
+/**
+ * @addtogroup audioinput
+ * @{
+ */
+
+  class GMAudioOutputManager_ptlib
+   : public Ekiga::AudioOutputManager
+    {
+  public:
+
+      /* The constructor
+       */
+       GMAudioOutputManager_ptlib (Ekiga::ServiceCore & core);
+      /* The destructor
+       */
+      ~GMAudioOutputManager_ptlib () {}
+
+
+      /*                 
+       * DISPLAY MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+
+      virtual void get_audiooutput_devices (std::vector <Ekiga::AudioOutputDevice> & audiooutput_devices);
+
+      virtual bool set_audiooutput_device (Ekiga::AudioOutputPrimarySecondary primarySecondary, const Ekiga::AudioOutputDevice & audiooutput_device);
+
+      virtual bool open (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      virtual void close(Ekiga::AudioOutputPrimarySecondary primarySecondary);
+
+      virtual void set_buffer_size (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned buffer_size, unsigned num_buffers);
+
+      virtual bool set_frame_data (Ekiga::AudioOutputPrimarySecondary primarySecondary, 
+                                   char *data, 
+                                   unsigned size,
+				   unsigned & written);
+
+      virtual void set_volume     (Ekiga::AudioOutputPrimarySecondary primarySecondary, unsigned volume );
+
+      virtual bool has_device     (const std::string & sink, const std::string & device, Ekiga::AudioOutputDevice & audiooutput_device);
+
+    protected:
+      Ekiga::ServiceCore & core;
+      Ekiga::Runtime & runtime;
+
+      PSoundChannel *output_device[2];
+  };
+/**
+ * @}
+ */
+
+
+#endif

Added: trunk/lib/engine/audiooutput/skel/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,25 @@
+noinst_LTLIBRARIES = libgmaudiooutput.la
+
+audiooutput_dir = $(top_srcdir)/lib/engine/audiooutput/skel
+
+AM_CXXFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf \
+	-I$(top_srcdir)/lib/engine/include \
+	-I$(top_srcdir)/lib/engine/framework \
+	-I$(top_srcdir)/lib/engine/audiooutput/skel \
+	-I$(top_srcdir)/lib/engine/hal/skel
+
+
+libgmaudiooutput_la_SOURCES = \
+	$(audiooutput_dir)/audiooutput-manager.h       \
+	$(audiooutput_dir)/audiooutput-info.h	       \
+	$(audiooutput_dir)/audiooutput-scheduler.h     \
+	$(audiooutput_dir)/audiooutput-scheduler.cpp   \
+	$(audiooutput_dir)/audiooutput-core.h	       \
+	$(audiooutput_dir)/audiooutput-core.cpp        \
+	$(audiooutput_dir)/audiooutput-gmconf-bridge.h \
+	$(audiooutput_dir)/audiooutput-gmconf-bridge.cpp
+
+libgmaudiooutput_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/audiooutput/skel/audiooutput-core.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-core.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,488 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-core.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audiooutput core.
+ *                          An audiooutput core manages AudioOutputManagers.
+ *
+ */
+#include "audiooutput-core.h"
+#include "audiooutput-manager.h"
+#include <algorithm>
+
+#define FALLBACK_DEVICE_TYPE "NULL"
+#define FALLBACK_DEVICE_SOURCE "NULL"
+#define FALLBACK_DEVICE_DEVICE "NULL"
+
+using namespace Ekiga;
+AudioOutputCore::AudioOutputCore (Ekiga::Runtime & _runtime)
+:  runtime (_runtime),
+   audio_event_scheduler(*this)
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+  PWaitAndSignal m_vol(vol_mutex);
+
+  current_primary_config.active = false;
+  current_primary_config.channels = 0;
+  current_primary_config.samplerate = 0;
+  current_primary_config.bits_per_sample = 0;
+  current_primary_config.buffer_size = 0;
+  current_primary_config.num_buffers = 0;
+  current_primary_config.volume = 0;
+  new_primary_volume = 0;
+  
+  current_manager[primary] = NULL;
+  current_manager[secondary] = NULL;
+  audiooutput_core_conf_bridge = NULL;
+  average_level = 0;
+  calculate_average = false;
+}
+
+AudioOutputCore::~AudioOutputCore ()
+{
+#ifdef __GNUC__
+  std::cout << __PRETTY_FUNCTION__ << std::endl;
+#endif
+
+  PWaitAndSignal m_pri(var_mutex[primary]);
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+
+  if (audiooutput_core_conf_bridge)
+    delete audiooutput_core_conf_bridge;
+}
+
+void AudioOutputCore::setup_conf_bridge ()
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+
+   audiooutput_core_conf_bridge = new AudioOutputCoreConfBridge (*this);
+}
+
+void AudioOutputCore::add_manager (AudioOutputManager &manager)
+{
+  managers.insert (&manager);
+  manager_added.emit (manager);
+
+  manager.audiooutputdevice_error.connect (sigc::bind (sigc::mem_fun (this, &AudioOutputCore::on_audiooutputdevice_error), &manager));
+  manager.audiooutputdevice_opened.connect (sigc::bind (sigc::mem_fun (this, &AudioOutputCore::on_audiooutputdevice_opened), &manager));
+  manager.audiooutputdevice_closed.connect (sigc::bind (sigc::mem_fun (this, &AudioOutputCore::on_audiooutputdevice_closed), &manager));
+}
+
+void AudioOutputCore::visit_managers (sigc::slot<bool, AudioOutputManager &> visitor)
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+  bool go_on = true;
+  
+  for (std::set<AudioOutputManager *>::iterator iter = managers.begin ();
+       iter != managers.end () && go_on;
+       iter++)
+      go_on = visitor (*(*iter));
+}
+
+void AudioOutputCore::add_event (const std::string & event_name, const std::string & file_name, bool enabled, AudioOutputPrimarySecondary primarySecondary)
+{
+  audio_event_scheduler.set_file_name(event_name, file_name, enabled, primarySecondary);
+}
+
+void AudioOutputCore::play_file (const std::string & file_name)
+{
+  audio_event_scheduler.add_event_to_queue(file_name, true, 0, 0);
+}
+
+void AudioOutputCore::play_event (const std::string & event_name)
+{
+  audio_event_scheduler.add_event_to_queue(event_name, false, 0, 0);
+}
+
+void AudioOutputCore::start_play_event (const std::string & event_name, unsigned interval, unsigned repetitions)
+{
+  audio_event_scheduler.add_event_to_queue(event_name, false, interval, repetitions);
+}
+
+void AudioOutputCore::stop_play_event (const std::string & event_name)
+{
+  audio_event_scheduler.remove_event_from_queue(event_name);
+}
+
+void AudioOutputCore::get_audiooutput_devices (std::vector <AudioOutputDevice> & audiooutput_devices)
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+
+  audiooutput_devices.clear();
+  
+  for (std::set<AudioOutputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++)
+    (*iter)->get_audiooutput_devices (audiooutput_devices);
+
+  if (PTrace::CanTrace(4)) {
+     for (std::vector<AudioOutputDevice>::iterator iter = audiooutput_devices.begin ();
+         iter != audiooutput_devices.end ();
+         iter++) {
+      PTRACE(0, "AudioOutputCore\tDetected Device: " << iter->type << "/" << iter->source << "/" << iter->device);
+    }
+  }
+
+}
+
+void AudioOutputCore::set_audiooutput_device(AudioOutputPrimarySecondary primarySecondary, const AudioOutputDevice & audiooutput_device)
+{
+  PTRACE(0, "AudioOutputCore\tSetting device[" << primarySecondary << "]: " << audiooutput_device.type << "/" << audiooutput_device.source << "/" << audiooutput_device.device);
+
+  PWaitAndSignal m_sec(var_mutex[secondary]);
+
+  switch (primarySecondary) {
+    case primary:
+      var_mutex[primary].Wait();
+      if (current_primary_config.active)
+        internal_close(primary);
+
+      if ( (audiooutput_device.type == current_device[secondary].type) &&
+           (audiooutput_device.source == current_device[secondary].source) &&
+           (audiooutput_device.device == current_device[secondary].device) )
+      { 
+        current_manager[secondary] = NULL;
+        current_device[secondary].type = "";
+        current_device[secondary].source = "";
+        current_device[secondary].device = "";
+      }
+
+      internal_set_device(primary, audiooutput_device);
+
+      if (current_primary_config.active)
+        internal_open(primary, current_primary_config.channels, current_primary_config.samplerate, current_primary_config.bits_per_sample);
+
+      if ((current_primary_config.buffer_size > 0) && (current_primary_config.num_buffers > 0 ) ) {
+        if (current_manager[primary])
+          current_manager[primary]->set_buffer_size (primary, current_primary_config.buffer_size, current_primary_config.num_buffers);
+      }
+
+      desired_primary_device = audiooutput_device;
+
+      var_mutex[primary].Signal();
+
+      break;
+    case secondary:
+        if ( (audiooutput_device.type == current_device[primary].type) &&
+             (audiooutput_device.source == current_device[primary].source) &&
+             (audiooutput_device.device == current_device[primary].device) )
+        {
+          current_manager[secondary] = NULL;
+          current_device[secondary].type = "";
+          current_device[secondary].source = "";
+          current_device[secondary].device = "";
+        }
+        else {
+          internal_set_device (secondary, audiooutput_device);
+        }
+        break;
+    default:
+      break;
+  }
+}
+
+void AudioOutputCore::start (unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+
+  if (current_primary_config.active) {
+    PTRACE(1, "AudioOutputCore\tTrying to start output device although already started");
+    return;
+  }
+
+  average_level = 0;
+  internal_open(primary, channels, samplerate, bits_per_sample);
+  current_primary_config.active = true;
+  current_primary_config.channels = channels;
+  current_primary_config.samplerate = samplerate;
+  current_primary_config.bits_per_sample = bits_per_sample;
+  current_primary_config.buffer_size = 0;
+  current_primary_config.num_buffers = 0;
+}
+
+void AudioOutputCore::stop()
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+
+  average_level = 0;
+  internal_close(primary);
+  current_primary_config.active = false;
+}
+
+void AudioOutputCore::set_buffer_size (unsigned buffer_size, unsigned num_buffers) {
+  PWaitAndSignal m_pri(var_mutex[primary]);
+
+  if (current_manager[primary])
+    current_manager[primary]->set_buffer_size (primary, buffer_size, num_buffers);
+
+  current_primary_config.buffer_size = buffer_size;
+  current_primary_config.num_buffers = num_buffers;
+}
+
+
+void AudioOutputCore::set_frame_data (char *data,
+                                      unsigned size,
+				      unsigned & written)
+{
+  PWaitAndSignal m_pri(var_mutex[primary]);
+
+  if (current_manager[primary]) {
+    if (!current_manager[primary]->set_frame_data(primary,data, size, written)) {
+      internal_close(primary);
+      internal_set_primary_fallback();
+      internal_open(primary, current_primary_config.channels, current_primary_config.samplerate, current_primary_config.bits_per_sample);
+      if (current_manager[primary])
+        current_manager[primary]->set_frame_data(primary,data, size, written); // the default device must always return true
+    }
+
+    PWaitAndSignal m_vol(vol_mutex);
+    if (new_primary_volume != current_primary_config.volume) {
+      current_manager[primary]->set_volume(primary, new_primary_volume);
+      current_primary_config.volume = new_primary_volume;
+    }
+  }
+
+  if (calculate_average) 
+    calculate_average_level((const short*) data, written);
+}
+
+void AudioOutputCore::play_buffer(AudioOutputPrimarySecondary primarySecondary, char* buffer, unsigned long len, unsigned channels, unsigned sample_rate, unsigned bps)
+{
+PTRACE(0, "Play buffer " << primarySecondary);
+  switch (primarySecondary) {
+    case primary:
+      var_mutex[primary].Wait();
+
+      if (!current_manager[primary]) {
+        PTRACE(0, "AudioOutputCore\tDropping sound event, primary manager not set");
+        var_mutex[primary].Signal();
+        return;
+      }
+
+      if (current_primary_config.active) {
+        PTRACE(0, "AudioOutputCore\tDropping sound event, primary device not set");
+        var_mutex[primary].Signal();
+        return;
+      }
+      internal_play(primary, buffer, len, channels, sample_rate, bps);
+      var_mutex[primary].Signal();
+
+      break;
+    case secondary:
+        var_mutex[secondary].Wait();
+ 
+        if (current_manager[secondary]) {
+             internal_play(secondary, buffer, len, channels, sample_rate, bps);
+          var_mutex[secondary].Signal();
+        }
+        else {
+          var_mutex[secondary].Signal();
+          PTRACE(0, "AudioOutputCore\tNo secondary audiooutput device defined, trying primary");
+          play_buffer(primary, buffer, len, channels, sample_rate, bps);
+        }
+      break;
+    default:
+      break;
+  }
+}
+
+
+void AudioOutputCore::internal_set_device (AudioOutputPrimarySecondary primarySecondary, const AudioOutputDevice & audiooutput_device)
+{
+  current_manager[primarySecondary] = NULL;
+  for (std::set<AudioOutputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->set_audiooutput_device (primarySecondary, audiooutput_device)) {
+       current_manager[primarySecondary] = (*iter);
+     }
+  }
+
+  if (current_manager[primarySecondary]) {
+    current_device[primarySecondary]  = audiooutput_device;
+  }
+  else {
+    if (primarySecondary == primary) {
+      PTRACE(1, "AudioOutputCore\tTried to set unexisting primary device " << audiooutput_device.type << "/" << audiooutput_device.source << "/" << audiooutput_device.device);
+      internal_set_primary_fallback();
+    }
+    else {
+      PTRACE(1, "AudioOutputCore\tTried to set unexisting secondary device " << audiooutput_device.type << "/" << audiooutput_device.source << "/" << audiooutput_device.device);
+      current_device[secondary].type = "";
+      current_device[secondary].source = "";
+      current_device[secondary].device = "";
+    }
+  }
+
+}
+
+void AudioOutputCore::on_audiooutputdevice_error (AudioOutputPrimarySecondary primarySecondary, AudioOutputDevice audiooutput_device, AudioOutputErrorCodes error_code, AudioOutputManager *manager)
+{
+  audiooutputdevice_error.emit (*manager, primarySecondary, audiooutput_device, error_code);
+}
+
+void AudioOutputCore::on_audiooutputdevice_opened (AudioOutputPrimarySecondary primarySecondary,
+                                                AudioOutputDevice audiooutput_device,
+                                                AudioOutputConfig audiooutput_config, 
+                                                AudioOutputManager *manager)
+{
+  audiooutputdevice_opened.emit (*manager, primarySecondary, audiooutput_device, audiooutput_config);
+}
+
+void AudioOutputCore::on_audiooutputdevice_closed (AudioOutputPrimarySecondary primarySecondary, AudioOutputDevice audiooutput_device, AudioOutputManager *manager)
+{
+  audiooutputdevice_closed.emit (*manager, primarySecondary, audiooutput_device);
+}
+
+
+bool AudioOutputCore::internal_open (AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample)
+{
+  PTRACE(0, "AudioOutputCore\tOpening device["<<primarySecondary<<"] with " << channels<< "-" << samplerate << "/" << bits_per_sample);
+
+  if (!current_manager[primarySecondary]) {
+    PTRACE(1, "AudioOutputCore\tUnable to obtain current manager for device["<<primarySecondary<<"]");
+    return false;
+  }
+
+  if (!current_manager[primarySecondary]->open(primarySecondary, channels, samplerate, bits_per_sample)) {
+    PTRACE(1, "AudioOutputCore\tUnable to open device["<<primarySecondary<<"]");
+    if (primarySecondary == primary) {
+      internal_set_primary_fallback();
+      if (current_manager[primary])
+        current_manager[primary]->open(primarySecondary, channels, samplerate, bits_per_sample);
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+  return true;
+}
+
+void AudioOutputCore::internal_close(AudioOutputPrimarySecondary primarySecondary)
+{
+  PTRACE(0, "AudioOutputCore\tClosing current device");
+  if (current_manager[primarySecondary])
+    current_manager[primarySecondary]->close(primarySecondary);
+}
+
+void AudioOutputCore::internal_play(AudioOutputPrimarySecondary primarySecondary, char* buffer, unsigned long len, unsigned channels, unsigned sample_rate, unsigned bps)
+{
+  unsigned long pos = 0;
+  unsigned written = 0;
+
+  PTRACE(0, "AudioOutputCore\tinternal_play");
+  if (!internal_open ( primarySecondary, channels, sample_rate, bps))
+    return;
+
+  if (current_manager[primarySecondary]) {
+    current_manager[primarySecondary]->set_buffer_size (primarySecondary, 320, 4);
+    do {
+      if (!current_manager[primarySecondary]->set_frame_data(primarySecondary, buffer+pos, std::min((unsigned)320, (unsigned) (len - pos)), written))
+        break;
+      pos += 320;
+    } while (pos < len);
+  }
+
+  internal_close( primarySecondary);
+}
+
+void AudioOutputCore::calculate_average_level (const short *buffer, unsigned size)
+{
+  int sum = 0;
+  unsigned csize = 0;
+  
+  while (csize < (size>>1) ) {
+
+    if (*buffer < 0)
+      sum -= *buffer++;
+    else
+      sum += *buffer++;
+
+    csize++;
+  }
+	  
+  average_level = log10 (9.0*sum/size/32767+1)*1.0;
+}
+
+void AudioOutputCore::set_volume (AudioOutputPrimarySecondary primarySecondary, unsigned volume)
+{
+  PWaitAndSignal m_vol(vol_mutex);
+
+  if (primarySecondary == primary) {
+    new_primary_volume = volume;
+  }
+}
+
+void AudioOutputCore::internal_set_primary_fallback()
+{
+  PTRACE(1, "AudioOutputCore\tFalling back to " << FALLBACK_DEVICE_TYPE << "/" << FALLBACK_DEVICE_SOURCE << "/" << FALLBACK_DEVICE_DEVICE);
+  current_device[primary].type = FALLBACK_DEVICE_TYPE;
+  current_device[primary].source = FALLBACK_DEVICE_SOURCE;
+  current_device[primary].device = FALLBACK_DEVICE_DEVICE;
+  internal_set_device(primary, current_device[primary]);
+}
+
+void AudioOutputCore::add_device (std::string & sink, std::string & device, HalManager* /*manager*/)
+{
+  PTRACE(0, "AudioOutputCore\tAdding Device");
+  AudioOutputDevice audiooutput_device;
+  for (std::set<AudioOutputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->has_device (sink, device, audiooutput_device)) {
+
+       if ( ( desired_primary_device.type   == audiooutput_device.type   ) &&
+            ( desired_primary_device.source == audiooutput_device.source ) &&
+            ( desired_primary_device.device == audiooutput_device.device ) ) {
+         set_audiooutput_device(primary, desired_primary_device);
+       }
+
+       runtime.run_in_main (sigc::bind (audiooutputdevice_added.make_slot (), audiooutput_device));
+     }
+  }
+}
+
+void AudioOutputCore::remove_device (std::string & sink, std::string & device, HalManager* /*manager*/)
+{
+  PTRACE(0, "AudioOutputCore\tRemoving Device");
+  AudioOutputDevice audiooutput_device;
+  for (std::set<AudioOutputManager *>::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+     if ((*iter)->has_device (sink, device, audiooutput_device)) {
+       runtime.run_in_main (sigc::bind (audiooutputdevice_removed.make_slot (), audiooutput_device));
+     }
+  }
+}

Added: trunk/lib/engine/audiooutput/skel/audiooutput-core.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-core.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,209 @@
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a audiooutput core.
+ *                          A audioout core manages AudioOutputManagers.
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_CORE_H__
+#define __AUDIOOUTPUT_CORE_H__
+
+#include "services.h"
+#include "runtime.h"
+#include "audiooutput-core.h"
+#include "hal-core.h"
+#include "audiooutput-gmconf-bridge.h"
+#include "audiooutput-info.h"
+#include "audiooutput-scheduler.h"
+
+#include <sigc++/sigc++.h>
+#include <glib.h>
+#include <set>
+
+#include "ptbuildopts.h"
+#include "ptlib.h"
+
+namespace Ekiga
+{
+  typedef struct AudioOutputDeviceConfig {
+    bool active;
+    unsigned channels;
+    unsigned samplerate;
+    unsigned bits_per_sample;
+    unsigned buffer_size;
+    unsigned num_buffers;
+    unsigned volume;
+  };
+
+/**
+ * @defgroup audiooutput Audio AudioInput
+ * @{
+ */
+
+   class AudioOutputManager;
+   class AudioOutputCore;
+
+  /** Core object for the audio auioinput support
+   */
+  class AudioOutputCore
+    : public Service
+    {
+
+  public:
+
+      /* The constructor
+      */
+      AudioOutputCore (Ekiga::Runtime & _runtime);
+
+      /* The destructor
+      */
+      ~AudioOutputCore ();
+
+      void setup_conf_bridge();
+
+      /*** Service Implementation ***/
+
+      /** Returns the name of the service.
+       * @return The service name.
+       */
+      const std::string get_name () const
+        { return "audiooutput-core"; }
+
+
+      /** Returns the description of the service.
+       * @return The service description.
+       */
+      const std::string get_description () const
+        { return "\tAudioOutput Core managing AudioOutput Manager objects"; }
+
+
+      /** Adds a AudioOutputManager to the AudioOutputCore service.
+       * @param The manager to be added.
+       */
+       void add_manager (AudioOutputManager &manager);
+
+      /** Triggers a callback for all Ekiga::AudioOutputManager sources of the
+       * AudioOutputCore service.
+       */
+       void visit_managers (sigc::slot<bool, AudioOutputManager &> visitor);
+
+      /** This signal is emitted when a Ekiga::AudioOutputManager has been
+       * added to the AudioOutputCore Service.
+       */
+       sigc::signal<void, AudioOutputManager &> manager_added;
+
+      void add_event (const std::string & event_name, const std::string & file_name, bool enabled, AudioOutputPrimarySecondary primarySecondary);
+
+      void play_file (const std::string & file_name);
+
+      void play_event (const std::string & event_name);
+
+      void start_play_event (const std::string & event_name, unsigned interval, unsigned repetitions);
+
+      void stop_play_event (const std::string & event_name);
+
+
+      void get_audiooutput_devices(std::vector <AudioOutputDevice> & audiooutput_devices);
+
+      void set_audiooutput_device(AudioOutputPrimarySecondary primarySecondary, const AudioOutputDevice & audiooutput_device);
+      
+      /*** VidInput Management ***/                 
+
+      void start (unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+
+      void stop ();
+
+      void set_buffer_size (unsigned buffer_size, unsigned num_buffers);
+
+      void set_frame_data (char *data, unsigned size, unsigned & written); 
+
+      void set_volume (AudioOutputPrimarySecondary primarySecondary, unsigned volume);
+
+      void play_buffer(AudioOutputPrimarySecondary primarySecondary, char* buffer, unsigned long len, unsigned channels, unsigned sample_rate, unsigned bps);
+
+      void start_average_collection () { calculate_average = true; }
+
+      void stop_average_collection () { calculate_average = false; }
+
+      float get_average_level () { return average_level; }
+      
+      void add_device (std::string & sink, std::string & device, HalManager* manager);
+      void remove_device (std::string & sink, std::string & device, HalManager* manager);
+		  
+      /*** VidInput Related Signals ***/
+      
+      /** See audiooutput-manager.h for the API
+       */
+      sigc::signal<void, AudioOutputManager &, AudioOutputPrimarySecondary, AudioOutputDevice&, AudioOutputErrorCodes> audiooutputdevice_error;
+      sigc::signal<void, AudioOutputDevice> audiooutputdevice_added;
+      sigc::signal<void, AudioOutputDevice> audiooutputdevice_removed;
+      sigc::signal<void, AudioOutputManager &, AudioOutputPrimarySecondary, AudioOutputDevice&, AudioOutputConfig&> audiooutputdevice_opened;
+      sigc::signal<void, AudioOutputManager &, AudioOutputPrimarySecondary, AudioOutputDevice&> audiooutputdevice_closed;
+
+  private:
+      void on_audiooutputdevice_error (AudioOutputPrimarySecondary primarySecondary, AudioOutputDevice audiooutput_device, AudioOutputErrorCodes error_code, AudioOutputManager *manager);
+      void on_audiooutputdevice_opened (AudioOutputPrimarySecondary primarySecondary, 
+                                        AudioOutputDevice audiooutput_device,  
+                                        AudioOutputConfig vidinput_config, 
+                                        AudioOutputManager *manager);
+      void on_audiooutputdevice_closed (AudioOutputPrimarySecondary primarySecondary, AudioOutputDevice audiooutput_device, AudioOutputManager *manager);
+
+      void internal_set_device (AudioOutputPrimarySecondary primarySecondary, const AudioOutputDevice & audiooutput_device);
+      bool internal_open (AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample);
+      void internal_close(AudioOutputPrimarySecondary primarySecondary);
+      void internal_play(AudioOutputPrimarySecondary primarySecondary, char* buffer, unsigned long len, unsigned channels, unsigned sample_rate, unsigned bps);
+      void internal_set_primary_fallback();
+      void calculate_average_level (const short *buffer, unsigned size);
+
+      std::set<AudioOutputManager *> managers;
+
+      Ekiga::Runtime & runtime;
+
+       AudioOutputDeviceConfig current_primary_config;
+       unsigned new_primary_volume;
+       AudioOutputManager* current_manager[2];
+       AudioOutputDevice desired_primary_device;
+       AudioOutputDevice current_device[2];
+
+      PMutex var_mutex[2];      /* To protect variables that are read and written */
+      PMutex vol_mutex;      /* To protect variables that are read and written */
+
+      AudioOutputCoreConfBridge* audiooutput_core_conf_bridge;
+      AudioEventScheduler audio_event_scheduler;
+      float average_level;
+      bool calculate_average;
+    };
+/**
+ * @}
+ */
+};
+
+#endif

Added: trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,148 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-core.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : declaration of the interface of a audiooutput core.
+ *                          A audiooutput core manages AudioOutputManagers.
+ *
+ */
+
+#include "config.h"
+
+#include "audiooutput-gmconf-bridge.h"
+#include "audiooutput-core.h"
+
+#define AUDIO_DEVICES_KEY "/apps/" PACKAGE_NAME "/devices/audio/"
+#define AUDIO_CODECS_KEY "/apps/" PACKAGE_NAME "/codecs/audio/"
+#define SOUND_EVENTS_KEY  "/apps/" PACKAGE_NAME "/general/sound_events/"
+
+using namespace Ekiga;
+
+AudioOutputCoreConfBridge::AudioOutputCoreConfBridge (Ekiga::Service & _service)
+ : Ekiga::ConfBridge (_service)
+{
+  Ekiga::ConfKeys keys;
+  property_changed.connect (sigc::mem_fun (this, &AudioOutputCoreConfBridge::on_property_changed));
+
+  keys.push_back (AUDIO_DEVICES_KEY "output_device"); 
+  keys.push_back (SOUND_EVENTS_KEY "output_device"); 
+  keys.push_back (AUDIO_DEVICES_KEY "plugin"); 
+  keys.push_back (SOUND_EVENTS_KEY "busy_tone_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "incoming_call_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "new_message_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "new_voicemail_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "ring_tone_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "enable_busy_tone_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "enable_incoming_call_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "enable_new_message_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "enable_new_voicemail_sound"); 
+  keys.push_back (SOUND_EVENTS_KEY "enable_ring_tone_sound"); 
+
+  load (keys);
+}
+
+void AudioOutputCoreConfBridge::on_property_changed (std::string key, GmConfEntry *entry)
+{
+  std::string name;
+  std::string file_name;
+  bool enabled;
+
+  AudioOutputCore & audioinput_core = (AudioOutputCore &) service;
+
+  if (key == AUDIO_DEVICES_KEY "output_device") {
+
+    PTRACE(4, "AudioOutputCoreConfBridge\tUpdating device");
+    std::string config_string = gm_conf_entry_get_string (entry);
+    AudioOutputDevice audiooutput_device;
+    unsigned type_sep = config_string.find_first_of("/");
+    unsigned source_sep = config_string.find_first_of("/", type_sep + 1);
+
+    audiooutput_device.type   = config_string.substr ( 0, type_sep );
+    audiooutput_device.source = config_string.substr ( type_sep + 1, source_sep - type_sep - 1);
+    audiooutput_device.device = config_string.substr ( source_sep + 1, config_string.size() - source_sep );
+    audioinput_core.set_audiooutput_device (primary, audiooutput_device);
+  }
+
+  if (key == SOUND_EVENTS_KEY "output_device") {
+
+    PTRACE(4, "AudioOutputCoreConfBridge\tUpdating device");
+    std::string config_string = gm_conf_entry_get_string (entry);
+    AudioOutputDevice audiooutput_device;
+    unsigned type_sep = config_string.find_first_of("/");
+    unsigned source_sep = config_string.find_first_of("/", type_sep + 1);
+
+    audiooutput_device.type   = config_string.substr ( 0, type_sep );
+    audiooutput_device.source = config_string.substr ( type_sep + 1, source_sep - type_sep - 1);
+    audiooutput_device.device = config_string.substr ( source_sep + 1, config_string.size() - source_sep );
+    audioinput_core.set_audiooutput_device (secondary, audiooutput_device);
+  }
+
+  if ( (key == SOUND_EVENTS_KEY "busy_tone_sound") ||
+       (key == SOUND_EVENTS_KEY "enable_busy_tone_sound") ) {
+    name = "busy_tone_sound";
+    file_name = gm_conf_get_string (SOUND_EVENTS_KEY "busy_tone_sound");
+    enabled = gm_conf_get_bool (SOUND_EVENTS_KEY "enable_busy_tone_sound");
+    audioinput_core.add_event (name, file_name, enabled, primary);
+  }
+
+  if ( (key == SOUND_EVENTS_KEY "incoming_call_sound") ||
+       (key == SOUND_EVENTS_KEY "enable_incoming_call_sound") ) {
+    name = "incoming_call_sound";
+    file_name = gm_conf_get_string (SOUND_EVENTS_KEY "incoming_call_sound");
+    enabled = gm_conf_get_bool (SOUND_EVENTS_KEY "enable_incoming_call_sound");
+    audioinput_core.add_event (name, file_name, enabled, secondary);
+  }
+
+  if ( (key == SOUND_EVENTS_KEY "new_message_sound") ||
+       (key == SOUND_EVENTS_KEY "enable_new_message_sound") ) {
+    name = "new_message_sound";
+    file_name = gm_conf_get_string (SOUND_EVENTS_KEY "new_message_sound");
+    enabled = gm_conf_get_bool (SOUND_EVENTS_KEY "enable_new_message_sound");
+    audioinput_core.add_event (name, file_name, enabled, secondary);
+
+  }
+
+  if ( (key == SOUND_EVENTS_KEY "new_voicemail_sound") ||
+       (key == SOUND_EVENTS_KEY "enable_new_voicemail_sound") ) {
+    name = "new_voicemail_sound";
+    file_name = gm_conf_get_string (SOUND_EVENTS_KEY "new_voicemail_sound");
+    enabled = gm_conf_get_bool (SOUND_EVENTS_KEY "enable_new_voicemail_sound");
+    audioinput_core.add_event (name, file_name, enabled, secondary);
+  }
+
+  if ( (key == SOUND_EVENTS_KEY "ring_tone_sound") ||
+       (key == SOUND_EVENTS_KEY "enable_ring_tone_sound") ) {
+    name = "ring_tone_sound";
+    file_name = gm_conf_get_string (SOUND_EVENTS_KEY "ring_tone_sound");
+    enabled = gm_conf_get_bool (SOUND_EVENTS_KEY "enable_ring_tone_sound");
+    audioinput_core.add_event (name, file_name, enabled, primary);
+  }
+}
+

Added: trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-gmconf-bridge.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,57 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a audiooutput core.
+ *                          A audiooutput core manages AudioOutputManagers.
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_GMCONF_BRIDGE_H__
+#define __AUDIOOUTPUT_GMCONF_BRIDGE_H__
+
+#include "services.h"
+#include "gmconf-bridge.h"
+
+namespace Ekiga
+{
+  class AudioOutputCoreConfBridge
+    : public Ekiga::ConfBridge
+  {
+  public:
+
+    AudioOutputCoreConfBridge (Ekiga::Service & service);
+
+    void on_property_changed (std::string key, GmConfEntry *value);
+  };
+
+};
+
+#endif

Added: trunk/lib/engine/audiooutput/skel/audiooutput-info.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-info.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,66 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                          audioinput-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of a vidinput core.
+ *                          A vidinput core manages VidInputManagers.
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_INFO_H__
+#define __AUDIOOUTPUT_INFO_H__
+
+namespace Ekiga
+{
+  typedef struct AudioOutputDevice {
+    std::string type;
+    std::string source;
+    std::string device;
+  };
+
+  typedef struct AudioOutputConfig {
+    unsigned volume;
+    bool modifyable;
+  };
+
+  enum AudioOutputErrorCodes {
+    _AUDIO_ERR_NONE = 0,
+    _AUDIO_ERR_DEVICE,
+    _AUDIO_ERR_WRITE
+  };
+
+  enum AudioOutputPrimarySecondary {
+    primary = 0,
+    secondary
+  };
+
+};
+
+#endif

Added: trunk/lib/engine/audiooutput/skel/audiooutput-manager.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-manager.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,115 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audioinput-manager.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of the interface of an audioinput manager
+ *                          implementation backend.
+ *
+ */
+
+
+#ifndef __AUDIOINPUT_MANAGER_H__
+#define __AUDIOINPUT_MANAGER_H__
+
+#include "audiooutput-core.h"
+
+namespace Ekiga
+{
+
+/**
+ * @addtogroup vidinput
+ * @{
+ */
+
+  typedef struct ManagerState {
+    bool opened;
+    unsigned channels;
+    unsigned samplerate;
+    unsigned bits_per_sample;
+    AudioOutputDevice audiooutput_device;
+  };
+  
+
+  class AudioOutputManager
+    {
+
+  public:
+
+      /* The constructor
+       */
+      AudioOutputManager () {}
+
+      /* The destructor
+       */
+      ~AudioOutputManager () {}
+
+
+      /*                 
+       * AUDIOINPUT MANAGEMENT 
+       */               
+
+      /** Create a call based on the remote uri given as parameter
+       * @param uri  an uri
+       * @return     true if a Ekiga::Call could be created
+       */
+
+      virtual void get_audiooutput_devices (std::vector <AudioOutputDevice> & audiooutput_devices) = 0;
+
+      virtual bool set_audiooutput_device (AudioOutputPrimarySecondary primarySecondary, const AudioOutputDevice & audiooutput_device) = 0;
+
+      virtual bool open (AudioOutputPrimarySecondary primarySecondary, unsigned channels, unsigned samplerate, unsigned bits_per_sample) = 0;
+
+      virtual void set_buffer_size (AudioOutputPrimarySecondary /*primarySecondary*/, unsigned /*buffer_size*/, unsigned /*num_buffers*/) {};
+
+      virtual bool set_frame_data (AudioOutputPrimarySecondary primarySecondary, 
+                                   char *data, 
+                                   unsigned size,
+				   unsigned & written) = 0;
+
+      virtual void close(AudioOutputPrimarySecondary /*primarySecondary*/) {};
+
+      virtual void set_volume (AudioOutputPrimarySecondary /*primarySecondary*/, unsigned /* volume */ ) {};
+
+      virtual bool has_device     (const std::string & sink, const std::string & device, AudioOutputDevice & audiooutput_device) = 0;
+      
+      sigc::signal<void, AudioOutputPrimarySecondary, AudioOutputDevice, AudioOutputErrorCodes> audiooutputdevice_error;
+      sigc::signal<void, AudioOutputPrimarySecondary, AudioOutputDevice, AudioOutputConfig> audiooutputdevice_opened;
+      sigc::signal<void, AudioOutputPrimarySecondary, AudioOutputDevice> audiooutputdevice_closed;
+
+  protected:  
+      ManagerState current_state[2];
+  };
+/**
+ * @}
+ */
+
+};
+
+#endif

Added: trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.cpp	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,292 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-scheduler.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of a scheduler for sound events that is run in 
+ *                          a separate thread.
+ *
+ */
+
+#include "audiooutput-core.h"
+#include "audiooutput-scheduler.h"
+#include "config.h"
+
+using namespace Ekiga;
+
+AudioEventScheduler::AudioEventScheduler (AudioOutputCore& _audio_output_core)
+: PThread (1000, NoAutoDeleteThread, HighestPriority, "AudioEventScheduler"),
+    audio_output_core (_audio_output_core)
+{
+  stop_thread = false;
+  // Since windows does not like to restart a thread that 
+  // was never started, we do so here
+  this->Resume ();
+  thread_sync_point.Wait ();
+}
+
+AudioEventScheduler::~AudioEventScheduler ()
+{
+  PTRACE(4, "AudioEventScheduler\tStopping Preview");
+  stop_thread = true;
+  new_event.Signal ();
+
+  /* Wait for the Main () method to be terminated */
+  PWaitAndSignal m(quit_mutex);
+
+}
+
+void AudioEventScheduler::Main ()
+{
+  PWaitAndSignal m(quit_mutex);
+
+  std::vector <AudioEvent> pending_event_list;
+  unsigned idle_time = 32000;
+  AudioEvent event;
+  char* buffer = NULL;
+  unsigned long buffer_len = 0;
+  unsigned channels, sample_rate, bps;
+  AudioOutputPrimarySecondary primarySecondary;
+
+  thread_sync_point.Signal ();
+
+  while (!stop_thread) {
+
+    new_event.Wait (idle_time);
+
+    if (stop_thread)
+      break;
+      
+    get_pending_event_list(pending_event_list);
+PTRACE(0, "Pending list: " << pending_event_list.size());
+
+    while (pending_event_list.size() > 0) {
+      event = *(pending_event_list.begin()); pending_event_list.erase(pending_event_list.begin());
+      load_wav(event.name, event.is_file_name, buffer, buffer_len, channels, sample_rate, bps, primarySecondary);
+      if (buffer) {
+         audio_output_core.play_buffer (primarySecondary, buffer, buffer_len, channels, sample_rate, bps);
+        free (buffer);
+        buffer = NULL;
+      }
+      Current()->Sleep (10);
+    }
+    idle_time = get_time_to_next_event();
+    PTRACE(0, "Idling for " << idle_time);
+  }
+}
+
+void AudioEventScheduler::get_pending_event_list (std::vector<AudioEvent> & pending_event_list)
+{
+  PWaitAndSignal m(event_list_mutex);
+
+  AudioEvent event;
+  std::vector <AudioEvent> new_event_list;
+  unsigned long time = get_time_ms();
+
+  pending_event_list.clear();
+
+  while (event_list.size() > 0) {
+
+    event = *(event_list.begin()); event_list.erase(event_list.begin());
+
+    if (event.interval == 0) {
+      pending_event_list.push_back(event);
+    }
+    else {
+      if (event.time >= time) {
+        pending_event_list.push_back(event);
+        event.repetitions--; 
+        if (event.repetitions > 0) {
+          event.time = time + event.interval;
+          new_event_list.push_back(event);
+        }
+      }
+      else {
+        new_event_list.push_back(event);
+      }
+    }
+  }
+
+  event_list = new_event_list;
+  PTRACE(0, "repeting list " << new_event_list.size() << " " << event_list.size());
+}
+
+unsigned long AudioEventScheduler::get_time_ms()
+{
+  GTimeVal time_val;
+  g_get_current_time(&time_val);
+  return (time_val.tv_sec * 1000 + (unsigned long) (time_val.tv_usec / 1000) );
+}
+
+unsigned AudioEventScheduler::get_time_to_next_event()
+{
+  PWaitAndSignal m(event_list_mutex);
+  unsigned long time = get_time_ms();
+  unsigned min_time = 32000;
+
+  for (std::vector<AudioEvent>::iterator iter = event_list.begin ();
+       iter !=event_list.end ();
+       iter++) {
+
+    if ( (iter->interval > 0) && ((iter->time - time) < min_time) )
+      min_time = iter->time - time;
+  }
+  return min_time;
+}
+
+void AudioEventScheduler::add_event_to_queue(const std::string & name, bool is_file_name, unsigned interval, unsigned repetitions)
+{
+PTRACE(0, "Adding Event " << name << " " << interval << "/" << repetitions);
+  PWaitAndSignal m(event_list_mutex);
+  AudioEvent event;
+  event.name = name;
+  event.is_file_name = is_file_name;
+  event.interval = interval;
+  event.repetitions = repetitions;
+  event.time = get_time_ms();
+  event_list.push_back(event);
+  new_event.Signal();
+}
+
+void AudioEventScheduler::remove_event_from_queue(const std::string & name)
+{
+PTRACE(0, "Removing Event " << name);
+  PWaitAndSignal m(event_list_mutex);
+
+  bool found = false;
+  std::vector<AudioEvent>::iterator iter;
+
+  for (iter = event_list.begin ();
+       iter != event_list.end () ;
+       iter++){
+      if ( (iter->name == name) ) { 
+        found = true;
+        break;
+      }
+}
+  if (found) {
+    event_list.erase(iter);
+  }
+}
+
+void AudioEventScheduler::load_wav(const std::string & event_name, bool is_file_name, char* & buffer, unsigned long & len, unsigned & channels, unsigned & sample_rate, unsigned & bps, AudioOutputPrimarySecondary & primarySecondary)
+{
+  PWAVFile* wav = NULL;
+  std::string file_name;
+
+  len = 0;
+  buffer = NULL;
+
+  // Shall we also try event name as file name?
+  if (is_file_name) {
+    file_name = event_name;
+    primarySecondary = primary;
+  }
+  else 
+    if (!get_file_name(event_name, file_name, primarySecondary)) // if this event is disabled
+      return;
+
+  wav = new PWAVFile (file_name.c_str(), PFile::ReadOnly);
+
+  if (!wav->IsValid ()) {
+     /* it isn't a full path to a file : add our default path */
+ 
+    delete wav;
+    wav = NULL;
+ 
+    gchar* filename = g_build_filename (DATA_DIR, "sounds", PACKAGE_NAME, file_name.c_str(), NULL);
+    wav = new PWAVFile (filename, PFile::ReadOnly);
+    g_free (filename);
+  }
+  
+PTRACE(0, "Loaded wav " << file_name);
+  if (wav->IsValid ()) {
+    PTRACE(0, "is valid");
+    len = wav->GetDataLength();
+    channels = wav->GetChannels ();
+    sample_rate = wav->GetSampleRate ();
+    bps = wav->GetSampleSize ();
+
+    buffer = (char*) malloc (len);
+    memset(buffer, 127, len);
+    wav->Read(buffer, len);
+  }
+
+  delete wav;
+}
+
+
+bool AudioEventScheduler::get_file_name(const std::string & event_name, std::string & file_name, AudioOutputPrimarySecondary & primarySecondary)
+{
+  PWaitAndSignal m(event_file_list_mutex);
+
+  file_name = "";
+
+  for (std::vector<EventFileName>::iterator iter = event_file_list.begin ();
+       iter != event_file_list.end ();
+       iter++) {
+
+    if (iter->event_name == event_name) {
+      file_name = iter->file_name;
+      primarySecondary = iter->primarySecondary;
+      return (iter->enabled);
+    }
+  }
+
+  return false;
+}
+
+void AudioEventScheduler::set_file_name(const std::string & event_name, const std::string & file_name, bool enabled, AudioOutputPrimarySecondary primarySecondary)
+{
+  PWaitAndSignal m(event_file_list_mutex);
+
+  bool found = false;
+
+  for (std::vector<EventFileName>::iterator iter = event_file_list.begin ();
+       iter != event_file_list.end ();
+       iter++) {
+
+    if (iter->event_name == event_name) {
+      iter->file_name = file_name;
+      iter->enabled = enabled;
+      iter->primarySecondary = primarySecondary;
+      found = true;
+      break;
+    }
+  }
+
+  if (!found) {
+    EventFileName event_file_name;
+    event_file_name.event_name = event_name;
+    event_file_name.file_name = file_name;
+    event_file_name.enabled = enabled;
+    event_file_name.primarySecondary = secondary;
+    event_file_list.push_back(event_file_name);
+  }
+}

Added: trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/audiooutput/skel/audiooutput-scheduler.h	Sun Mar 30 19:46:13 2008
@@ -0,0 +1,104 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+
+ * This program 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 of the License, or (at
+ * your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         audiooutput-scheduler.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Matthias Schneider
+ *   copyright            : (c) 2008 by Matthias Schneider
+ *   description          : Declaration of a scheduler for sound events that is run in 
+ *                          a separate thread.
+ *
+ */
+
+#ifndef __AUDIOOUTPUT_SCHEDULER_H__
+#define __AUDIOOUTPUT_SCHEDULER_H__
+
+#include "services.h"
+#include "audiooutput-core.h"
+
+#include <glib.h>
+#include <vector>
+
+#include "ptbuildopts.h"
+#include "ptlib.h"
+#include <ptclib/pwavfile.h>
+
+namespace Ekiga
+{
+  typedef struct AudioEvent {
+    std::string name;
+    bool is_file_name;
+    unsigned interval;
+    unsigned repetitions;
+    unsigned long time;
+  };
+
+  typedef struct EventFileName {
+    std::string event_name;
+    std::string file_name;
+    bool enabled;
+    AudioOutputPrimarySecondary primarySecondary;
+  };
+  class AudioOutputCore;
+//  class AudioEventScheduler;
+
+  class AudioEventScheduler : public PThread
+  {
+    PCLASSINFO(AudioEventScheduler, PThread);
+
+  public:
+    AudioEventScheduler(AudioOutputCore& _audio_output_core);
+    ~AudioEventScheduler();
+    void add_event_to_queue(const std::string & name, bool is_file_name, unsigned interval, unsigned repetitions);
+    void remove_event_from_queue(const std::string & name);
+    void set_file_name(const std::string & event_name, const std::string & file_name, bool enabled, AudioOutputPrimarySecondary primarySecondary);
+  
+  protected:
+    void Main (void);
+    void get_pending_event_list (std::vector<AudioEvent> & pending_event_list);
+    unsigned long get_time_ms();
+    unsigned get_time_to_next_event();
+    bool get_file_name(const std::string & event_name, std::string & file_name, AudioOutputPrimarySecondary & primarySecondary);
+    void load_wav(const std::string & event_name, bool is_file_name, char* & buffer, unsigned long & len, unsigned & channels, unsigned & sample_rate, unsigned & bps, AudioOutputPrimarySecondary & primarySecondary);
+
+    bool stop_thread;
+
+    PMutex quit_mutex;     /* To exit */
+    PSyncPoint thread_sync_point;
+
+    PSyncPoint new_event;
+
+    PMutex event_list_mutex;
+    std::vector <AudioEvent> event_list;
+
+    PMutex event_file_list_mutex;
+    std::vector <EventFileName> event_file_list;
+
+    AudioOutputCore& audio_output_core;
+  };
+};
+#endif

Modified: trunk/lib/engine/engine.cpp
==============================================================================
--- trunk/lib/engine/engine.cpp	(original)
+++ trunk/lib/engine/engine.cpp	Sun Mar 30 19:46:13 2008
@@ -46,6 +46,8 @@
 #include "call-core.h"
 #include "display-core.h"
 #include "vidinput-core.h"
+#include "audioinput-core.h"
+#include "audiooutput-core.h"
 #include "hal-core.h"
 #include "history-main.h"
 #include "local-roster-main.h"
@@ -63,8 +65,12 @@
 #endif
 
 #include "vidinput-main-mlogo.h"
+#include "audioinput-main-null.h"
+#include "audiooutput-main-null.h"
 
 #include "vidinput-main-ptlib.h"
+#include "audioinput-main-ptlib.h"
+#include "audiooutput-main-ptlib.h"
 
 #ifdef HAVE_DBUS
 #include "hal-main-dbus.h"
@@ -101,6 +107,8 @@
   Ekiga::CallCore *call_core = new Ekiga::CallCore;
   Ekiga::DisplayCore *display_core = new Ekiga::DisplayCore;
   Ekiga::VidInputCore *vidinput_core = new Ekiga::VidInputCore(*runtime, *display_core);
+  Ekiga::AudioOutputCore *audiooutput_core = new Ekiga::AudioOutputCore(*runtime);  
+  Ekiga::AudioInputCore *audioinput_core = new Ekiga::AudioInputCore(*runtime, *audiooutput_core);
   Ekiga::HalCore *hal_core = new Ekiga::HalCore;
 
 
@@ -117,6 +125,8 @@
   core->add (*call_core);
   core->add (*display_core);
   core->add (*vidinput_core);
+  core->add (*audiooutput_core);
+  core->add (*audioinput_core);
   core->add (*hal_core);
 
   if (!gmconf_personal_details_init (*core, &argc, &argv)) {
@@ -143,11 +153,31 @@
     return;
   }
 
+  if (!audioinput_null_init (*core, &argc, &argv)) {
+    delete core;
+    return;
+  }
+
+  if (!audiooutput_null_init (*core, &argc, &argv)) {
+    delete core;
+    return;
+  }
+
   if (!vidinput_ptlib_init (*core, &argc, &argv)) {
     delete core;
     return;
   }
 
+  if (!audioinput_ptlib_init (*core, &argc, &argv)) {
+    delete core;
+    return;
+  }
+
+  if (!audiooutput_ptlib_init (*core, &argc, &argv)) {
+    delete core;
+    return;
+  }
+
 #ifdef HAVE_DBUS
   if (!hal_dbus_init (*core, &argc, &argv)) {
     delete core;
@@ -207,6 +237,18 @@
     return;
   }
 
-  vidinput_core->setup_conf_bridge();
   display_core->setup_conf_bridge();
+  vidinput_core->setup_conf_bridge();
+//  audiooutput_core->setup_conf_bridge();
+//  audioinput_core->setup_conf_bridge();
+
+//  sigc::connection conn;
+//  conn = hal_core->video_input_device_added.connect (sigc::mem_fun (vidinput_core, &Ekiga::VidInputCore::add_device));
+//  conn = hal_core->video_input_device_removed.connect (sigc::mem_fun (vidinput_core, &Ekiga::VidInputCore::remove_device));
+//  conn = hal_core->audio_output_device_added.connect (sigc::mem_fun (audiooutput_core, &Ekiga::AudioOutputCore::add_device));
+//  conn = hal_core->audio_output_device_removed.connect (sigc::mem_fun (audiooutput_core, &Ekiga::AudioOutputCore::remove_device));
+//  conn = hal_core->audio_input_device_added.connect (sigc::mem_fun (audioinput_core, &Ekiga::AudioInputCore::add_device));
+//  conn = hal_core->audio_input_device_removed.connect (sigc::mem_fun (audioinput_core, &Ekiga::AudioInputCore::remove_device));
+  // std::vector<sigc::connection> connections;
+  //connections.push_back (conn);
 }

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sun Mar 30 19:46:13 2008
@@ -16,10 +16,12 @@
 	-I$(top_srcdir)/lib/engine/protocol/sip		\
 	-I$(top_srcdir)/lib/engine/display/skel		\
 	-I$(top_srcdir)/lib/engine/vidinput/skel	\
+	-I$(top_srcdir)/lib/engine/audioinput/skel	\
+	-I$(top_srcdir)/lib/engine/audiooutput/skel	\
+	-I$(top_srcdir)/lib/engine/hal/skel	\
 	-I$(top_srcdir)/lib/engine/framework		\
 	-I$(top_builddir)				\
 	$(GNOME_INCLUDEDIR)				\
-	-DDATA_DIR=\""$(datadir)"\"			\
 	-DSCHEMA_AGE= SCHEMA_AGE@ 
 
 # XVideo/X



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]