00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036
00037 #ifdef HAVE_SYS_SOUNDCARD_H
00038 #include <stdio.h>
00039 #include <unistd.h>
00040 #include <stdlib.h>
00041 #include <fcntl.h>
00042
00043 #ifdef __STDC__
00044 #include <string.h>
00045 #else
00046 #include <strings.h>
00047 #endif
00048
00049 #include <sys/ioctl.h>
00050 #include <sys/soundcard.h>
00051
00052 #include "audio_oss.h"
00053
00054 #define DSP_FRAGMENT (0x7fff0000 | 0x000b)
00055
00056 int32_t audio_open_oss(p_audio_pub device)
00057 {
00058 int32_t err;
00059 int32_t fctl;
00060
00061 if(device->play_record == AUDIO_DEVICE_RECORD) {
00062 fctl = (O_RDONLY | O_NONBLOCK);
00063 }
00064 else if(device->play_record == AUDIO_DEVICE_PLAY) {
00065 fctl = (O_WRONLY | O_NONBLOCK);
00066 }
00067 else {
00068 fctl = (O_RDONLY | O_NONBLOCK);
00069 }
00070
00071
00072 device->handle = open(device->name, fctl, 0);
00073 if (device->handle == -1) {
00074 perror (device->name);
00075 device->error_msg_handler("Audio device busy.\nAnother program may be using the sound device.");
00076 err = -1;
00077 }
00078 else {
00079
00080
00081
00082
00083
00084
00085 fcntl(device->handle, F_SETFL, 0);
00086 err = 0;
00087 }
00088 return err;
00089 }
00090
00091 int32_t audio_init_oss(p_audio_pub device)
00092 {
00093 int32_t tmp;
00094
00095 device->dsp_channels = AUDIO_MONO;
00096 device->format = AFMT_S16_LE;
00097 device->samplesize = 16;
00098 device->buffer_segments = AUDIO_BUFFER_SEGMENTS;
00099 device->fragsize= DSP_FRAGMENT;
00100
00101 if(device->fragsize != 0) {
00102 if(ioctl(device->handle, SNDCTL_DSP_SETFRAGMENT, &device->fragsize) == -1) {
00103 perror("SETFRAGMENT");
00104 device->error_msg_handler("Unable to set audio fragment.");
00105 return(-1);
00106 }
00107 }
00108
00109 tmp = device->samplesize;
00110 ioctl(device->handle, SNDCTL_DSP_SAMPLESIZE, &device->samplesize);
00111 if (tmp != device->samplesize) {
00112 fprintf(stderr, "Unable to set the sample size\n");
00113 device->error_msg_handler("Unable to set audio sample size.");
00114 return(-1);
00115 }
00116
00117 if (ioctl(device->handle, SNDCTL_DSP_STEREO, &device->dsp_channels) == -1) {
00118 fprintf (stderr, "Unable to set mono/stereo\n");
00119 perror (device->name);
00120 device->error_msg_handler("Unable to set mono mode.");
00121 return(-1);
00122 }
00123 if(device->dsp_channels != AUDIO_MONO) {
00124 perror("mono format not supported");
00125 }
00126
00127 device->format = AFMT_S16_LE;
00128 if (ioctl (device->handle, SNDCTL_DSP_SETFMT, &device->format) == -1) {
00129 fprintf (stderr, "Unable to little endian sound format\n");
00130 device->error_msg_handler("Unable to set little endian sound format.");
00131 perror (device->name);
00132 return(-1);
00133 }
00134 if(device->format != AFMT_S16_LE) {
00135 perror("Sound format not supported");
00136 device->error_msg_handler("Audio sound format not supported.");
00137 }
00138
00139 if (ioctl (device->handle, SNDCTL_DSP_SPEED, &device->sample_frequency) == -1) {
00140 fprintf (stderr, "Unable to set audio sampling rate\n");
00141 perror (device->name);
00142 device->error_msg_handler("Unable to audio sampling rate.");
00143 return(-1);
00144 }
00145 ioctl (device->handle, SNDCTL_DSP_GETBLKSIZE, &device->audio_buffer_size);
00146 if(device->audio_buffer_size < 0) {
00147 perror ("GETBLKSIZE");
00148 return(-1);
00149 }
00150
00151
00152
00153 device->samples = device->audio_buffer_size / (device->samplesize >> 3) / (device->dsp_channels + 1);
00154
00155 if ((device->audio_buffer_raw = malloc ((size_t)(device->audio_buffer_size * device->buffer_segments))) == NULL) {
00156 fprintf (stderr, "Unable to allocate input/output buffer\n");
00157 device->error_msg_handler("Unable to allocate input/output buffer.");
00158 return(-1);
00159 }
00160 return 0;
00161 }
00162
00163 int32_t audio_close_oss(p_audio_pub device)
00164 {
00165 if(device->handle != -1) {
00166 close (device->handle);
00167 }
00168 return 0;
00169 }
00170
00171 void audio_record_oss(p_audio_pub device, te_audio_segments buffer_segment)
00172 {
00173 int32_t l;
00174 int32_t offset;
00175
00176 offset = device->audio_buffer_size * buffer_segment;
00177
00178 if((l = read (device->handle, &device->audio_buffer_raw[offset], device->audio_buffer_size)) <= 0) {
00179 fprintf (stderr, "Unable to read data from audio device\n");
00180 device->error_msg_handler("Unable to read data from audio device.\nTry lowering the sample rate.");
00181 }
00182 }
00183
00184 void audio_play_oss(p_audio_pub device, te_audio_segments buffer_segment)
00185 {
00186 int32_t l;
00187 int32_t offset;
00188
00189 offset = device->audio_buffer_size * buffer_segment;
00190
00191 if((l = write(device->handle, &device->audio_buffer_raw[offset], device->audio_buffer_size)) <= 0) {
00192 fprintf (stderr, "Unable to write data to audio device\n");
00193 device->error_msg_handler("Unable to write data to audio device.\nTry lowering the sample rate.");
00194 }
00195 }
00196 #endif