00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <sys/types.h>
00010 #include <errno.h>
00011 #include <signal.h>
00012 #include <stdlib.h>
00013 #include <unistd.h>
00014 #include <fcntl.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <sys/ioctl.h>
00018 #include <minix/sound.h>
00019
00020 _PROTOTYPE( void main, (int argc, char **argv));
00021 _PROTOTYPE( void usage, (void));
00022
00023
00024
00025 #define RIFF_ID 0x46464952
00026 #define WAVE_ID1 0x45564157
00027 #define WAVE_ID2 0x20746D66
00028 #define DATA_ID 0x61746164
00029 #define MS_PCM_FORMAT 0x0001
00030
00031 #define WORD short
00032 #define DWORD unsigned long
00033
00034 struct RIFF_fields
00035 {
00036 DWORD RIFF_id;
00037 DWORD RIFF_len;
00038 DWORD WAVE_id1;
00039 DWORD WAVE_id2;
00040 DWORD data_ptr;
00041 } r_fields;
00042
00043 struct common_fields
00044 {
00045 WORD FormatTag;
00046 WORD Channels;
00047 DWORD SamplesPerSec;
00048 DWORD AvgBytesPerSec;
00049 WORD BlockAlign;
00050 } c_fields;
00051
00052 struct specific_fields
00053 {
00054 WORD BitsPerSample;
00055 } s_fields;
00056
00057 DWORD data_id;
00058 DWORD data_len;
00059
00060
00061
00062
00063 void usage()
00064 {
00065 fprintf(stderr, "Usage: playwav [-i] file\n");
00066 exit(-1);
00067 }
00068
00069
00070 void main ( int argc, char *argv[] )
00071 {
00072 int i, audio, file;
00073 char *buffer, *file_name;
00074 unsigned int sign;
00075 unsigned int fragment_size;
00076 unsigned int channels;
00077 unsigned int bits;
00078 long data_pos;
00079 int showinfo = 0;
00080
00081
00082 if (argc > 2)
00083 {
00084 if (strncmp(argv[1], "-i", 2) == 0)
00085 {
00086 showinfo = 1;
00087 file_name = argv[2];
00088 }
00089 else
00090 usage();
00091 }
00092 else file_name = argv[1];
00093
00094
00095 if ((audio = open("/dev/audio", O_RDWR)) < 0)
00096 {
00097 printf("Cannot open /dev/audio\n");
00098 exit(-1);
00099 }
00100
00101
00102 ioctl(audio, DSPIOMAX, &fragment_size);
00103 if ((buffer = malloc(fragment_size)) == (char *)0)
00104 {
00105 fprintf(stderr, "Cannot allocate buffer\n");
00106 exit(-1);
00107 }
00108 ioctl(audio, DSPIOSIZE, &fragment_size);
00109
00110
00111 if((file = open(file_name, O_RDONLY)) < 0)
00112 {
00113 printf("Cannot open %s\n", file_name);
00114 exit(-1);
00115 }
00116
00117
00118 read(file, &r_fields, 20);
00119 if(r_fields.RIFF_id != RIFF_ID)
00120 {
00121 printf("%s not in RIFF format\n", file_name);
00122 exit(1);
00123 }
00124 if(r_fields.WAVE_id1 != WAVE_ID1 || r_fields.WAVE_id2 != WAVE_ID2)
00125 {
00126 printf("%s not in WAVE format\n", file_name);
00127 exit(1);
00128 }
00129
00130
00131 data_pos = lseek(file, 0L, 1) + r_fields.data_ptr;
00132
00133
00134 read(file, &c_fields, 14);
00135 read(file, &s_fields, 2);
00136
00137
00138 if(c_fields.FormatTag != MS_PCM_FORMAT)
00139 {
00140 printf("%s not in MicroSoft PCM format\n", file_name);
00141 exit(1);
00142 }
00143
00144
00145 channels = c_fields.Channels;
00146 channels--;
00147 bits = s_fields.BitsPerSample;
00148 ioctl(audio, DSPIOSTEREO, &channels);
00149 ioctl(audio, DSPIORATE, &c_fields.SamplesPerSec);
00150 ioctl(audio, DSPIOBITS, &bits);
00151 sign = (bits == 16 ? 1 : 0);
00152 ioctl(audio, DSPIOSIGN, &sign);
00153
00154
00155 lseek(file, data_pos, SEEK_SET);
00156
00157
00158 read(file, &data_id, sizeof(data_id));
00159 if(data_id != DATA_ID)
00160 {
00161 printf("Invalid data chunk\n");
00162 exit(1);
00163 }
00164
00165
00166 read(file, &data_len, sizeof(data_len));
00167
00168 if (showinfo)
00169 {
00170 printf("\nBits per sample : %d \n", s_fields.BitsPerSample);
00171 printf("Stereo : %s \n", (c_fields.Channels == 1 ? "yes" : "no"));
00172 printf("Samples per second: %ld \n", c_fields.SamplesPerSec);
00173 printf("Average bytes/sec : %ld \n", c_fields.AvgBytesPerSec);
00174 printf("Block alignment : %d \n", c_fields.BlockAlign);
00175 printf("Datalength (bytes): %ld \n\n", data_len);
00176 }
00177
00178
00179 while(data_len > 0)
00180 {
00181 if (data_len > fragment_size)
00182 {
00183
00184 read(file, buffer, fragment_size);
00185 data_len-= fragment_size;
00186 }
00187 else
00188 {
00189
00190
00191
00192 read(file, buffer, data_len);
00193 for (i = data_len; i< fragment_size; i++)
00194 buffer[i] = buffer[(int)data_len-1];
00195 data_len = 0;
00196 }
00197
00198
00199 write(audio, buffer, fragment_size);
00200 }
00201 }