Index: libs/libmythtv/alsaaudioinput.h
===================================================================
--- libs/libmythtv/alsaaudioinput.h	(revision 0)
+++ libs/libmythtv/alsaaudioinput.h	(revision 0)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#ifndef _ALSAAUDIOINPUT_H_
+#define _ALSAAUDIOINPUT_H_
+
+#include <alsa/asoundlib.h>
+
+#include "audioinput.h"
+
+class ALSAAudioInput : public AudioInput
+{
+public:
+    ALSAAudioInput( QString &device );
+    virtual ~ALSAAudioInput();
+    
+    int OpenDevice( int depth, int sample_rate, int channels );
+    int CloseDevice();
+    
+    int StartCapture();
+    int StopCapture();
+    
+    int GetBlockSize();
+    
+    int GetSamples(void *buffer, int num_samples);
+    int GetNumReadyBytes();
+    
+private:
+    snd_pcm_t *audio_handle;
+    int audio_channels, audio_sample_size, audio_sample_rate;
+    
+    QString device_name;
+};
+
+#endif /* _ALSAAUDIOINPUT_H_ */
Index: libs/libmythtv/ossaudioinput.h
===================================================================
--- libs/libmythtv/ossaudioinput.h	(revision 0)
+++ libs/libmythtv/ossaudioinput.h	(revision 0)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#ifndef _OSSAUDIOINPUT_H_
+#define _OSSAUDIOINPUT_H_
+
+#include "audioinput.h"
+
+class OSSAudioInput : public AudioInput
+{
+public:
+    OSSAudioInput( QString &device );
+    virtual ~OSSAudioInput();
+    
+    int OpenDevice( int depth, int sample_rate, int channels );
+    int CloseDevice();
+    
+    int StartCapture();
+    int StopCapture();
+    
+    int GetBlockSize();
+    
+    int GetSamples(void *buffer, int num_samples);
+    int GetNumReadyBytes();
+    
+private:
+    int audio_fd;
+    int audio_channels, audio_sample_size, audio_sample_rate;
+    
+    QString device_name;
+};
+
+#endif /* _OSSAUDIOINPUT_H_ */
Index: libs/libmythtv/NuppelVideoRecorder.cpp
===================================================================
--- libs/libmythtv/NuppelVideoRecorder.cpp	(revision 13396)
+++ libs/libmythtv/NuppelVideoRecorder.cpp	(working copy)
@@ -17,6 +17,8 @@
 
 #include <qstringlist.h>
 
+#include "audioinput.h"
+
 #include <iostream>
 using namespace std;
 
@@ -113,7 +115,7 @@
     audiobytes = 0;
     audio_bits = 16;
     audio_channels = 2;
-    audio_samplerate = 44100;
+    audio_samplerate = 48000;
     audio_bytes_per_sample = audio_channels * audio_bits / 8;
 
     picture_format = PIX_FMT_YUV420P;
@@ -626,8 +628,9 @@
 
 int NuppelVideoRecorder::AudioInit(bool skipdevice)
 {
-    int afmt, afd;
-    int frag, blocksize = 4096;
+    AudioInput *audio_device;
+   
+    int blocksize = 256;
     int tmp;
 
     if (!skipdevice)
@@ -642,57 +645,42 @@
 
         return 1;
 #else
-        if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
+        audio_device = AudioInput::CreateDevice(audiodevice);
+        if (NULL == audio_device)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Cannot open DSP '%1'")
-                    .arg(audiodevice));
-            perror("open");
+            VERBOSE(VB_IMPORTANT, 
+                    LOC_ERR + "AudioInit: Unable to create device");
             return 1;
         }
- 
-        fcntl(afd, F_SETFL, fcntl(afd, F_GETFL) & ~O_NONBLOCK);
- 
-        //ioctl(afd, SNDCTL_DSP_RESET, 0);
-   
-        frag = (8 << 16) | (10); //8 buffers, 1024 bytes each
-        ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &frag);
- 
-        afmt = AFMT_S16_LE;
-        ioctl(afd, SNDCTL_DSP_SETFMT, &afmt);
-        if (afmt != AFMT_S16_LE) 
+        
+        if (-1 == audio_device->OpenDevice(audio_bits, 
+                                           audio_samplerate, 
+                                           audio_channels))
         {
-            close(afd);
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get 16 bit DSP");
+            delete audio_device;
+            VERBOSE(VB_IMPORTANT, 
+                    LOC_ERR + "AudioInit: Unable to open device");
             return 1;
         }
-
-        if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
-            ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
-            ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
+        
+        blocksize = audio_device->GetBlockSize();
+        
+        delete audio_device;
+        
+        if (-1 == blocksize)
         {
-            close(afd);
-            QString msg = LOC_ERR +
-                QString("AudioInit(): %1 : error setting audio input device"
-                        " to %2kHz/%3bits/%4channel").arg(audiodevice).
-                arg(audio_samplerate).arg(audio_bits).arg(audio_channels);
-            VERBOSE(VB_IMPORTANT, msg);
-            return 1;
+            VERBOSE(VB_IMPORTANT, 
+                    LOC_ERR + "AudioInit: Unable to determine block size,"
+                    "using default 1024 bytes");
+            blocksize = 1024;
         }
-
-        if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize)) 
-        {
-            close(afd);
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "AudioInit(): Can't get DSP blocksize");
-            return(1);
-        }
-
-        close(afd);
+        
+        VERBOSE(VB_IMPORTANT, 
+                LOC + QString("AudioInit: Using buffer size of %1 bytes")
+                .arg(blocksize));
 #endif
     }
 
-    audio_bytes_per_sample = audio_channels * audio_bits / 8;
-    blocksize *= 4;
-
     audio_buffer_size = blocksize;
 
     if (compressaudio)
@@ -2195,84 +2183,48 @@
 
 void NuppelVideoRecorder::doAudioThread(void)
 {
+    AudioInput *audio_device;
+    int act = 0, lastread = 0;
+    unsigned char *buffer;
+    struct timeval anow;
+    
 #if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
     VERBOSE(VB_IMPORTANT, LOC +
             QString("doAudioThread() This Unix doesn't support"
                     " device files for audio access. Skipping"));
     return;
 #else
-    int afmt = 0, trigger = 0;
-    int afd = 0, act = 0, lastread = 0;
-    int frag = 0, blocksize = 0;
-    unsigned char *buffer;
-    audio_buf_info ispace;
-    struct timeval anow;
-
-    act_audio_sample = 0;
-
-    if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK))) 
+    
+    audio_device = AudioInput::CreateDevice(audiodevice);
+    if (NULL == audio_device)
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Cannot open DSP '%1', exiting").
-                arg(audiodevice));
-        perror("open");
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to create device");
         return;
     }
-
-    fcntl(afd, F_SETFL, fcntl(afd, F_GETFL) & ~O_NONBLOCK);
-    //ioctl(afd, SNDCTL_DSP_RESET, 0);
-
-    frag = (8 << 16) | (10); //8 buffers, 1024 bytes each
-    ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &frag);
-
-    afmt = AFMT_S16_LE;
-    ioctl(afd, SNDCTL_DSP_SETFMT, &afmt);
-    if (afmt != AFMT_S16_LE) 
+    
+    if (-1 == audio_device->OpenDevice(audio_bits, 
+                                       audio_samplerate, 
+                                       audio_channels))
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get 16 bit DSP, exiting");
-        close(afd);
+        delete audio_device;
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to open device");
         return;
     }
 
-    if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
-        ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
-        ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + QString(" %1: error setting audio input device to "
-                                      "%2 kHz/%3 bits/%4 channel").
-                arg(audiodevice).arg(audio_samplerate).
-                arg(audio_bits).arg(audio_channels));
-        close(afd);
-        return;
-    }
-
     audio_bytes_per_sample = audio_channels * audio_bits / 8;
 
-    if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE,  &blocksize)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get DSP blocksize, exiting");
-        close(afd);
-        return;
-    }
-
-    blocksize *= 4;  // allways read 4*blocksize
-
-    if (blocksize != audio_buffer_size) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC +
-                QString("Warning, audio blocksize = '%1' while audio_buffer_size='%2'").
-                arg(blocksize).arg(audio_buffer_size));
-    }
-
     buffer = new unsigned char[audio_buffer_size];
 
-    /* trigger record */
-    trigger = 0;
-    ioctl(afd,SNDCTL_DSP_SETTRIGGER,&trigger);
-
-    trigger = PCM_ENABLE_INPUT;
-    ioctl(afd,SNDCTL_DSP_SETTRIGGER,&trigger);
-
     audiopaused = false;
+    
+    if (-1 == audio_device->StartCapture())
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to start capture");
+        delete audio_device;
+        return;
+    }
+    
+    VERBOSE(VB_IMPORTANT, LOC + "Audio: Successfully opened & started device");    
     while (childrenLive) 
     {
         if (request_pause)
@@ -2288,27 +2240,38 @@
         }
         audiopaused = false;
 
-        if (audio_buffer_size != (lastread = read(afd, buffer,
-                                                  audio_buffer_size))) 
+        if (audio_buffer_size != 
+                (lastread = audio_device->GetSamples(buffer, 
+                                                     audio_buffer_size))) 
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR +
                     QString("Only read %1 bytes of %2 bytes from '%3").
                     arg(lastread).arg(audio_buffer_size).arg(audiodevice));
             perror("read audio");
+            
+            // TODO: Potentially evil!!!
+            if (0 > lastread)
+            {
+                continue;
+            }
+            else if (0 == lastread)
+            {
+                continue;
+            }
         }
-
+            
         /* record the current time */
         /* Don't assume that the sound device's record buffer is empty
            (like we used to.) Measure to see how much stuff is in there,
            and correct for it when calculating the timestamp */
         gettimeofday(&anow, &tzone);
-        ioctl( afd, SNDCTL_DSP_GETISPACE, &ispace );
 
         act = act_audio_buffer;
 
         if (!audiobuffer[act]->freeToBuffer) 
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Ran out of free AUDIO buffers :-(");
+            VERBOSE(VB_IMPORTANT, 
+                    LOC_ERR + "Audio: Ran out of free AUDIO buffers :-(");
             act_audio_sample++;
             continue;
         }
@@ -2323,7 +2286,7 @@
            audio chunk. So, subtract off the length of the chunk
            and the length of audio still in the capture buffer. */
         audiobuffer[act]->timecode -= (int)( 
-                (ispace.fragments * ispace.fragsize + audio_buffer_size)
+                (audio_device->GetNumReadyBytes() + audio_buffer_size)
                  * 1000.0 / (audio_samplerate * audio_bytes_per_sample));
 
         memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size);
@@ -2338,7 +2301,7 @@
     }
 
     delete [] buffer;
-    close(afd);
+    delete audio_device;
 #endif
 }
 
Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 13396)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -365,8 +365,21 @@
 
     # Simple NuppelVideo Recorder
     using_ffmpeg_threads:DEFINES += USING_FFMPEG_THREADS
-    HEADERS += NuppelVideoRecorder.h       fifowriter.h
-    SOURCES += NuppelVideoRecorder.cpp     fifowriter.cpp
+    HEADERS += NuppelVideoRecorder.h       fifowriter.h     audioinput.h
+    SOURCES += NuppelVideoRecorder.cpp     fifowriter.cpp   audioinput.cpp
+    
+    using_oss {
+        DEFINES += USING_OSS
+        HEADERS += ossaudioinput.h
+        SOURCES += ossaudioinput.cpp
+    }
+    
+    using_alsa {
+        DEFINES += USE_ALSA
+        HEADERS += alsaaudioinput.h
+        SOURCES += alsaaudioinput.cpp
+        LIBS += $$ALSA_LIBS
+    }
 
     # Support for Video4Linux devices
     using_v4l {
Index: libs/libmythtv/audioinput.cpp
===================================================================
--- libs/libmythtv/audioinput.cpp	(revision 0)
+++ libs/libmythtv/audioinput.cpp	(revision 0)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#include "audioinput.h"
+#include "mythcontext.h"
+
+#ifdef USE_ALSA
+#include "alsaaudioinput.h"
+#endif
+
+#ifdef USING_OSS
+#include "ossaudioinput.h"
+#endif
+
+AudioInput * AudioInput::CreateDevice(QString device)
+{
+    AudioInput *dev = NULL;
+
+    if (device.startsWith("ALSA:"))
+    {
+#ifdef USE_ALSA
+        dev = new ALSAAudioInput(device.remove(0,5));
+#else
+        VERBOSE(VB_AUDIO, "ALSA input support not available");
+#endif
+    }
+    else
+    {
+#ifdef USING_OSS
+        dev = new OSSAudioInput(device);
+#else
+        VERBOSE(VB_AUDIO, "OSS input support not available");
+#endif
+    }   
+    
+    return dev;
+}
+
Index: libs/libmythtv/ossaudioinput.cpp
===================================================================
--- libs/libmythtv/ossaudioinput.cpp	(revision 0)
+++ libs/libmythtv/ossaudioinput.cpp	(revision 0)
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ * Based upon OSS code from NuppelVideoRecorder.cpp
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include "mythconfig.h"
+#ifdef HAVE_SYS_SOUNDCARD_H
+    #include <sys/soundcard.h>
+#elif HAVE_SOUNDCARD_H
+    #include <soundcard.h>
+#endif
+
+#include "ossaudioinput.h"
+#include "mythcontext.h"
+
+#define LOC     QString("OSSAudioInput: ")
+
+OSSAudioInput::OSSAudioInput( QString &device )
+{
+    audio_fd = 0;
+    
+    audio_channels = 0;
+    audio_sample_size = 0;
+    audio_sample_rate = 0;
+    
+    device_name = device;
+}
+
+OSSAudioInput::~OSSAudioInput()
+{
+    CloseDevice();
+}
+
+int OSSAudioInput::OpenDevice( int sample_size, int sample_rate, int channels )
+{
+    int retval = 0;
+    int format;
+    int trigger;
+    
+    // Open the device
+    retval = open(device_name.ascii(), O_RDONLY | O_NONBLOCK);
+    if (0 <= retval)
+    {
+        audio_fd = 0;
+        VERBOSE(VB_AUDIO, QString(LOC + "Cannot open DSP '%1', exiting")
+                          .arg(device_name));
+    }
+    
+    if (0 <= retval)
+    {
+        audio_fd = retval;
+
+        // Disable trigger
+        trigger = 0;
+        retval = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &trigger);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Can't stop trigger, exiting");
+        }
+
+    }
+    
+    if (0 <= retval)
+    {
+        // Set blocking IO
+        retval = fcntl(audio_fd, F_SETFL, 
+                       fcntl(audio_fd, F_GETFL) & ~O_NONBLOCK);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to set blocking, exiting");
+        }
+    }
+    
+    if (0 <= retval)
+    {
+        // Set format
+        format = AFMT_S16_LE;
+        retval = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Can't get 16 bit DSP, exiting");
+        }
+    }
+    
+    if (0 <= retval)
+    {
+        // Set sample size
+        audio_sample_size = sample_size;
+        retval = ioctl(audio_fd, SNDCTL_DSP_SAMPLESIZE, &audio_sample_size);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to set sample size");
+        }
+    }
+    
+    if (0 <= retval)
+    {       
+        // Set channels
+        audio_channels = channels;
+        retval = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &audio_channels);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to set number of channels");
+        }
+    }
+    
+    if (0 <= retval)
+    {
+        // Set sample rate
+        audio_sample_rate = sample_rate;
+        retval = ioctl(audio_fd, SNDCTL_DSP_SPEED, &audio_sample_rate);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to set sample rate");
+        }
+    }
+    
+    if (0 > retval)
+    {
+        CloseDevice();
+    }
+    else
+    {
+        VERBOSE(VB_AUDIO, LOC + "Opened device" + device_name);
+    }
+    
+    return retval;
+}
+
+int OSSAudioInput::CloseDevice()
+{
+    if (0 < audio_fd)
+    {
+        close(audio_fd);
+        audio_fd = 0;
+        
+        VERBOSE(VB_AUDIO, LOC + "Closed device" + device_name);
+    }   
+    
+    return 0;
+}
+
+int OSSAudioInput::StartCapture()
+{
+    int retval = 0;
+    int trigger;
+    
+    if (0 == audio_fd)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        trigger = PCM_ENABLE_INPUT;
+        retval = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &trigger);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to start capture");
+        }
+        else
+        {
+            VERBOSE(VB_AUDIO, LOC + "Started capture on " + device_name);
+        }
+    }
+    
+    return retval;
+}
+
+int OSSAudioInput::StopCapture()
+{
+    return -1;
+}
+
+int OSSAudioInput::GetBlockSize()
+{
+    int retval = 0;
+    int fragment_size;
+    
+    if (0 == audio_fd)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        retval = ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size);
+    }
+
+    if (0 <= retval)
+    {
+        retval = fragment_size;
+    }
+    
+    return retval;
+}
+
+int OSSAudioInput::GetSamples(void *buffer, int num_bytes)
+{
+    int retval = 0;
+
+
+    if (0 != (num_bytes % ((audio_sample_size * audio_channels) / 8)))
+    {
+        VERBOSE(VB_AUDIO, LOC + "Invalid num_bytes");
+        retval = -1;
+    }
+
+    if (0 <= retval)
+    {
+        retval = read(audio_fd, buffer, num_bytes);
+    }
+    
+    return retval;
+}
+
+int OSSAudioInput::GetNumReadyBytes()
+{
+    int retval = 0;
+    audio_buf_info ispace;
+    
+    if (0 == audio_fd)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        retval = ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &ispace);
+        if (0 > retval)
+        {
+            VERBOSE(VB_AUDIO, LOC + "Unable to get ready bytes");
+        }
+    }
+
+    if (0 <= retval)
+    {
+        retval = ispace.bytes;
+    }
+    
+    return retval;
+}
Index: libs/libmythtv/audioinput.h
===================================================================
--- libs/libmythtv/audioinput.h	(revision 0)
+++ libs/libmythtv/audioinput.h	(revision 0)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#ifndef _AUDIOINPUT_H_
+#define _AUDIOINPUT_H_
+
+#include <qstring.h>
+
+class AudioInput 
+{
+public:
+
+    // Factory function
+    static AudioInput * CreateDevice( QString device );
+
+    virtual ~AudioInput() {};
+
+    virtual int OpenDevice( int depth, int sample_rate, int channels ) =0;
+    virtual int CloseDevice() =0;
+    
+    virtual int StartCapture() =0;
+    virtual int StopCapture() =0;
+    
+    virtual int GetBlockSize() =0;
+    
+    virtual int GetSamples(void *buffer, int num_samples) =0;
+    virtual int GetNumReadyBytes() =0;
+};
+    
+
+#endif /* _AUDIOINPUT_H_ */
+
Index: libs/libmythtv/videosource.cpp
===================================================================
--- libs/libmythtv/videosource.cpp	(revision 13396)
+++ libs/libmythtv/videosource.cpp	(working copy)
@@ -774,7 +774,7 @@
 {
   public:
     AudioDevice(const CaptureCard &parent) :
-        PathSetting(this, true),
+        PathSetting(this, false),
         CaptureCardDBStorage(this, parent, "audiodevice")
     {
         setLabel(QObject::tr("Audio device"));
Index: libs/libmythtv/alsaaudioinput.cpp
===================================================================
--- libs/libmythtv/alsaaudioinput.cpp	(revision 0)
+++ libs/libmythtv/alsaaudioinput.cpp	(revision 0)
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2007  Anand K. Mistry
+ *
+ * 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 Street, Fifth Floor, Boston, MA 
+ * 02110-1301, USA.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <iostream>
+
+#include "mythconfig.h"
+
+#include "alsaaudioinput.h"
+#include "mythcontext.h"
+
+#define LOC     QString("ALSAAudioInput: ")
+
+ALSAAudioInput::ALSAAudioInput( QString &device )
+{
+    audio_handle = NULL;
+    
+    audio_channels = 0;
+    audio_sample_size = 0;
+    audio_sample_rate = 0;
+    
+    device_name = device;
+}
+
+ALSAAudioInput::~ALSAAudioInput()
+{
+    CloseDevice();
+}
+
+int ALSAAudioInput::OpenDevice( int sample_size, int sample_rate, int channels )
+{
+    int retval = 0;
+    snd_pcm_hw_params_t * hw_params;
+    
+    // Open the device
+    retval = snd_pcm_open(&audio_handle, 
+                          device_name.ascii(), SND_PCM_STREAM_CAPTURE, 0);
+    if (0 > retval) {
+        audio_handle = NULL;
+        VERBOSE(VB_AUDIO, 
+                QString(LOC + "Cannot open ALSA '%1', exiting")
+                .arg(device_name));
+    }
+    
+    if (0 <= retval)
+    {
+        // Allocate hw params structure
+        retval = snd_pcm_hw_params_malloc(&hw_params);
+    }
+    
+    if (0 <= retval)
+    {
+        // Initialize hw params
+        retval = snd_pcm_hw_params_any(audio_handle, hw_params);
+    }
+    
+    if (0 <= retval)
+    {
+        // Set interleaved access
+        retval = snd_pcm_hw_params_set_access(audio_handle, 
+                                              hw_params, 
+                                              SND_PCM_ACCESS_RW_INTERLEAVED);
+    }
+    
+    if (0 <= retval)
+    {
+        // Set format
+        retval = snd_pcm_hw_params_set_format(audio_handle, 
+                                              hw_params, 
+                                              SND_PCM_FORMAT_S16_LE);
+    }
+    
+    if (0 <= retval)
+    {
+        // Set sampling rate
+        audio_sample_rate = sample_rate;
+        retval = snd_pcm_hw_params_set_rate(audio_handle, 
+                                            hw_params, 
+                                            audio_sample_rate, 0);
+    }
+    
+    if (0 <= retval)
+    {
+        // Set channels
+        audio_channels = channels;
+        retval = snd_pcm_hw_params_set_channels(audio_handle, 
+                                                hw_params, 
+                                                audio_channels);
+    }
+    
+    if (0 <= retval)
+    {
+        // Set sample size
+        audio_sample_size = sample_size;
+    
+        // Apply settings
+        retval = snd_pcm_hw_params(audio_handle, hw_params);
+    }
+    
+    snd_pcm_hw_params_free(hw_params);
+    
+    if (0 <= retval)
+    {
+        VERBOSE(VB_AUDIO, LOC + "Opened device " + device_name);
+    }
+    
+    return retval;
+}
+
+int ALSAAudioInput::CloseDevice()
+{
+    if (0 < audio_handle)
+    {
+        snd_pcm_close(audio_handle);
+        audio_handle = 0;
+        
+        VERBOSE(VB_AUDIO, LOC + "Closed device" + device_name);
+    }   
+    
+    return 0;
+}
+
+int ALSAAudioInput::StartCapture()
+{
+    int retval = 0;
+    
+    if (0 == audio_handle)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        retval = snd_pcm_prepare(audio_handle);
+    }
+    
+    if (0 <= retval)
+    {
+        VERBOSE(VB_AUDIO, LOC + "Started capture on " + device_name);
+    }
+    else
+    {
+        VERBOSE(VB_AUDIO, LOC + "Unable to start capture");
+    }
+    
+    return retval;
+}
+
+int ALSAAudioInput::StopCapture()
+{
+    return -1;
+}
+
+int ALSAAudioInput::GetBlockSize()
+{
+    int retval = 0;
+    snd_pcm_uframes_t buffer_size, period_size;
+    
+    if (NULL == audio_handle)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        retval = snd_pcm_get_params(audio_handle, &buffer_size, &period_size);
+    }
+    
+    if (0 <= retval)
+    {
+        retval = (period_size * audio_channels * audio_sample_size) / 8;
+    }
+    
+    return retval; 
+}
+
+int ALSAAudioInput::GetSamples(void *buffer, int num_bytes)
+{
+    int retval = 0;
+    int frame_size;
+    
+    frame_size = (audio_sample_size * audio_channels) / 8;
+
+    if (0 != (num_bytes % frame_size))
+    {
+         VERBOSE(VB_AUDIO, LOC + "Invalid num_bytes");
+         retval = -1;
+    }
+    
+    if (0 <= retval)
+    {    
+        retval = snd_pcm_readi(audio_handle, buffer, num_bytes/frame_size);
+        if (0 > retval)
+        {
+            retval = snd_pcm_recover(audio_handle, retval, 1);
+        }
+    }
+    
+    if (0 <= retval)
+    {
+        retval *= frame_size;
+    }
+    
+    return retval;
+}
+
+int ALSAAudioInput::GetNumReadyBytes()
+{
+    int retval = 0;
+    snd_pcm_sframes_t delay;
+    
+    if (NULL == audio_handle)
+    {
+        retval = -1;
+    }
+    
+    if (0 <= retval)
+    {
+        retval = snd_pcm_delay(audio_handle, &delay);
+    }
+    
+    if (0 <= retval)
+    {
+        retval = (delay * audio_channels * audio_sample_size) / 8;
+    }
+    
+    return retval;
+}
+
