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
00034
00035
00036
00037
#ifndef _VRAUDIOSOURCE_H_
00038
#define _VRAUDIOSOURCE_H_
00039
00040 #define AUDIOINCHUNKSIZE 200
00041
00042
extern "C" {
00043
#include <sys/soundcard.h>
00044
#include <sys/ioctl.h>
00045
#include <fcntl.h>
00046
#include <unistd.h>
00047 }
00048
00049
#include <VrSource.h>
00050
#include <fstream>
00051
#include <algorithm>
00052
#include <string>
00053
00054
template<
class oType>
00055 class VrAudioSource :
public VrSource<oType> {
00056
protected:
00057 int audiofd;
00058 long format;
00059 bool decimate;
00060 std::string
device_name;
00061
public:
00062
virtual int work2(
VrSampleRange output,
void *o[]);
00063
virtual void initialize();
00064
00065 VrAudioSource(
double sampling_freq,
const char* dev =
"/dev/dsp")
00066 :
audiofd(-1),
decimate(false),
device_name(dev){
00067
00068
setSamplingFrequency (sampling_freq);
00069
setOutputSize (
AUDIOINCHUNKSIZE);
00070 }
00071
00072 virtual const char *
name() {
return "VrAudioSource"; }
00073
00074 virtual ~VrAudioSource() {close(
audiofd);}
00075 };
00076
00077
00078
template<
class oType>
void
00079 VrAudioSource<oType>::initialize()
00080 {
00081
int temp = 0x7fff0004;
00082
if(
audiofd==-1) {
00083
if ((
audiofd = open(
device_name.c_str(), O_RDONLY)) < 0) {
00084 cerr <<
"VrAudioSource: ";
00085 perror (
device_name.c_str ());
00086 exit(1);
00087 }
00088
if ((ioctl(
audiofd,SNDCTL_DSP_SETFRAGMENT,&temp)) < 0) {
00089 fprintf (stderr,
"VrAudioSource: set fragment returned %d\n", errno);
00090 exit(1);
00091 }
00092 }
00093
00094
if(
sizeof(
oType)==1) {
00095
format=AFMT_MU_LAW;
00096 }
else if(
sizeof(
oType)==2) {
00097 printf(
"setting to 16 bits \n");
00098
format = AFMT_S16_LE;
00099 }
else {
00100 fprintf (stderr,
00101
"VrAudioSource: cannot handle data type of size %d\n",
00102
sizeof(
oType));
00103 exit(1);
00104 }
00105
00106 ioctl(
audiofd,SNDCTL_DSP_RESET);
00107
00108
int origf=
format;
00109
if((ioctl(
audiofd,SNDCTL_DSP_SETFMT,&format)) < 0) {
00110 cerr <<
"VrAudioSource: " <<
device_name <<
" IOCTL failed with errno " << errno <<
"\n";
00111 exit(1);
00112 }
00113
if(origf!=format) {
00114 fprintf (stderr,
"VrAudioSource: Warning: unable to support format %d\n", origf);
00115 fprintf (stderr,
" card requested %ld instead.\n", format);
00116 }
00117
00118
00119
00120
int noutputs = 1;
00121
int channels = noutputs;
00122
if (ioctl (
audiofd, SNDCTL_DSP_CHANNELS, &channels) < 0){
00123 perror (
"VrAudioSink: SNDCTL_DSP_CHANNELS failed");
00124 exit (1);
00125 }
00126
00127
if (channels != noutputs){
00128
if (noutputs == 2){
00129 fprintf(stderr,
"VrAudioSource: could not set STEREO mode\n");
00130
00131 exit(1);
00132 }
00133
else {
00134
00135 fprintf (stderr,
"VrAudioSource: could not set MONO mode\n");
00136
decimate =
true;
00137 }
00138 }
00139
00140
int sf = (
int)
getSamplingFrequency();
00141
00142
if ((ioctl(
audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) {
00143 cerr <<
device_name <<
": Invalid sampling frequency...defaulting to 8 Khz\n";
00144 sf = 8000;
00145
if ((ioctl(
audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) {
00146 fprintf (stderr,
"Couldn't even manage that...aborting\n");
00147 exit(1);
00148 }
00149 }
00150
if(sf!=
getSamplingFrequency())
00151 fprintf(stderr,
"VrAudioSource Warning: soundcard defaulted to %d Hz\n", sf);
00152 }
00153
00154
00155
template<
class oType>
int
00156 VrAudioSource<oType>::work2(
VrSampleRange output,
void *ao[])
00157 {
00158
unsigned units=output.
size;
00159
oType **o= (
oType **)ao;
00160
oType *curPos=o[0];
00161
00162
if (
decimate){
00163
00164
while(units > 0) {
00165
const unsigned N = 2048;
00166
oType tmp[N*2];
00167
00168
int nbytes = std::min (units, N) * (
sizeof(
oType) * 2);
00169
int count = read(
audiofd, tmp, nbytes);
00170
00171
if(count < 0) {
00172 perror (
"VrAudioSource");
00173 exit(1);
00174 }
00175
00176 assert ((count & ((
sizeof(
oType) * 2) - 1)) == 0);
00177
00178
for (
unsigned int i = 0; i < count / (
sizeof (
oType) * 2); i++){
00179 curPos[i] = tmp[2*i];
00180 }
00181
00182 units -= count / (
sizeof (
oType) * 2);
00183 curPos += count / (
sizeof (
oType) * 2);
00184 }
00185
return output.
size;
00186 }
00187
00188
else {
00189
while(units > 0) {
00190
int nbytes = units *
sizeof(
oType);
00191
int count = read(
audiofd, curPos, nbytes);
00192
00193
if(count < 0) {
00194 perror (
"VrAudioSource");
00195 exit(1);
00196 }
00197
00198 assert ((count & (
sizeof(
oType) - 1)) == 0);
00199
00200 units -= count /
sizeof (
oType);
00201 curPos += count /
sizeof (
oType);
00202 }
00203
return output.
size;
00204 }
00205 }
00206
00207
#endif