19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
25 #elif !defined(__hpux) && !defined(_AIX)
29 #if !defined(__BIG_ENDIAN)
30 #define __LITTLE_ENDIAN 1234
31 #define __BIG_ENDIAN 4321
32 #define __PDP_ENDIAN 3412
33 #define __BYTE_ORDER __LITTLE_ENDIAN
37 using namespace UCOMMON_NAMESPACE;
39 AudioFile::AudioFile(
const char *name,
unsigned long sample)
43 AudioFile::open(name);
49 AudioFile::AudioFile(
const char *name, info_t& inf,
unsigned long samples)
54 AudioFile::create(name, inf);
60 AudioFile::AudioFile()
66 AudioFile::~AudioFile()
72 ssize_t AudioFile::read(
void *buffer,
size_t request)
74 ssize_t result = fs.read(buffer, request);
82 ssize_t AudioFile::write(
void *buffer,
size_t request)
84 ssize_t result = fs.write(buffer, request);
92 ssize_t AudioFile::peek(
void *buffer,
size_t request)
94 ssize_t result = fs.read(buffer, request);
100 bool AudioFile::seek(
size_t offset)
102 if(!fs.seek(offset)) {
111 encoding_t e = getEncoding();
114 return AudioCodec::get(e,
"g.711");
116 return AudioCodec::get(e,
"g.711");
120 return AudioCodec::get(e,
"g.721");
123 return AudioCodec::get(e,
"g.722");
126 return AudioCodec::get(e,
"g.723");
132 void AudioFile::setShort(
unsigned char *data,
unsigned short val)
144 unsigned short AudioFile::getShort(
unsigned char *data)
const
147 return data[0] * 256 + data[1];
149 return data[1] * 256 + data[0];
152 void AudioFile::setLong(
unsigned char *data,
unsigned long val)
158 data[i] = (
unsigned char)(val & 0xff);
160 data[3 - i] = (
unsigned char)(val & 0xff);
165 unsigned long AudioFile::getLong(
unsigned char * data)
const
168 unsigned long val =0;
172 val = (val << 8) | data[3 - i];
174 val = (val << 8) | data[i];
179 ssize_t AudioFile::putNative(encoded_t data,
size_t bytes)
184 swapEncoded(info, data, bytes);
185 return putBuffer(data, bytes);
188 ssize_t AudioFile::getNative(encoded_t data,
size_t bytes)
193 result = getBuffer(data, bytes);
198 swapEncoded(info, data, result);
202 void AudioFile::create(
const char *name, info_t& myinfo, timeout_t framing)
205 unsigned char aufile[24];
206 unsigned char riffhdr[40];
207 const char *ext = strrchr(name,
'/');
211 ext = strrchr(name,
'\\');
214 ext = strrchr(name,
':');
217 ext = strrchr(name,
'.');
219 ext = strrchr(ext,
'.');
225 fs.create(name, fsys::ACCESS_STREAM, 0660);
229 memset(riffhdr, 0,
sizeof(riffhdr));
231 info.annotation = NULL;
232 pathname =
new char[strlen(name) + 1];
233 strcpy(pathname, name);
234 if(myinfo.annotation) {
235 info.annotation =
new char[strlen(myinfo.annotation) + 1];
236 strcpy(info.annotation, myinfo.annotation);
239 if(!stricmp(ext,
".raw") || !stricmp(ext,
".bin")) {
241 if(info.encoding == unknownEncoding)
242 info.encoding = pcm16Mono;
244 else if(!stricmp(ext,
".au") || !stricmp(ext,
".snd"))
249 else if(!stricmp(ext,
".wav") || !stricmp(ext,
".wave"))
254 else if(!stricmp(ext,
".ul") || !stricmp(ext,
".ulaw") || !stricmp(ext,
".mulaw"))
256 info.encoding = mulawAudio;
261 else if(!stricmp(ext,
".al") || !stricmp(ext,
".alaw"))
263 info.encoding = alawAudio;
268 else if(!stricmp(ext,
".sw") || !stricmp(ext,
".pcm"))
270 info.encoding = pcm16Mono;
274 else if(!stricmp(ext,
".vox"))
276 info.encoding = voxADPCM;
281 else if(!stricmp(ext,
".gsm"))
283 info.encoding = gsmVoice;
287 info.framecount = 160;
289 info.bitrate = 13200;
291 else if(!stricmp(ext,
".adpcm") || !stricmp(ext,
".a32"))
293 info.encoding = g721ADPCM;
298 else if(!stricmp(ext,
".a24"))
300 info.encoding = g723_3bit;
305 else if(!stricmp(ext,
".a16"))
307 info.encoding = g723_2bit;
312 else if(!stricmp(ext,
".sx"))
314 info.encoding = sx96Voice;
319 else if(!stricmp(ext,
".a40"))
321 info.encoding = g723_5bit;
326 else if(!stricmp(ext,
".cda"))
328 info.encoding = cdaStereo;
334 switch(info.format) {
352 strncpy((
char *)riffhdr,
"RIFF", 4);
354 strncpy((
char *)riffhdr,
"RIFX", 4);
356 info.rate = Audio::getRate(info.encoding);
358 info.rate = rate8khz;
362 memset(riffhdr + 4, 0xff, 4);
363 strncpy((
char *)riffhdr + 8,
"WAVE", 4);
364 if(write(riffhdr, 12) != 12) {
418 memset(riffhdr, 0,
sizeof(riffhdr));
419 strncpy((
char *)riffhdr,
"fmt ", 4);
423 if(info.encoding < cdaStereo)
424 setLong(riffhdr + 4, 18);
426 setLong(riffhdr + 4, 16);
428 setShort(riffhdr + 8, 0x01);
429 if(is_mono(info.encoding))
430 setShort(riffhdr + 10, 1);
432 setShort(riffhdr + 10, 2);
433 setLong(riffhdr + 12, info.rate);
434 setLong(riffhdr + 16, (
unsigned long)toBytes(info, info.rate));
435 setShort(riffhdr + 20, (snd16_t)toBytes(info, 1));
436 setShort(riffhdr + 22, 0);
438 switch(info.encoding) {
441 setShort(riffhdr + 22, 8);
448 setShort(riffhdr + 22, 16);
453 setShort(riffhdr + 22, 32);
457 setShort(riffhdr + 8, 6);
458 setShort(riffhdr + 22, 8);
461 setShort(riffhdr + 8, 7);
462 setShort(riffhdr + 22, 8);
468 setShort(riffhdr + 8, 0x10);
469 setShort(riffhdr + 24, 4);
472 setShort(riffhdr + 8, 0x17);
473 setShort(riffhdr + 24, 4);
476 setShort(riffhdr + 8, 0x40);
477 setShort(riffhdr + 24, 4);
480 setShort(riffhdr + 8, 0x64);
481 setShort(riffhdr + 24, 8);
485 setShort(riffhdr + 8, 0x31);
486 setShort(riffhdr + 24, 260);
489 setShort(riffhdr + 8, 0x14);
490 setShort(riffhdr + 24, 3);
493 setShort(riffhdr + 8, 0x14);
494 setShort(riffhdr + 24, 5);
495 case unknownEncoding:
501 setShort(riffhdr + 24, 0);
502 strncpy((
char *)(riffhdr + 26),
"fact", 4);
503 setLong(riffhdr + 30, 4);
504 setLong(riffhdr + 34, 0);
505 if(write(riffhdr, 38) != 38) {
511 if(write(riffhdr, 24) != 24) {
532 memset(riffhdr, 0,
sizeof(riffhdr));
533 strncpy((
char *)riffhdr,
"data", 4);
534 memset(riffhdr + 4, 0xff, 4);
535 if(write(riffhdr, 8) != 8) {
540 header = getAbsolutePosition();
548 info.rate = Audio::getRate(info.encoding);
550 info.rate = rate8khz;
552 strncpy((
char *)aufile,
".snd", 4);
554 setLong(aufile + 4, 24 + (
unsigned long)strlen(info.annotation) + 1);
556 setLong(aufile + 4, 24);
557 header = getLong(aufile + 4);
558 setLong(aufile + 8, ~0l);
559 switch(info.encoding) {
562 setLong(aufile + 12, 2);
568 setLong(aufile + 12, 3);
572 setLong(aufile + 12, 5);
575 setLong(aufile + 12, 23);
580 setLong(aufile + 12, 24);
583 setLong(aufile + 12, 25);
586 setLong(aufile + 12, 26);
589 setLong(aufile + 12, 28);
592 setLong(aufile + 12, 27);
595 setLong(aufile + 12, 1);
597 setLong(aufile + 16, info.rate);
598 if(is_mono(info.encoding))
599 setLong(aufile + 20, 1);
601 setLong(aufile + 20, 2);
602 if(write(aufile, 24) != 24) {
607 write((
unsigned char *)info.annotation, (
unsigned long)strlen(info.annotation) + 1);
608 header = getAbsolutePosition();
614 info.setFraming(framing);
619 void AudioFile::getWaveFormat(
int request)
621 unsigned char filehdr[24];
628 if(peek(filehdr, request) < 1) {
632 channels = getShort(filehdr + 2);
633 info.rate = getLong(filehdr + 4);
635 switch(getShort(filehdr)) {
637 bitsize = getShort(filehdr + 14);
641 info.encoding = pcm8Stereo;
643 info.encoding = pcm8Mono;
646 if(info.rate == 44100) {
648 info.encoding = cdaStereo;
650 info.encoding = cdaMono;
654 info.encoding = pcm16Stereo;
656 info.encoding = pcm16Mono;
660 info.encoding = pcm32Stereo;
662 info.encoding = pcm32Mono;
665 info.encoding = unknownEncoding;
669 info.encoding = alawAudio;
672 info.encoding = mulawAudio;
675 info.encoding = okiADPCM;
678 info.encoding = voxADPCM;
681 info.encoding = g721ADPCM;
684 info.encoding = g722Audio;
687 info.encoding = msgsmVoice;
690 bitsize = getLong(filehdr + 8) * 8 / info.rate;
692 info.encoding = g723_3bit;
694 info.encoding = g723_5bit;
697 info.encoding = unknownEncoding;
701 void AudioFile::open(
const char *name, mode_t m, timeout_t framing)
703 unsigned char filehdr[24];
710 fsys::fileinfo_t ino;
714 fm = fsys::ACCESS_REWRITE;
717 fm = fsys::ACCESS_APPEND;
720 fm = fsys::ACCESS_STREAM;
728 fsys::fileinfo(name, &ino);
731 if(mode == modeReadAny || mode == modeReadOne)
732 name = getContinuation();
740 pathname =
new char[strlen(name) + 1];
741 strcpy(pathname, name);
746 info.encoding = mulawAudio;
749 ext = strrchr(pathname,
'.');
753 info.encoding = Audio::getEncoding(ext);
754 switch(info.encoding) {
758 case unknownEncoding:
759 info.encoding = mulawAudio;
764 strcpy((
char *)filehdr,
".xxx");
766 if(peek(filehdr, 24) < 1) {
771 if(!strncmp((
char *)filehdr,
"RIFF", 4)) {
776 if(!strncmp((
char *)filehdr,
"RIFX", 4)) {
781 if(!strncmp((
char *)filehdr + 8,
"WAVE", 4) && info.format == riff) {
789 if(peek(filehdr, 8) < 1) {
794 if(!strncmp((
char *)filehdr,
"data", 4))
797 count = getLong(filehdr + 4);
799 if(!strncmp((
char *)filehdr,
"fmt ", 4))
800 getWaveFormat(count);
807 if(!strncmp((
char *)filehdr,
".snd", 4)) {
810 header = getLong(filehdr + 4);
811 info.rate = getLong(filehdr + 16);
812 channels = getLong(filehdr + 20);
814 switch(getLong(filehdr + 12)) {
817 info.encoding = pcm8Stereo;
819 info.encoding = pcm8Mono;
822 if(info.rate == 44100) {
824 info.encoding = cdaStereo;
826 info.encoding = cdaMono;
830 info.encoding = pcm16Stereo;
832 info.encoding = pcm16Mono;
836 info.encoding = pcm32Stereo;
838 info.encoding = pcm32Mono;
841 info.encoding = g721ADPCM;
844 info.encoding = g722Audio;
847 info.encoding = g723_3bit;
850 info.encoding = g723_5bit;
853 info.encoding = alawAudio;
856 info.encoding = gsmVoice;
859 info.encoding = mulawAudio;
862 info.encoding = unknownEncoding;
865 info.annotation =
new char[header - 24];
867 read((
unsigned char *)info.annotation, header - 24);
877 info.setFraming(framing);
881 if(mode == modeFeed) {
882 fsys::fileinfo_t ino;
883 fsys::fileinfo(name, &ino);
884 iolimit = ino.st_size;
888 void AudioFile::close(
void)
890 unsigned char buf[58];
895 if(mode != modeWrite) {
907 if(-1 == peek(buf, 58)) {
913 switch(info.format) {
917 setLong(buf + 4, eof - 8);
921 switch(info.encoding) {
930 setLong(buf + 40, eof - header);
933 setLong(buf + 54, eof - header);
939 setLong(buf + 8, eof - header);
949 void AudioFile::clear(
void)
956 if(info.annotation) {
958 delete[] info.annotation;
959 info.annotation = NULL;
966 void AudioFile::initialize(
void)
971 info.annotation = NULL;
978 int AudioFile::getSamples(
void *addr,
unsigned request)
981 unsigned char *caddr = (
unsigned char *)addr;
982 ssize_t count, bytes;
985 request = info.framecount;
989 bytes = (int)toBytes(info, request);
992 count = read(caddr, bytes);
1001 count = request - toSamples(info.encoding, count);
1006 if(mode == modeFeed) {
1013 if(mode == modeReadOne)
1016 fname = getContinuation();
1022 AudioFile::open(fname, modeRead);
1024 if(mode == modeReadAny)
1032 Audio::fill(caddr, count, info.encoding);
1036 int AudioFile::putSamples(
void *addr,
unsigned samples)
1042 samples = info.framecount;
1044 bytes = (int)toBytes(info, samples);
1048 count = write((
unsigned char *)addr, bytes);
1057 ssize_t AudioFile::putBuffer(encoded_t addr,
size_t len)
1060 unsigned long curpos;
1063 len = info.framesize;
1065 curpos = (
unsigned long)toBytes(info, getPosition());
1066 if(curpos >= iolimit && mode == modeFeed) {
1071 if (iolimit && ((curpos + len) > iolimit))
1072 len = iolimit - curpos;
1077 count = write((
unsigned char *)addr, (
unsigned)len);
1078 if(count == (ssize_t)len)
1086 ssize_t AudioFile::getBuffer(encoded_t addr,
size_t bytes)
1091 unsigned long curpos, xfer = 0;
1094 bytes = info.framesize;
1096 curpos = (
unsigned long)toBytes(info, getPosition());
1097 if(curpos >= iolimit && mode == modeFeed) {
1101 if (iolimit && ((curpos + bytes) > iolimit))
1102 bytes = iolimit - curpos;
1110 count = read(addr, (
unsigned)bytes);
1117 if(count == (ssize_t)bytes)
1119 if(mode == modeFeed) {
1125 if(mode == modeReadOne)
1128 fname = getContinuation();
1133 AudioFile::open(fname, modeRead, info.framing);
1135 if(mode == modeReadAny)
1140 if(prior.encoding != info.encoding) {
1151 int AudioFile::setPosition(
unsigned long samples)
1154 fsys::fileinfo_t ino;
1161 if(samples == (
unsigned long)~0l)
1162 return seek(ino.st_size);
1164 offset = header + toBytes(info, samples);
1165 if(offset > (
size_t)ino.st_size)
1166 offset = ino.st_size;
1168 return seek(offset);
1171 unsigned long AudioFile::getPosition(
void)
1176 return toSamples(info, (pos - header));
1179 int AudioFile::setMinimum(
unsigned long samples)
1189 const char *AudioFile::getContinuation(
void)
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.