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 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
00075 audio_buf_info info;
00076 if (ioctl(m_output_device, SNDCTL_DSP_GETOSPACE, &info) == -1) {
00077 return;
00078 }
00079
00080
00081 int sample_count = info.bytes / 4;
00082
00083
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);
00096 }
00097
00098 }