[PATCH] Add alsa device driver and compilation fixes.

View: New views
1 Messages — Rating Filter:   Alert me  

[PATCH] Add alsa device driver and compilation fixes.

by Jinghua Luo :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

hi, folks.
 It seems audiere is not actively maintained. I attached two patches
I wrote today and hope it will be useful for guys using linux.

diff -ur audiere/configure.in audiere-1.9.4/configure.in
--- audiere/configure.in 2004-11-08 07:41:37.000000000 +0800
+++ audiere-1.9.4/configure.in 2008-11-15 20:08:22.000000000 +0800
@@ -163,6 +163,12 @@
     AC_DEFINE(HAVE_OSS))
 AM_CONDITIONAL(HAVE_OSS, test "x$HAVE_OSS" = "xtrue")
 
+AC_CHECK_HEADER(alsa/asoundlib.h,
+    HAVE_ALSA=true
+    LIBS="-lasound $LIBS"
+    AC_DEFINE(HAVE_ALSA))
+AM_CONDITIONAL(HAVE_ALSA, test "x$HAVE_ALSA" = "xtrue")
+
 AC_CHECK_HEADER(vorbis/vorbisfile.h,
     HAVE_OGG=true
     LIBS="-lvorbisfile -lvorbis -logg $LIBS"
diff -ur audiere/src/device.cpp audiere-1.9.4/src/device.cpp
--- audiere/src/device.cpp 2004-04-09 15:19:14.000000000 +0800
+++ audiere-1.9.4/src/device.cpp 2008-11-15 22:29:36.000000000 +0800
@@ -20,6 +20,10 @@
 
 #endif
 
+#ifdef HAVE_ALSA
+  #include "device_alsa.h"
+#endif
+
 #ifdef HAVE_OSS
   #include "device_oss.h"
 #endif
@@ -149,6 +153,9 @@
       "directsound:DirectSound (high-performance)"  ";"
       "winmm:Windows Multimedia (compatible)"  ";"
 #else
+#ifdef HAVE_ALSA
+      "alsa:Advance Linux Sound Architecture"  ";"
+#endif
 #ifdef HAVE_OSS
       "oss:Open Sound System"  ";"
 #endif
@@ -219,10 +226,18 @@
         TRY_GROUP("al");
         TRY_GROUP("directsound");
         TRY_GROUP("winmm");
+        TRY_GROUP("alsa");
         TRY_GROUP("oss");
         return 0;
       }
 
+      #ifdef HAVE_ALSA
+        if (name == "alsa") {
+          TRY_DEVICE(ALSAAudioDevice);
+          return 0;
+        }
+      #endif
+
       #ifdef HAVE_OSS
         if (name == "oss") {
           TRY_DEVICE(OSSAudioDevice);
diff -ur audiere/src/Makefile.am audiere-1.9.4/src/Makefile.am
--- audiere/src/Makefile.am 2004-11-08 07:41:39.000000000 +0800
+++ audiere-1.9.4/src/Makefile.am 2008-11-15 20:12:23.000000000 +0800
@@ -33,6 +33,12 @@
 AL_DIST    = device_al.cpp device_al.h
 endif
 
+if HAVE_ALSA
+ALSA_SOURCES = device_alsa.cpp device_alsa.h
+else
+ALSA_DIST    = device_alsa.cpp device_alsa.h
+endif
+
 if HAVE_OSS
 OSS_SOURCES = device_oss.cpp device_oss.h
 else
@@ -106,6 +112,7 @@
  device_null.cpp \
  device_null.h \
  $(AL_SOURCES) \
+ $(ALSA_SOURCES) \
  $(OSS_SOURCES) \
  $(WINMM_SOURCES) \
  dumb_resample.cpp \
--- /dev/null 2008-11-15 21:52:27.942635028 +0800
+++ audiere-1.9.4/src/device_alsa.h 2008-11-15 22:29:54.000000000 +0800
@@ -0,0 +1,35 @@
+#ifndef DEVICE_ALSA_H
+#define DEVICE_ALSA_H
+
+
+#include "audiere.h"
+#include "device_mixer.h"
+
+#include <alsa/asoundlib.h>
+
+namespace audiere {
+
+  class ALSAAudioDevice : public MixerDevice {
+  public:
+    static ALSAAudioDevice* create(const ParameterList& parameters);
+
+  private:
+    ALSAAudioDevice(snd_pcm_t* pcm_handle,
+                    int rate,
+                    int buffer_size);
+    ~ALSAAudioDevice();
+
+  public:
+    void ADR_CALL update();
+    const char* ADR_CALL getName();
+
+  private:
+    snd_pcm_t* m_pcm_handle;
+    int m_buffer_size;
+    char* m_buffer;
+  };
+
+}
+
+
+#endif
--- /dev/null 2008-11-15 21:52:27.942635028 +0800
+++ audiere-1.9.4/src/device_alsa.cpp 2008-11-15 22:29:48.000000000 +0800
@@ -0,0 +1,219 @@
+#include <algorithm>
+#include <string>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <alsa/asoundlib.h>
+#include "device_alsa.h"
+#include "debug.h"
+
+
+namespace audiere {
+
+  ALSAAudioDevice*
+  ALSAAudioDevice::create(const ParameterList& parameters) {
+    std::string device = parameters.getValue("device", "default");
+    int status;
+
+    snd_pcm_t* pcm_handle;
+    status = snd_pcm_open(&pcm_handle, device.c_str (),
+                          SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+    if (status < 0) {
+      perror(device.c_str());
+      return 0;
+    }
+
+    snd_pcm_hw_params_t* hwparams;
+    snd_pcm_sw_params_t* swparams;
+
+    snd_pcm_hw_params_alloca(&hwparams);
+    status = snd_pcm_hw_params_any(pcm_handle, hwparams);
+    if (status < 0) {
+      ADR_LOG("Couldn't get hardware config.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    status = snd_pcm_hw_params_set_access(pcm_handle, hwparams,
+                                          SND_PCM_ACCESS_RW_INTERLEAVED);
+    if (status < 0) {
+      ADR_LOG("Couldn't set interleaved access.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    status = snd_pcm_hw_params_set_format(pcm_handle, hwparams,
+                                          SND_PCM_FORMAT_S16_LE);
+    if (status < 0) {
+      ADR_LOG("Couldn't set audio format.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    status = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2);
+    if (status < 0) {
+      ADR_LOG("Couldn't set audio channels");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    unsigned int rate = 44100;
+    status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
+                                             &rate, NULL);
+    if (status < 0) {
+      ADR_LOG("Couldn't set audio frequency.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+    status = snd_pcm_hw_params_get_rate(hwparams, &rate, NULL);
+    if (status < 0) {
+      ADR_LOG("Couldn't get audio frequency.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    unsigned int buffer_time;
+    status = snd_pcm_hw_params_get_buffer_time_max(hwparams,
+                                                   &buffer_time, 0);
+
+    if (status < 0) {
+      ADR_LOG("Couldn't get maximium buffer time.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+    buffer_time /= 2;
+    if (buffer_time < 100000)
+      buffer_time = 100000;
+    if (buffer_time > 500000)
+      buffer_time = 500000;
+
+    unsigned int period_time = 0;
+    period_time = buffer_time / 4;
+
+    status = snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams,
+                                                    &period_time, 0);
+    if (status < 0) {
+      ADR_LOG("Couldn't set period time.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    status = snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams,
+                                                    &buffer_time, 0);
+    if (status < 0) {
+      ADR_LOG("Couldn't set buffer time.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    status = snd_pcm_hw_params(pcm_handle, hwparams);
+    if (status < 0) {
+      ADR_LOG("Couldn't set haredware parameters.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    snd_pcm_uframes_t chunk_size;
+    snd_pcm_uframes_t buffer_size;
+    snd_pcm_hw_params_get_period_size(hwparams, &chunk_size, 0);
+    snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
+    if (chunk_size == buffer_size) {
+      ADR_LOG("Can't use period equal to buffer size");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    snd_pcm_sw_params_alloca(&swparams);
+    status = snd_pcm_sw_params_current(pcm_handle, swparams);
+    if (status < 0) {
+      ADR_LOG("Couldn't get software config.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+    status = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 0);
+    if (status < 0) {
+      ADR_LOG("Couldn't set start threshold");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+    status = snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, chunk_size);
+    if (status < 0) {
+      ADR_LOG("Couldn't set avail min.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+    status = snd_pcm_sw_params(pcm_handle, swparams);
+    if (status < 0) {
+      ADR_LOG("Couldn't set software audio parameters.");
+      snd_pcm_close(pcm_handle);
+      return 0;
+    }
+
+    int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
+    int bits_per_frame = bits_per_sample * 2;
+    int chunk_bytes = chunk_size * bits_per_frame / 8;
+
+    return new ALSAAudioDevice(pcm_handle, rate, chunk_bytes);
+  }
+
+
+  ALSAAudioDevice::ALSAAudioDevice(snd_pcm_t* pcm_handle,
+                                   int rate,
+                                   int buffer_size)
+    : MixerDevice(rate)
+  {
+    m_pcm_handle = pcm_handle;
+    m_buffer_size = buffer_size;
+    m_buffer = new char [buffer_size];
+  }
+
+
+  ALSAAudioDevice::~ALSAAudioDevice() {
+    ADR_GUARD("ALSAAudioDevice::~ALSAAudioDevice");
+    snd_pcm_drain(m_pcm_handle);
+    snd_pcm_close(m_pcm_handle);
+    delete [] m_buffer;
+  }
+
+
+  void ADR_CALL
+  ALSAAudioDevice::update() {
+    int           ret;
+    int           sample_len;
+    char*         sample_buf;
+
+    sample_buf = m_buffer;
+    sample_len = m_buffer_size / 4;
+
+    read(sample_len, sample_buf);
+    while (sample_len > 0) {
+      ret = snd_pcm_writei(m_pcm_handle, sample_buf, sample_len);
+      if (ret < 0) {
+        if (ret == -EAGAIN) {
+          snd_pcm_wait(m_pcm_handle, 10);
+          continue;
+        }
+        if (ret == -ESTRPIPE) {
+          do {
+            snd_pcm_wait(m_pcm_handle, 10);
+            ret = snd_pcm_resume(m_pcm_handle);
+          } while (ret == -EAGAIN);
+        }
+        if (ret < 0)
+          ret = snd_pcm_prepare(m_pcm_handle);
+        if (ret < 0)
+          return;
+        continue;
+      }
+      sample_buf += ret * 4;
+      sample_len -= ret;
+    }
+  }
+
+
+  const char* ADR_CALL
+  ALSAAudioDevice::getName() {
+    return "alsa";
+  }
+
+}

diff -ur audiere/examples/wxPlayer/DeviceFrame.cpp audiere-1.9.4/examples/wxPlayer/DeviceFrame.cpp
--- audiere/examples/wxPlayer/DeviceFrame.cpp 2006-02-13 14:03:17.000000000 +0800
+++ audiere-1.9.4/examples/wxPlayer/DeviceFrame.cpp 2008-11-15 14:13:11.000000000 +0800
@@ -57,7 +57,7 @@
 
 
 DeviceFrame::DeviceFrame(audiere::AudioDevicePtr device)
-: wxMDIParentFrame(0, -1, wxT("Audio Device - " + wxString(device->getName())),
+: wxMDIParentFrame(0, -1, wxT("Audio Device - " + wxString(device->getName(), wxConvUTF8)),
                    wxDefaultPosition, wxSize(400, 500))
 {
   m_device = device;
diff -ur audiere/examples/wxPlayer/MIDIDeviceDialog.h audiere-1.9.4/examples/wxPlayer/MIDIDeviceDialog.h
--- audiere/examples/wxPlayer/MIDIDeviceDialog.h 2004-07-22 10:57:09.000000000 +0800
+++ audiere-1.9.4/examples/wxPlayer/MIDIDeviceDialog.h 2008-11-15 14:13:37.000000000 +0800
@@ -15,7 +15,7 @@
   }
 
 private:
-  void MIDIDeviceDialog::OnButton(wxCommandEvent& event);
+  void OnButton(wxCommandEvent& event);
 
   wxTextCtrl* m_name;
 
diff -ur audiere/src/audiere.h audiere-1.9.4/src/audiere.h
--- audiere/src/audiere.h 2004-11-28 09:41:59.000000000 +0800
+++ audiere-1.9.4/src/audiere.h 2008-11-15 14:01:17.000000000 +0800
@@ -28,6 +28,7 @@
 
 #include <vector>
 #include <string>
+#include <cstring>
 
 #ifdef _MSC_VER
 #pragma warning(disable : 4786)
diff -ur audiere/src/debug.cpp audiere-1.9.4/src/debug.cpp
--- audiere/src/debug.cpp 2004-04-09 17:33:50.000000000 +0800
+++ audiere-1.9.4/src/debug.cpp 2008-11-15 14:01:45.000000000 +0800
@@ -4,6 +4,7 @@
 
 #include "debug.h"
 
+#include <cstdlib>
 
 namespace audiere {
 


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Audiere-users mailing list
Audiere-users@...
https://lists.sourceforge.net/lists/listinfo/audiere-users