Ticket #3405: mythtv_alsa-2.patch

File mythtv_alsa-2.patch, 29.0 KB (added by amistry@…, 17 years ago)

Further adhere to coding standards

  • libs/libmythtv/alsaaudioinput.h

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 * 02110-1301, USA.
     18 */
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
     20
     21#ifndef _ALSAAUDIOINPUT_H_
     22#define _ALSAAUDIOINPUT_H_
     23
     24#include <alsa/asoundlib.h>
     25
     26#include "audioinput.h"
     27
     28class ALSAAudioInput : public AudioInput
     29{
     30public:
     31    ALSAAudioInput(QString &device);
     32    virtual ~ALSAAudioInput();
     33   
     34    int OpenDevice(int depth, int sample_rate, int channels);
     35    int CloseDevice();
     36   
     37    int StartCapture();
     38    int StopCapture();
     39   
     40    int GetBlockSize();
     41   
     42    int GetSamples(void *buffer, int num_samples);
     43    int GetNumReadyBytes();
     44   
     45private:
     46    snd_pcm_t *m_audio_handle;
     47    int m_audio_channels, m_audio_sample_size, m_audio_sample_rate;
     48   
     49    QString m_device_name;
     50};
     51
     52#endif /* _ALSAAUDIOINPUT_H_ */
     53
  • libs/libmythtv/ossaudioinput.h

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 * 02110-1301, USA.
     18 */
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
     20
     21#ifndef _OSSAUDIOINPUT_H_
     22#define _OSSAUDIOINPUT_H_
     23
     24#include "audioinput.h"
     25
     26class OSSAudioInput : public AudioInput
     27{
     28public:
     29    OSSAudioInput(QString &device);
     30    virtual ~OSSAudioInput();
     31
     32    int OpenDevice(int depth, int sample_rate, int channels);
     33    int CloseDevice();
     34
     35    int StartCapture();
     36    int StopCapture();
     37
     38    int GetBlockSize();
     39
     40    int GetSamples(void *buffer, int num_samples);
     41    int GetNumReadyBytes();
     42
     43private:
     44    int m_audio_fd;
     45    int m_audio_channels, m_audio_sample_size, m_audio_sample_rate;
     46
     47    QString m_device_name;
     48};
     49
     50#endif /* _OSSAUDIOINPUT_H_ */
     51
  • libs/libmythtv/NuppelVideoRecorder.cpp

     
    1717
    1818#include <qstringlist.h>
    1919
     20#include "audioinput.h"
     21
    2022#include <iostream>
     23#include <memory>
    2124using namespace std;
    2225
    2326#include "mythcontext.h"
     
    626629
    627630int NuppelVideoRecorder::AudioInit(bool skipdevice)
    628631{
    629     int afmt, afd;
    630     int frag, blocksize = 4096;
     632    auto_ptr<AudioInput> audio_device;
     633   
     634    int blocksize = 256;
    631635    int tmp;
    632636
    633637    if (!skipdevice)
     
    642646
    643647        return 1;
    644648#else
    645         if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
     649        audio_device = auto_ptr<AudioInput>
     650                            (AudioInput::CreateDevice(audiodevice));
     651        if (NULL == audio_device.get())
    646652        {
    647             VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Cannot open DSP '%1'")
    648                     .arg(audiodevice));
    649             perror("open");
     653            VERBOSE(VB_IMPORTANT,
     654                    LOC_ERR + "AudioInit: Unable to create device");
    650655            return 1;
    651656        }
    652  
    653         fcntl(afd, F_SETFL, fcntl(afd, F_GETFL) & ~O_NONBLOCK);
    654  
    655         //ioctl(afd, SNDCTL_DSP_RESET, 0);
    656    
    657         frag = (8 << 16) | (10); //8 buffers, 1024 bytes each
    658         ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &frag);
    659  
    660         afmt = AFMT_S16_LE;
    661         ioctl(afd, SNDCTL_DSP_SETFMT, &afmt);
    662         if (afmt != AFMT_S16_LE)
     657       
     658        if (-1 == audio_device->OpenDevice(audio_bits,
     659                                           audio_samplerate,
     660                                           audio_channels))
    663661        {
    664             close(afd);
    665             VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get 16 bit DSP");
     662            VERBOSE(VB_IMPORTANT,
     663                    LOC_ERR + "AudioInit: Unable to open device");
    666664            return 1;
    667665        }
    668 
    669         if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
    670             ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
    671             ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
     666       
     667        blocksize = audio_device->GetBlockSize();
     668       
     669        if (-1 == blocksize)
    672670        {
    673             close(afd);
    674             QString msg = LOC_ERR +
    675                 QString("AudioInit(): %1 : error setting audio input device"
    676                         " to %2kHz/%3bits/%4channel").arg(audiodevice).
    677                 arg(audio_samplerate).arg(audio_bits).arg(audio_channels);
    678             VERBOSE(VB_IMPORTANT, msg);
    679             return 1;
     671            VERBOSE(VB_IMPORTANT,
     672                    LOC_ERR + "AudioInit: Unable to determine block size,"
     673                    "using default 1024 bytes");
     674            blocksize = 1024;
    680675        }
    681 
    682         if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
    683         {
    684             close(afd);
    685             VERBOSE(VB_IMPORTANT, LOC_ERR + "AudioInit(): Can't get DSP blocksize");
    686             return(1);
    687         }
    688 
    689         close(afd);
     676       
     677        VERBOSE(VB_IMPORTANT,
     678                LOC + QString("AudioInit: Using buffer size of %1 bytes")
     679                .arg(blocksize));
    690680#endif
    691681    }
    692682
    693     audio_bytes_per_sample = audio_channels * audio_bits / 8;
    694     blocksize *= 4;
    695 
    696683    audio_buffer_size = blocksize;
    697684
    698685    if (compressaudio)
     
    21952182
    21962183void NuppelVideoRecorder::doAudioThread(void)
    21972184{
     2185    auto_ptr<AudioInput> audio_device;
     2186    int act = 0, lastread = 0;
     2187    unsigned char *buffer;
     2188    struct timeval anow;
     2189   
    21982190#if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
    21992191    VERBOSE(VB_IMPORTANT, LOC +
    22002192            QString("doAudioThread() This Unix doesn't support"
    22012193                    " device files for audio access. Skipping"));
    22022194    return;
    22032195#else
    2204     int afmt = 0, trigger = 0;
    2205     int afd = 0, act = 0, lastread = 0;
    2206     int frag = 0, blocksize = 0;
    2207     unsigned char *buffer;
    2208     audio_buf_info ispace;
    2209     struct timeval anow;
    2210 
    2211     act_audio_sample = 0;
    2212 
    2213     if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
     2196   
     2197    audio_device = auto_ptr<AudioInput>(AudioInput::CreateDevice(audiodevice));
     2198    if (NULL == audio_device.get())
    22142199    {
    2215         VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Cannot open DSP '%1', exiting").
    2216                 arg(audiodevice));
    2217         perror("open");
     2200        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to create device");
    22182201        return;
    22192202    }
    2220 
    2221     fcntl(afd, F_SETFL, fcntl(afd, F_GETFL) & ~O_NONBLOCK);
    2222     //ioctl(afd, SNDCTL_DSP_RESET, 0);
    2223 
    2224     frag = (8 << 16) | (10); //8 buffers, 1024 bytes each
    2225     ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &frag);
    2226 
    2227     afmt = AFMT_S16_LE;
    2228     ioctl(afd, SNDCTL_DSP_SETFMT, &afmt);
    2229     if (afmt != AFMT_S16_LE)
     2203   
     2204    if (-1 == audio_device->OpenDevice(audio_bits,
     2205                                       audio_samplerate,
     2206                                       audio_channels))
    22302207    {
    2231         VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get 16 bit DSP, exiting");
    2232         close(afd);
     2208        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to open device");
    22332209        return;
    22342210    }
    22352211
    2236     if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
    2237         ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
    2238         ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
    2239     {
    2240         VERBOSE(VB_IMPORTANT, LOC_ERR + QString(" %1: error setting audio input device to "
    2241                                       "%2 kHz/%3 bits/%4 channel").
    2242                 arg(audiodevice).arg(audio_samplerate).
    2243                 arg(audio_bits).arg(audio_channels));
    2244         close(afd);
    2245         return;
    2246     }
    2247 
    22482212    audio_bytes_per_sample = audio_channels * audio_bits / 8;
    22492213
    2250     if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE,  &blocksize))
    2251     {
    2252         VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't get DSP blocksize, exiting");
    2253         close(afd);
    2254         return;
    2255     }
    2256 
    2257     blocksize *= 4;  // allways read 4*blocksize
    2258 
    2259     if (blocksize != audio_buffer_size)
    2260     {
    2261         VERBOSE(VB_IMPORTANT, LOC +
    2262                 QString("Warning, audio blocksize = '%1' while audio_buffer_size='%2'").
    2263                 arg(blocksize).arg(audio_buffer_size));
    2264     }
    2265 
    22662214    buffer = new unsigned char[audio_buffer_size];
    22672215
    2268     /* trigger record */
    2269     trigger = 0;
    2270     ioctl(afd,SNDCTL_DSP_SETTRIGGER,&trigger);
    2271 
    2272     trigger = PCM_ENABLE_INPUT;
    2273     ioctl(afd,SNDCTL_DSP_SETTRIGGER,&trigger);
    2274 
    22752216    audiopaused = false;
     2217   
     2218    if (-1 == audio_device->StartCapture())
     2219    {
     2220        VERBOSE(VB_IMPORTANT, LOC_ERR + "Audio: Unable to start capture");
     2221        return;
     2222    }
     2223   
     2224    VERBOSE(VB_IMPORTANT, LOC + "Audio: Successfully opened & started device");   
    22762225    while (childrenLive)
    22772226    {
    22782227        if (request_pause)
     
    22882237        }
    22892238        audiopaused = false;
    22902239
    2291         if (audio_buffer_size != (lastread = read(afd, buffer,
    2292                                                   audio_buffer_size)))
     2240        if (audio_buffer_size !=
     2241                (lastread = audio_device->GetSamples(buffer,
     2242                                                     audio_buffer_size)))
    22932243        {
    22942244            VERBOSE(VB_IMPORTANT, LOC_ERR +
    22952245                    QString("Only read %1 bytes of %2 bytes from '%3").
    22962246                    arg(lastread).arg(audio_buffer_size).arg(audiodevice));
    22972247            perror("read audio");
     2248           
     2249            // TODO: Potentially evil!!!
     2250            if (0 > lastread)
     2251            {
     2252                continue;
     2253            }
     2254            else if (0 == lastread)
     2255            {
     2256                continue;
     2257            }
    22982258        }
    22992259
    23002260        /* record the current time */
     
    23022262           (like we used to.) Measure to see how much stuff is in there,
    23032263           and correct for it when calculating the timestamp */
    23042264        gettimeofday(&anow, &tzone);
    2305         ioctl( afd, SNDCTL_DSP_GETISPACE, &ispace );
    23062265
    23072266        act = act_audio_buffer;
    23082267
    23092268        if (!audiobuffer[act]->freeToBuffer)
    23102269        {
    2311             VERBOSE(VB_IMPORTANT, LOC_ERR + "Ran out of free AUDIO buffers :-(");
     2270            VERBOSE(VB_IMPORTANT,
     2271                    LOC_ERR + "Audio: Ran out of free AUDIO buffers :-(");
    23122272            act_audio_sample++;
    23132273            continue;
    23142274        }
     
    23232283           audio chunk. So, subtract off the length of the chunk
    23242284           and the length of audio still in the capture buffer. */
    23252285        audiobuffer[act]->timecode -= (int)(
    2326                 (ispace.fragments * ispace.fragsize + audio_buffer_size)
     2286                (audio_device->GetNumReadyBytes() + audio_buffer_size)
    23272287                 * 1000.0 / (audio_samplerate * audio_bytes_per_sample));
    23282288
    23292289        memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size);
     
    23382298    }
    23392299
    23402300    delete [] buffer;
    2341     close(afd);
    23422301#endif
    23432302}
    23442303
  • libs/libmythtv/libmythtv.pro

     
    365365
    366366    # Simple NuppelVideo Recorder
    367367    using_ffmpeg_threads:DEFINES += USING_FFMPEG_THREADS
    368     HEADERS += NuppelVideoRecorder.h       fifowriter.h
    369     SOURCES += NuppelVideoRecorder.cpp     fifowriter.cpp
     368    HEADERS += NuppelVideoRecorder.h       fifowriter.h     audioinput.h
     369    SOURCES += NuppelVideoRecorder.cpp     fifowriter.cpp   audioinput.cpp
     370   
     371    using_oss {
     372        DEFINES += USING_OSS
     373        HEADERS += ossaudioinput.h
     374        SOURCES += ossaudioinput.cpp
     375    }
     376   
     377    using_alsa {
     378        DEFINES += USE_ALSA
     379        HEADERS += alsaaudioinput.h
     380        SOURCES += alsaaudioinput.cpp
     381        LIBS += $$ALSA_LIBS
     382    }
    370383
    371384    # Support for Video4Linux devices
    372385    using_v4l {
  • libs/libmythtv/audioinput.cpp

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 * 02110-1301, USA.
     18 */
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
     20
     21#include "audioinput.h"
     22#include "mythcontext.h"
     23
     24#ifdef USE_ALSA
     25#include "alsaaudioinput.h"
     26#endif
     27
     28#ifdef USING_OSS
     29#include "ossaudioinput.h"
     30#endif
     31
     32AudioInput * AudioInput::CreateDevice(QString device)
     33{
     34    AudioInput *dev = NULL;
     35
     36    if (device.startsWith("ALSA:"))
     37    {
     38#ifdef USE_ALSA
     39        dev = new ALSAAudioInput(device.remove(0,5));
     40#else
     41        VERBOSE(VB_AUDIO, "ALSA input support not available");
     42#endif
     43    }
     44    else
     45    {
     46#ifdef USING_OSS
     47        dev = new OSSAudioInput(device);
     48#else
     49        VERBOSE(VB_AUDIO, "OSS input support not available");
     50#endif
     51    }   
     52   
     53    return dev;
     54}
     55
  • libs/libmythtv/ossaudioinput.cpp

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 * Based upon OSS code from NuppelVideoRecorder.cpp
     4 *
     5 * This program is free software; you can redistribute it and/or
     6 * modify it under the terms of the GNU General Public License
     7 * as published by the Free Software Foundation; either version 2
     8 * of the License, or (at your option) any later version.
     9 *
     10 * This program is distributed in the hope that it will be useful,
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 * GNU General Public License for more details.
     14 *
     15 * You should have received a copy of the GNU General Public License
     16 * along with this program; if not, write to the Free Software
     17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     18 * 02110-1301, USA.
     19 */
     20/* vim: set expandtab tabstop=4 shiftwidth=4: */
     21
     22#include <fcntl.h>
     23#include <unistd.h>
     24#include <sys/types.h>
     25#include <sys/stat.h>
     26#include <sys/ioctl.h>
     27
     28#include "mythconfig.h"
     29#ifdef HAVE_SYS_SOUNDCARD_H
     30    #include <sys/soundcard.h>
     31#elif HAVE_SOUNDCARD_H
     32    #include <soundcard.h>
     33#endif
     34
     35#include "ossaudioinput.h"
     36#include "mythcontext.h"
     37
     38#define LOC     QString("OSSAudioInput: ")
     39
     40OSSAudioInput::OSSAudioInput(QString &device)
     41{
     42    m_audio_fd = 0;
     43   
     44    m_audio_channels = 0;
     45    m_audio_sample_size = 0;
     46    m_audio_sample_rate = 0;
     47   
     48    m_device_name = device;
     49}
     50
     51OSSAudioInput::~OSSAudioInput()
     52{
     53    CloseDevice();
     54}
     55
     56int OSSAudioInput::OpenDevice(int sample_size, int sample_rate, int channels)
     57{
     58    int retval = 0;
     59    int format;
     60    int trigger;
     61   
     62    // Open the device
     63    retval = open(m_device_name.ascii(), O_RDONLY | O_NONBLOCK);
     64    if (0 <= retval)
     65    {
     66        m_audio_fd = 0;
     67        VERBOSE(VB_AUDIO, QString(LOC + "Cannot open DSP '%1', exiting")
     68                          .arg(m_device_name));
     69    }
     70   
     71    if (0 <= retval)
     72    {
     73        m_audio_fd = retval;
     74
     75        // Disable trigger
     76        trigger = 0;
     77        retval = ioctl(m_audio_fd, SNDCTL_DSP_SETTRIGGER, &trigger);
     78        if (0 > retval)
     79        {
     80            VERBOSE(VB_AUDIO, LOC + "Can't stop trigger, exiting");
     81        }
     82
     83    }
     84   
     85    if (0 <= retval)
     86    {
     87        // Set blocking IO
     88        retval = fcntl(m_audio_fd, F_SETFL,
     89                       fcntl(m_audio_fd, F_GETFL) & ~O_NONBLOCK);
     90        if (0 > retval)
     91        {
     92            VERBOSE(VB_AUDIO, LOC + "Unable to set blocking, exiting");
     93        }
     94    }
     95   
     96    if (0 <= retval)
     97    {
     98        // Set format
     99        format = AFMT_S16_LE;
     100        retval = ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &format);
     101        if (0 > retval)
     102        {
     103            VERBOSE(VB_AUDIO, LOC + "Can't get 16 bit DSP, exiting");
     104        }
     105    }
     106   
     107    if (0 <= retval)
     108    {
     109        // Set sample size
     110        m_audio_sample_size = sample_size;
     111        retval = ioctl(m_audio_fd, SNDCTL_DSP_SAMPLESIZE, &m_audio_sample_size);
     112        if (0 > retval)
     113        {
     114            VERBOSE(VB_AUDIO, LOC + "Unable to set sample size");
     115        }
     116    }
     117   
     118    if (0 <= retval)
     119    {       
     120        // Set channels
     121        m_audio_channels = channels;
     122        retval = ioctl(m_audio_fd, SNDCTL_DSP_CHANNELS, &m_audio_channels);
     123        if (0 > retval)
     124        {
     125            VERBOSE(VB_AUDIO, LOC + "Unable to set number of channels");
     126        }
     127    }
     128   
     129    if (0 <= retval)
     130    {
     131        // Set sample rate
     132        m_audio_sample_rate = sample_rate;
     133        retval = ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &m_audio_sample_rate);
     134        if (0 > retval)
     135        {
     136            VERBOSE(VB_AUDIO, LOC + "Unable to set sample rate");
     137        }
     138    }
     139   
     140    if (0 > retval)
     141    {
     142        CloseDevice();
     143    }
     144    else
     145    {
     146        VERBOSE(VB_AUDIO, LOC + "Opened device" + m_device_name);
     147    }
     148   
     149    return retval;
     150}
     151
     152int OSSAudioInput::CloseDevice()
     153{
     154    if (0 < m_audio_fd)
     155    {
     156        close(m_audio_fd);
     157        m_audio_fd = 0;
     158       
     159        VERBOSE(VB_AUDIO, LOC + "Closed device" + m_device_name);
     160    }   
     161   
     162    return 0;
     163}
     164
     165int OSSAudioInput::StartCapture()
     166{
     167    int retval = 0;
     168    int trigger;
     169   
     170    if (0 == m_audio_fd)
     171    {
     172        retval = -1;
     173    }
     174   
     175    if (0 <= retval)
     176    {
     177        trigger = PCM_ENABLE_INPUT;
     178        retval = ioctl(m_audio_fd, SNDCTL_DSP_SETTRIGGER, &trigger);
     179        if (0 > retval)
     180        {
     181            VERBOSE(VB_AUDIO, LOC + "Unable to start capture");
     182        }
     183        else
     184        {
     185            VERBOSE(VB_AUDIO, LOC + "Started capture on " + m_device_name);
     186        }
     187    }
     188   
     189    return retval;
     190}
     191
     192int OSSAudioInput::StopCapture()
     193{
     194    return -1;
     195}
     196
     197int OSSAudioInput::GetBlockSize()
     198{
     199    int retval = 0;
     200    int fragment_size;
     201   
     202    if (0 == m_audio_fd)
     203    {
     204        retval = -1;
     205    }
     206   
     207    if (0 <= retval)
     208    {
     209        retval = ioctl(m_audio_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size);
     210    }
     211
     212    if (0 <= retval)
     213    {
     214        retval = fragment_size;
     215    }
     216   
     217    return retval;
     218}
     219
     220int OSSAudioInput::GetSamples(void *buffer, int num_bytes)
     221{
     222    int retval = 0;
     223
     224
     225    if (0 != (num_bytes % ((m_audio_sample_size * m_audio_channels) / 8)))
     226    {
     227        VERBOSE(VB_AUDIO, LOC + "Invalid num_bytes");
     228        retval = -1;
     229    }
     230
     231    if (0 <= retval)
     232    {
     233        retval = read(m_audio_fd, buffer, num_bytes);
     234    }
     235   
     236    return retval;
     237}
     238
     239int OSSAudioInput::GetNumReadyBytes()
     240{
     241    int retval = 0;
     242    audio_buf_info ispace;
     243   
     244    if (0 == m_audio_fd)
     245    {
     246        retval = -1;
     247    }
     248   
     249    if (0 <= retval)
     250    {
     251        retval = ioctl(m_audio_fd, SNDCTL_DSP_GETISPACE, &ispace);
     252        if (0 > retval)
     253        {
     254            VERBOSE(VB_AUDIO, LOC + "Unable to get ready bytes");
     255        }
     256    }
     257
     258    if (0 <= retval)
     259    {
     260        retval = ispace.bytes;
     261    }
     262   
     263    return retval;
     264}
     265
  • libs/libmythtv/audioinput.h

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 * 02110-1301, USA.
     18 */
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
     20
     21#ifndef _AUDIOINPUT_H_
     22#define _AUDIOINPUT_H_
     23
     24#include <qstring.h>
     25
     26class AudioInput
     27{
     28public:
     29
     30    // Factory function
     31    static AudioInput * CreateDevice(QString device);
     32
     33    virtual ~AudioInput() {};
     34
     35    virtual int OpenDevice(int depth, int sample_rate, int channels) = 0;
     36    virtual int CloseDevice() = 0;
     37   
     38    virtual int StartCapture() = 0;
     39    virtual int StopCapture() = 0;
     40   
     41    virtual int GetBlockSize() = 0;
     42   
     43    virtual int GetSamples(void *buffer, int num_samples) = 0;
     44    virtual int GetNumReadyBytes() = 0;
     45};
     46   
     47
     48#endif /* _AUDIOINPUT_H_ */
     49
  • libs/libmythtv/videosource.cpp

     
    774774{
    775775  public:
    776776    AudioDevice(const CaptureCard &parent) :
    777         PathSetting(this, true),
     777        PathSetting(this, false),
    778778        CaptureCardDBStorage(this, parent, "audiodevice")
    779779    {
    780780        setLabel(QObject::tr("Audio device"));
  • libs/libmythtv/alsaaudioinput.cpp

     
     1/*
     2 * Copyright (C) 2007  Anand K. Mistry
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 * 02110-1301, USA.
     18 */
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
     20
     21#include <fcntl.h>
     22#include <unistd.h>
     23#include <sys/types.h>
     24#include <sys/stat.h>
     25#include <sys/ioctl.h>
     26
     27#include <iostream>
     28
     29#include "mythconfig.h"
     30
     31#include "alsaaudioinput.h"
     32#include "mythcontext.h"
     33
     34#define LOC     QString("ALSAAudioInput: ")
     35
     36ALSAAudioInput::ALSAAudioInput(QString &device)
     37{
     38    m_audio_handle = NULL;
     39   
     40    m_audio_channels = 0;
     41    m_audio_sample_size = 0;
     42    m_audio_sample_rate = 0;
     43   
     44    m_device_name = device;
     45}
     46
     47ALSAAudioInput::~ALSAAudioInput()
     48{
     49    CloseDevice();
     50}
     51
     52int ALSAAudioInput::OpenDevice(int sample_size, int sample_rate, int channels)
     53{
     54    int retval = 0;
     55    snd_pcm_hw_params_t * hw_params;
     56   
     57    // Open the device
     58    retval = snd_pcm_open(&m_audio_handle,
     59                          m_device_name.ascii(), SND_PCM_STREAM_CAPTURE, 0);
     60    if (0 > retval)
     61    {
     62        m_audio_handle = NULL;
     63        VERBOSE(VB_AUDIO,
     64                QString(LOC + "Cannot open ALSA '%1', exiting")
     65                .arg(m_device_name));
     66    }
     67   
     68    if (0 <= retval)
     69    {
     70        // Allocate hw params structure
     71        retval = snd_pcm_hw_params_malloc(&hw_params);
     72    }
     73   
     74    if (0 <= retval)
     75    {
     76        // Initialize hw params
     77        retval = snd_pcm_hw_params_any(m_audio_handle, hw_params);
     78    }
     79   
     80    if (0 <= retval)
     81    {
     82        // Set interleaved access
     83        retval = snd_pcm_hw_params_set_access(m_audio_handle,
     84                                              hw_params,
     85                                              SND_PCM_ACCESS_RW_INTERLEAVED);
     86    }
     87   
     88    if (0 <= retval)
     89    {
     90        // Set format
     91        retval = snd_pcm_hw_params_set_format(m_audio_handle,
     92                                              hw_params,
     93                                              SND_PCM_FORMAT_S16_LE);
     94    }
     95   
     96    if (0 <= retval)
     97    {
     98        // Set sampling rate
     99        m_audio_sample_rate = sample_rate;
     100        retval = snd_pcm_hw_params_set_rate(m_audio_handle,
     101                                            hw_params,
     102                                            m_audio_sample_rate, 0);
     103    }
     104   
     105    if (0 <= retval)
     106    {
     107        // Set channels
     108        m_audio_channels = channels;
     109        retval = snd_pcm_hw_params_set_channels(m_audio_handle,
     110                                                hw_params,
     111                                                m_audio_channels);
     112    }
     113   
     114    if (0 <= retval)
     115    {
     116        // Set sample size
     117        m_audio_sample_size = sample_size;
     118   
     119        // Apply settings
     120        retval = snd_pcm_hw_params(m_audio_handle, hw_params);
     121    }
     122   
     123    snd_pcm_hw_params_free(hw_params);
     124   
     125    if (0 <= retval)
     126    {
     127        VERBOSE(VB_AUDIO, LOC + "Opened device " + m_device_name);
     128    }
     129   
     130    return retval;
     131}
     132
     133int ALSAAudioInput::CloseDevice()
     134{
     135    if (0 < m_audio_handle)
     136    {
     137        snd_pcm_close(m_audio_handle);
     138        m_audio_handle = 0;
     139       
     140        VERBOSE(VB_AUDIO, LOC + "Closed device " + m_device_name);
     141    }   
     142   
     143    return 0;
     144}
     145
     146int ALSAAudioInput::StartCapture()
     147{
     148    int retval = 0;
     149   
     150    if (0 == m_audio_handle)
     151    {
     152        retval = -1;
     153    }
     154   
     155    if (0 <= retval)
     156    {
     157        retval = snd_pcm_prepare(m_audio_handle);
     158    }
     159   
     160    if (0 <= retval)
     161    {
     162        VERBOSE(VB_AUDIO, LOC + "Started capture on " + m_device_name);
     163    }
     164    else
     165    {
     166        VERBOSE(VB_AUDIO, LOC + "Unable to start capture");
     167    }
     168   
     169    return retval;
     170}
     171
     172int ALSAAudioInput::StopCapture()
     173{
     174    return -1;
     175}
     176
     177int ALSAAudioInput::GetBlockSize()
     178{
     179    int retval = 0;
     180    snd_pcm_uframes_t buffer_size, period_size;
     181   
     182    if (NULL == m_audio_handle)
     183    {
     184        retval = -1;
     185    }
     186   
     187    if (0 <= retval)
     188    {
     189        retval = snd_pcm_get_params(m_audio_handle, &buffer_size, &period_size);
     190    }
     191   
     192    if (0 <= retval)
     193    {
     194        retval = (period_size * m_audio_channels * m_audio_sample_size) / 8;
     195    }
     196   
     197    return retval;
     198}
     199
     200int ALSAAudioInput::GetSamples(void *buffer, int num_bytes)
     201{
     202    int retval = 0;
     203    int frame_size;
     204   
     205    frame_size = (m_audio_sample_size * m_audio_channels) / 8;
     206
     207    if (0 != (num_bytes % frame_size))
     208    {
     209         VERBOSE(VB_AUDIO, LOC + "Invalid num_bytes");
     210         retval = -1;
     211    }
     212   
     213    if (0 <= retval)
     214    {   
     215        retval = snd_pcm_readi(m_audio_handle, buffer, num_bytes/frame_size);
     216        if (0 > retval)
     217        {
     218            retval = snd_pcm_recover(m_audio_handle, retval, 1);
     219        }
     220    }
     221   
     222    if (0 <= retval)
     223    {
     224        retval *= frame_size;
     225    }
     226   
     227    return retval;
     228}
     229
     230int ALSAAudioInput::GetNumReadyBytes()
     231{
     232    int retval = 0;
     233    snd_pcm_sframes_t delay;
     234   
     235    if (NULL == m_audio_handle)
     236    {
     237        retval = -1;
     238    }
     239   
     240    if (0 <= retval)
     241    {
     242        retval = snd_pcm_delay(m_audio_handle, &delay);
     243    }
     244   
     245    if (0 <= retval)
     246    {
     247        retval = (delay * m_audio_channels * m_audio_sample_size) / 8;
     248    }
     249   
     250    return retval;
     251}
     252