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
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
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
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
00052 return 0;
00053 }
00054
00055 int fragsize = 0x0004000b;
00056 if (ioctl(output_device, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
00057 perror("SNDCTL_DSP_SETFRAGMENT");
00058 return 0;
00059 }
00060
00061 return new OSSAudioDevice(output_device);
00062 }
00063
00064
00065 OSSAudioDevice::OSSAudioDevice(int output_device)
00066 : MixerDevice(44100)
00067 {
00068 m_output_device = output_device;
00069 }
00070
00071
00072 OSSAudioDevice::~OSSAudioDevice() {
00073 ADR_GUARD("OSSAudioDevice::~OSSAudioDevice");
00074 close(m_output_device);
00075 }
00076
00077
00078 void ADR_CALL
00079 OSSAudioDevice::update() {
00080 static const int BUFFER_SIZE = 512;
00081 char buffer[BUFFER_SIZE * 4];
00082 read(BUFFER_SIZE, buffer);
00083 write(m_output_device, buffer, BUFFER_SIZE * 4);
00084 }
00085
00086
00087 const char* ADR_CALL
00088 OSSAudioDevice::getName() {
00089 return "oss";
00090 }
00091
00092 }