#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/soundcard.h> #include <unistd.h> #include <iostream> #include "MonitorAudioOSS.h" #include "../MonitorLogging.h" using namespace std ; MonitorAudioOSS::MonitorAudioOSS(const std::string* name, tSamplerate rate) : MonitorAudio (name, rate) { run = false; } MonitorAudioOSS::~MonitorAudioOSS() { CloseDevice(); } bool MonitorAudioOSS::Start(void *format) { if (InitDevice() < 0) { LOG_ERROR("Error initializing PCM device " << pcm_name ) exit(10); } run = true; JThread::Start(); return true; } void MonitorAudioOSS::Stop() { LOG_ERROR("stopping " << pcm_name ) run = false; } int MonitorAudioOSS::InitDevice() { int sndparam; if ((pcm_name.length() == 0) || (pcm_rate == 0)) { return -1; } if ((dev_handle = open(pcm_name.c_str(), O_RDONLY)) < 0) { LOG_ERROR("open" ) return -1; } sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */ /* little endian; works only on little endian systems! */ if (ioctl(dev_handle, SNDCTL_DSP_SETFMT, &sndparam) == -1) { LOG_ERROR("ioctl: SNDCTL_DSP_SETFMT") return -1; } sndparam = 1; /* 2 Kanäle */ if (ioctl(dev_handle, SNDCTL_DSP_STEREO, &sndparam) == -1) { LOG_ERROR(("ioctl: SNDCTL_DSP_STEREO")) return -1; } if (sndparam != 1) { /* Monovariante? */ LOG_ERROR("soundif: Error, cannot set the channel number to 2") return -1; } ioctl(dev_handle, SNDCTL_DSP_SPEED, &pcm_rate); return 0; } int MonitorAudioOSS::CloseDevice() { close(dev_handle); return 0; } void *MonitorAudioOSS::Thread() { int bytes; short *temp_buffer; float *left, *right; if ((temp_buffer = (short*) malloc(audio_buffer->SampleLen * sizeof (short) * 2)) == NULL) { LOG_ERROR("cannot allocate temporary audio buffer") exit (-1); } JThread::ThreadStarted(); LOG_INFO("AudioThread " << pcm_name << " is running" ) while(run) { bytes = read(dev_handle, temp_buffer, audio_buffer->SampleLen * sizeof (short) * 2); if (bytes > 0) { left = audio_buffer->Left; right = audio_buffer->Right; /* bytes / Kan�le / bytes pro sample */ audio_buffer->Samples = bytes / sizeof(short) / 2; for (tFramecount i=0; i < audio_buffer->Samples; i++) { left[i] = temp_buffer[i*2] / 32768.0; right[i] = temp_buffer[i*2+1] / 32768.0; } DataFromSoundIn(audio_buffer, m_pOwner); } else if (bytes < 0) { /* Schliessen des Sounddevices und neustarten */ CloseDevice(); sleep(1); if (InitDevice() < 0) { LOG_ERROR("Error initializing PCM device "<< pcm_name ) } } } LOG_INFO("AudioThread " << pcm_name << " has stopped" ) free(temp_buffer); return NULL; } // vim: sw=4 ts=4