Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

device_oss.cpp

Go to the documentation of this file.
00001 #include <algorithm>
00002 #include <string>
00003 #include <stdio.h>
00004 #include <unistd.h>
00005 #include <fcntl.h>
00006 #include <sys/ioctl.h>
00007 #include <sys/soundcard.h>
00008 #include "device_oss.h"
00009 #include "debug.h"
00010 
00011 
00012 namespace audiere {
00013 
00014   OSSAudioDevice*
00015   OSSAudioDevice::create(const ParameterList& parameters) {
00016     std::string device = parameters.getValue("device", "/dev/dsp");
00017 
00018     // attempt to open output device
00019     int output_device = open(device.c_str(), O_WRONLY);
00020     if (output_device == -1) {
00021       perror(device.c_str());
00022       return 0;
00023     }
00024 
00025     int format = AFMT_S16_LE;
00026     if (ioctl(output_device, SNDCTL_DSP_SETFMT, &format) == -1) {
00027       perror("SNDCTL_DSP_SETFMT");
00028       return 0;
00029     }
00030     if (format != AFMT_S16_LE) {
00031       // unsupported format
00032       return 0;
00033     }
00034 
00035     int stereo = 1;
00036     if (ioctl(output_device, SNDCTL_DSP_STEREO, &stereo) == -1) {
00037       perror("SNDCTL_DSP_STEREO");
00038       return 0;
00039     }
00040     if (stereo != 1) {
00041       // unsupported channel number
00042       return 0;
00043     }
00044 
00045     int speed = 44100;
00046     if (ioctl(output_device, SNDCTL_DSP_SPEED, &speed) == -1) {
00047       perror("SNDCTL_DSP_SPEED");
00048       return 0;
00049     }
00050     if (abs(44100 - speed) > 2205) {
00051       // unsupported sampling rate
00052       return 0;
00053     }
00054 
00055     return new OSSAudioDevice(output_device);
00056   }
00057 
00058 
00059   OSSAudioDevice::OSSAudioDevice(int output_device)
00060     : MixerDevice(44100)
00061   {
00062     m_output_device = output_device;
00063   }
00064 
00065 
00066   OSSAudioDevice::~OSSAudioDevice() {
00067     ADR_GUARD("OSSAudioDevice::~OSSAudioDevice");
00068     close(m_output_device);
00069   }
00070 
00071 
00072   void
00073   OSSAudioDevice::update() {
00074     // find out how much data we can write to the device before it blocks
00075     audio_buf_info info;
00076     if (ioctl(m_output_device, SNDCTL_DSP_GETOSPACE, &info) == -1) {
00077       return;
00078     }
00079 
00080     // how many samples is that?
00081     int sample_count = info.bytes / 4;
00082 
00083     // write to the OSS device, 1024 samples at a time
00084     static const int BUFFER_SIZE = 1024;
00085     char buffer[BUFFER_SIZE * 4];
00086     while (sample_count > 0) {
00087       int transfer_count = std::min(sample_count, BUFFER_SIZE);
00088 
00089       read(transfer_count, buffer);
00090       write(m_output_device, buffer, transfer_count * 4);
00091 
00092       sample_count -= transfer_count;
00093     }
00094 
00095     usleep(50000);  // 50 milliseconds
00096   }
00097 
00098 }

Generated on Sat Oct 12 01:43:03 2002 for audiere by doxygen1.2.17