Ticket #3405: mythtv_alsa-2.patch
File mythtv_alsa-2.patch, 29.0 KB (added by , 17 years ago) |
---|
-
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 28 class ALSAAudioInput : public AudioInput 29 { 30 public: 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 45 private: 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 26 class OSSAudioInput : public AudioInput 27 { 28 public: 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 43 private: 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
17 17 18 18 #include <qstringlist.h> 19 19 20 #include "audioinput.h" 21 20 22 #include <iostream> 23 #include <memory> 21 24 using namespace std; 22 25 23 26 #include "mythcontext.h" … … 626 629 627 630 int NuppelVideoRecorder::AudioInit(bool skipdevice) 628 631 { 629 int afmt, afd; 630 int frag, blocksize = 4096; 632 auto_ptr<AudioInput> audio_device; 633 634 int blocksize = 256; 631 635 int tmp; 632 636 633 637 if (!skipdevice) … … 642 646 643 647 return 1; 644 648 #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()) 646 652 { 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"); 650 655 return 1; 651 656 } 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)) 663 661 { 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"); 666 664 return 1; 667 665 } 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) 672 670 { 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; 680 675 } 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)); 690 680 #endif 691 681 } 692 682 693 audio_bytes_per_sample = audio_channels * audio_bits / 8;694 blocksize *= 4;695 696 683 audio_buffer_size = blocksize; 697 684 698 685 if (compressaudio) … … 2195 2182 2196 2183 void NuppelVideoRecorder::doAudioThread(void) 2197 2184 { 2185 auto_ptr<AudioInput> audio_device; 2186 int act = 0, lastread = 0; 2187 unsigned char *buffer; 2188 struct timeval anow; 2189 2198 2190 #if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H) 2199 2191 VERBOSE(VB_IMPORTANT, LOC + 2200 2192 QString("doAudioThread() This Unix doesn't support" 2201 2193 " device files for audio access. Skipping")); 2202 2194 return; 2203 2195 #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()) 2214 2199 { 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"); 2218 2201 return; 2219 2202 } 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)) 2230 2207 { 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"); 2233 2209 return; 2234 2210 } 2235 2211 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 2248 2212 audio_bytes_per_sample = audio_channels * audio_bits / 8; 2249 2213 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*blocksize2258 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 2266 2214 buffer = new unsigned char[audio_buffer_size]; 2267 2215 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 2275 2216 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"); 2276 2225 while (childrenLive) 2277 2226 { 2278 2227 if (request_pause) … … 2288 2237 } 2289 2238 audiopaused = false; 2290 2239 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))) 2293 2243 { 2294 2244 VERBOSE(VB_IMPORTANT, LOC_ERR + 2295 2245 QString("Only read %1 bytes of %2 bytes from '%3"). 2296 2246 arg(lastread).arg(audio_buffer_size).arg(audiodevice)); 2297 2247 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 } 2298 2258 } 2299 2259 2300 2260 /* record the current time */ … … 2302 2262 (like we used to.) Measure to see how much stuff is in there, 2303 2263 and correct for it when calculating the timestamp */ 2304 2264 gettimeofday(&anow, &tzone); 2305 ioctl( afd, SNDCTL_DSP_GETISPACE, &ispace );2306 2265 2307 2266 act = act_audio_buffer; 2308 2267 2309 2268 if (!audiobuffer[act]->freeToBuffer) 2310 2269 { 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 :-("); 2312 2272 act_audio_sample++; 2313 2273 continue; 2314 2274 } … … 2323 2283 audio chunk. So, subtract off the length of the chunk 2324 2284 and the length of audio still in the capture buffer. */ 2325 2285 audiobuffer[act]->timecode -= (int)( 2326 ( ispace.fragments * ispace.fragsize+ audio_buffer_size)2286 (audio_device->GetNumReadyBytes() + audio_buffer_size) 2327 2287 * 1000.0 / (audio_samplerate * audio_bytes_per_sample)); 2328 2288 2329 2289 memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size); … … 2338 2298 } 2339 2299 2340 2300 delete [] buffer; 2341 close(afd);2342 2301 #endif 2343 2302 } 2344 2303 -
libs/libmythtv/libmythtv.pro
365 365 366 366 # Simple NuppelVideo Recorder 367 367 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 } 370 383 371 384 # Support for Video4Linux devices 372 385 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 32 AudioInput * 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 40 OSSAudioInput::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 51 OSSAudioInput::~OSSAudioInput() 52 { 53 CloseDevice(); 54 } 55 56 int 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 152 int 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 165 int 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 192 int OSSAudioInput::StopCapture() 193 { 194 return -1; 195 } 196 197 int 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 220 int 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 239 int 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 26 class AudioInput 27 { 28 public: 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
774 774 { 775 775 public: 776 776 AudioDevice(const CaptureCard &parent) : 777 PathSetting(this, true),777 PathSetting(this, false), 778 778 CaptureCardDBStorage(this, parent, "audiodevice") 779 779 { 780 780 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 36 ALSAAudioInput::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 47 ALSAAudioInput::~ALSAAudioInput() 48 { 49 CloseDevice(); 50 } 51 52 int 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 133 int 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 146 int 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 172 int ALSAAudioInput::StopCapture() 173 { 174 return -1; 175 } 176 177 int 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 200 int 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 230 int 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