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 #include "libport/cstdio"
00030 #include <ctime>
00031 #include <sys/types.h>
00032 #include "libport/sys/stat.h"
00033
00034 #include <fcntl.h>
00035 #include "urbi/uclient.hh"
00036
00037 #ifndef WIN32
00038 # include <sys/ioctl.h>
00039 # include <sys/soundcard.h>
00040 static const char *device="/dev/dsp";
00041 #endif
00042
00043 struct wavheader
00044 {
00045 char riff[4];
00046 int length;
00047 char wave[4];
00048 char fmt[4];
00049 int lnginfo;
00050 short one;
00051 short channels;
00052 int freqechant;
00053 int bytespersec;
00054 short bytesperechant;
00055 short bitperchannel;
00056 char data[4];
00057 int datalength;
00058 };
00059
00060
00061
00062 char * fname;
00063 int imcount;
00064 FILE * file;
00065 bool outtodsp;
00066 bool withheader;
00067 bool waswithheader;
00068 int totallength;
00069
00070 urbi::UCallbackAction
00071 endProgram(const urbi::UMessage&)
00072 {
00073 if (waswithheader)
00074 {
00075
00076
00077
00078 if (fseek(file,offsetof(wavheader, length),SEEK_SET)==-1)
00079 {
00080 fprintf(stderr, "warning, can't seek output file (stdout?), wav header will be incorrect!\n");
00081 exit(0);
00082 }
00083 int len = totallength - 8;
00084 fwrite(&len, 1, 4, file);
00085 fseek(file,offsetof(wavheader, datalength),SEEK_SET);
00086 len = totallength - 44;
00087 fwrite(&len, 1, 4, file);
00088 fclose(file);
00089 exit(0);
00090 }
00091 exit(0);
00092 return urbi::URBI_CONTINUE;
00093 }
00094
00095 urbi::UCallbackAction
00096 getSound(const urbi::UMessage& msg)
00097 {
00098 static urbi::USound out;
00099 static bool initialized=false;
00100 if (!initialized)
00101 {
00102 totallength = 0;
00103 initialized = true;
00104 out.data = 0;
00105 out.size = 0;
00106 if (outtodsp)
00107 {
00108 out.channels = 2;
00109 out.sampleSize = 16;
00110 out.rate = 16000;
00111 out.sampleFormat = urbi::SAMPLE_SIGNED;
00112 }
00113 else
00114 {
00115 out.channels = 0;
00116 out.sampleSize = 0;
00117 out.rate = 0;
00118 out.sampleFormat = (urbi::USoundSampleFormat)0;
00119 }
00120 }
00121
00122 if (msg.type != urbi::MESSAGE_DATA
00123 || msg.value->type != urbi::DATA_BINARY
00124 || msg.value->binary->type != urbi::BINARY_SOUND)
00125 return urbi::URBI_CONTINUE;
00126 out.soundFormat =
00127 withheader? urbi::SOUND_WAV : urbi::SOUND_RAW;
00128 withheader = false;
00129 convert(msg.value->binary->sound, out);
00130 totallength += out.size;
00131 fwrite(out.data, out.size, 1, file);
00132 return urbi::URBI_CONTINUE;
00133 }
00134
00135
00136 int main(int argc, char *argv[])
00137 {
00138 const char *usage = "usage: urbisound robot milisecondtime :plays sound recorded by the aibo to /dev/dsp\n"
00139 "\turbisound robot milisecondtime file [withoutheader] : write recorded sound to a file, with a wav header except if argument withoutheader is set to anything\n";
00140
00141 if (argc != 3)
00142 {
00143 printf(usage);
00144 exit(1);
00145 }
00146
00147 int time = strtol(argv[2], NULL, 0);
00148
00149 if (argc >= 4)
00150 {
00151 outtodsp = false;
00152 if (STREQ(argv[3],"-"))
00153 file=stdout;
00154 else
00155 file = fopen(argv[3], "wb+");
00156 fname = argv[3];
00157 if (file==0)
00158 {
00159 printf("error creating file\n");
00160 exit(2);
00161 }
00162
00163 if (argc==5)
00164 withheader = false;
00165 else
00166 withheader = true;
00167 }
00168 else
00169 {
00170 #ifdef WIN32
00171 printf("output to soundcard not supported under windows\n");
00172 exit(2);
00173 #else
00174 outtodsp = true;
00175 withheader = false;
00176 file = fopen(device, "wb" );
00177 if (file==0)
00178 {
00179 printf("error opening device\n"), exit(2);
00180 }
00181 int f = fileno(file);
00182 int param;
00183
00184 param=16;
00185 if (ioctl(f, SNDCTL_DSP_SAMPLESIZE, ¶m)==-1)
00186 {
00187 fprintf(stderr,"failed to set sample size for %s\n", device);
00188 exit(1);
00189 }
00190
00191 param=1;
00192 if (ioctl (f, SNDCTL_DSP_STEREO, ¶m)==-1)
00193 {
00194 fprintf(stderr,"failed to set stereo for %s\n", device);
00195 exit(1);
00196 }
00197
00198 param=16000;
00199 if (ioctl (f, SNDCTL_DSP_SPEED, ¶m) == -1)
00200 {
00201 fprintf(stderr,"failed to set speed for %s\n", device);
00202 exit(1);
00203 }
00204 #endif
00205 }
00206
00207 waswithheader = withheader;
00208 urbi::UClient client (argv[1]);
00209 if (client.error())
00210 exit(0);
00211
00212 client.setCallback(getSound, "usound");
00213 client.setCallback(endProgram, "end");
00214
00215 client.send("loopsound:loop usound: micro.val ,"
00216 "{ wait(%d); stop loopsound; wait(1000); end:ping }, ", time);
00217 urbi::execute();
00218 }