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
00038
00039
00040
00041 #ifndef CCXX_AUDIO_H_
00042 #define CCXX_AUDIO_H_
00043
00044 #ifndef CCXX_CONFIG_H_
00045 #include <cc++/config.h>
00046 #endif
00047
00048 #ifndef CCXX_THREAD_H_
00049 #include <cc++/thread.h>
00050 #endif
00051
00052 #ifdef CCXX_NAMESPACES
00053 namespace ost {
00054 #endif
00055
00056 #define AUDIO_SIGNED_LINEAR_RAW 1
00057 #define AUDIO_LINEAR_CONVERSION 1
00058 #define AUDIO_CODEC_MODULES 1
00059
00060 typedef signed short *Linear;
00061
00062 typedef struct
00063 {
00064 float v2;
00065 float v3;
00066 float fac;
00067 } goertzel_state_t;
00068
00069 typedef struct
00070 {
00071 int hit1;
00072 int hit2;
00073 int hit3;
00074 int hit4;
00075 int mhit;
00076
00077 goertzel_state_t row_out[4];
00078 goertzel_state_t col_out[4];
00079 goertzel_state_t row_out2nd[4];
00080 goertzel_state_t col_out2nd[4];
00081 goertzel_state_t fax_tone;
00082 goertzel_state_t fax_tone2nd;
00083 float energy;
00084
00085 int current_sample;
00086 char digits[129];
00087 int current_digits;
00088 int detected_digits;
00089 int lost_digits;
00090 int digit_hits[16];
00091 int fax_hits;
00092 } dtmf_detect_state_t;
00093
00094 typedef struct
00095 {
00096 float fac;
00097 } tone_detection_descriptor_t;
00098
00099 class AudioCodec;
00100
00109 class CCXX_CLASS_EXPORT Audio
00110 {
00111 public:
00112 enum Rate
00113 {
00114 rateUnknown,
00115 rate6khz = 6000,
00116 rate8khz = 8000,
00117 rate44khz = 44100
00118 };
00119 typedef enum Rate Rate;
00120
00121 enum Encoding
00122 {
00123 unknownEncoding = 0,
00124 g721ADPCM,
00125 g722Audio,
00126 g722_7bit,
00127 g722_6bit,
00128 g723_3bit,
00129 g723_5bit,
00130 gsmVoice,
00131 mulawAudio,
00132 alawAudio,
00133 okiADPCM,
00134 voxADPCM,
00135
00136
00137
00138
00139 cdaStereo,
00140 cdaMono,
00141 pcm8Stereo,
00142 pcm8Mono,
00143 pcm16Stereo,
00144 pcm16Mono,
00145 pcm32Stereo,
00146 pcm32Mono
00147 };
00148 typedef enum Encoding Encoding;
00149
00150 enum Format
00151 {
00152 raw,
00153 sun,
00154 riff,
00155 wave
00156 };
00157 typedef enum Format Format;
00158
00159 enum Error
00160 {
00161 errSuccess = 0,
00162 errReadLast,
00163 errNotOpened,
00164 errEndOfFile,
00165 errStartOfFile,
00166 errRateInvalid,
00167 errEncodingInvalid,
00168 errReadInterrupt,
00169 errWriteInterrupt,
00170 errReadFailure,
00171 errWriteFailure,
00172 errReadIncomplete,
00173 errWriteIncomplete,
00174 errRequestInvalid,
00175 errTOCFailed,
00176 errStatFailed,
00177 errInvalidTrack,
00178 errPlaybackFailed,
00179 errNotPlaying,
00180 errNoCodec
00181 };
00182 typedef enum Error Error;
00183
00184 class Info
00185 {
00186 public:
00187 Format format;
00188 Encoding encoding;
00189 unsigned rate;
00190 unsigned order;
00191 char *annotation;
00192 };
00193
00194 static bool isMono(Encoding encoding);
00195 static bool isStereo(Encoding encoding);
00196 static Rate getRate(Encoding encoding);
00197
00220 static int getFrame(Encoding encoding, int samples = 0);
00221
00234 static int getCount(Encoding encoding);
00235 static unsigned long toSamples(Encoding encoding, size_t bytes);
00236 static unsigned long toBytes(Encoding encoding, unsigned long samples);
00237 static void fill(unsigned char *addr, int samples, Encoding encoding);
00238 };
00239
00248 class CCXX_CLASS_EXPORT AudioFile: public Audio
00249 {
00250 private:
00251 char *pathname;
00252 Error error;
00253 Info info;
00254 unsigned long header;
00255 unsigned long minimum;
00256 unsigned long length;
00257
00258
00259 bool modified;
00260
00261 void initialize(void);
00262 void getWaveFormat(int size);
00263
00264 protected:
00265 union
00266 {
00267 int fd;
00268 void *handle;
00269 } file;
00270
00271 unsigned long limit;
00272
00273 virtual bool afCreate(const char *path);
00274 virtual bool afOpen(const char *path);
00275 virtual bool afPeek(unsigned char *data, unsigned size);
00276
00277 AudioCodec *getCodec(void);
00278
00291 virtual int afRead(unsigned char *data, unsigned size);
00292
00304 virtual int afWrite(unsigned char *data, unsigned size);
00305
00315 virtual bool afSeek(unsigned long pos);
00316 virtual void afClose(void);
00317
00318 virtual char *getContinuation(void)
00319 {return NULL;};
00320
00329 const char * getErrorStr(Error err);
00330 Error setError(Error err);
00331
00332 unsigned long getHeader(void)
00333 {return header;};
00334
00335 unsigned short getShort(unsigned char *data);
00336 void setShort(unsigned char *data, unsigned short value);
00337 unsigned long getLong(unsigned char *data);
00338 void setLong(unsigned char *data, unsigned long value);
00339
00340 public:
00341 AudioFile(const char *fname, unsigned long samples = 0);
00342 AudioFile(const char *fname, Info *info, unsigned long min = 0);
00343
00344 AudioFile()
00345 {initialize();};
00346
00347 virtual ~AudioFile()
00348 {clear();};
00349
00358 void open(const char *fname);
00359
00368 void create(const char *fname, Info *info);
00369
00375 void close(void);
00376
00384 void clear(void);
00385
00397 int getBuffer(void *addr, unsigned len);
00398
00407 unsigned getLinear(Linear buffer, unsigned request);
00408
00421 int putBuffer(void *attr, unsigned len);
00422
00431 unsigned putLinear(Linear buffer, unsigned request);
00432
00447 Error getSamples(void *addr, unsigned samples);
00448
00463 Error putSamples(void *addr, unsigned samples);
00464 Error skip(long samples);
00465 Error setPosition(unsigned long samples = ~0l);
00466 Error setLimit(unsigned long samples = 0l);
00467 Error getInfo(Info *info);
00468 Error setMinimum(unsigned long samples);
00469
00479 unsigned long getAbsolutePosition(void);
00480
00492 unsigned long getPosition(void);
00493 virtual bool isOpen(void);
00494 virtual bool hasPositioning(void)
00495 {return true;};
00496
00497 inline Encoding getEncoding(void)
00498 {return info.encoding;};
00499
00500 inline Format getFormat(void)
00501 {return info.format;};
00502
00503 inline unsigned getSampleRate(void)
00504 {return info.rate;};
00505
00506 inline char *getAnnotation(void)
00507 {return info.annotation;};
00508
00509 inline Error getError(void)
00510 {return error;};
00511
00512 inline bool operator!(void)
00513 {return (bool)!isOpen();};
00514
00520 bool isSigned(void);
00521 };
00522
00531 class CCXX_CLASS_EXPORT CDAudio : public Audio
00532 {
00533 private:
00534 union
00535 {
00536 int fd;
00537 void *handle;
00538 } file;
00539 unsigned char v0, v1;
00540 #ifdef __WIN32__
00541 CRITICAL_SECTION crit;
00542 bool paused;
00543 bool opened;
00544 char position[20];
00545 char endmark[24];
00546 char ret[256];
00547 DWORD command(char *fmt, ...);
00548 #endif
00549 Error err;
00550
00551 public:
00552 CDAudio(int devnbr = 0);
00553 ~CDAudio();
00554
00555 Error play(int start, int end = 0);
00556 Error stop(void);
00557 Error pause(void);
00558 Error resume(void);
00559 Error eject(void);
00560 Error reload(void);
00561 int getFirst(void);
00562 int getLast(void);
00563 bool isPaused(void);
00564 bool isAudio(int track);
00565 bool isOpen(void);
00566
00567 unsigned char getVolume(int speaker);
00568 void setVolume(unsigned char left, unsigned char right);
00569
00570 inline unsigned char getVolumeLeft(void)
00571 {return getVolume(0);};
00572
00573 inline unsigned char getVolumeRight(void)
00574 {return getVolume(1);};
00575
00576 inline Error getError(void)
00577 {return err;};
00578
00579 inline bool operator!(void)
00580 {return (bool)!isOpen();};
00581 };
00582
00589 class CCXX_CLASS_EXPORT AudioSample : public Audio
00590 {
00591 protected:
00592 friend class AudioCopy;
00593
00594 Encoding encoding;
00595 unsigned rate;
00596 unsigned count;
00597 unsigned char *samples;
00598
00599 public:
00600 AudioSample(unsigned frame, Encoding coding = pcm16Mono, unsigned rate = 8000);
00601 ~AudioSample();
00602
00603 inline unsigned getCount(void)
00604 {return count;};
00605
00606 inline unsigned getRate(void)
00607 {return rate;};
00608
00609 inline Encoding getEncoding(void)
00610 {return encoding;};
00611
00612 inline unsigned char *getSamples(void)
00613 {return samples;};
00614 };
00615
00621 class CCXX_CLASS_EXPORT LinearSample : public AudioSample
00622 {
00623 public:
00624 LinearSample(unsigned frame, unsigned rate = 8000) :
00625 AudioSample(frame, pcm16Mono, rate) {};
00626
00627 inline short *getSamples(void)
00628 {return (short *)samples;};
00629 };
00630
00643 class CCXX_CLASS_EXPORT AudioCodec : public Audio
00644 {
00645 protected:
00646 static Mutex lock;
00647 static AudioCodec *first;
00648 AudioCodec *next;
00649 Encoding encoding;
00650 const char *name;
00651
00652 public:
00653 AudioCodec(const char *n, Encoding e);
00654 virtual ~AudioCodec() {};
00655
00656 static AudioCodec *getCodec(Encoding encoding, const char *name = NULL);
00657 static bool load(const char *name);
00658
00667 virtual unsigned encode(Linear buffer, void *dest, unsigned lsamples) = 0;
00668
00677 virtual unsigned decode(Linear buffer, void *source, unsigned lsamples) = 0;
00678 };
00679
00688 class CCXX_CLASS_EXPORT AudioTone : public AudioSample
00689 {
00690 protected:
00691 double p1, p2, v1, v2, fa1, fa2;
00692
00693 public:
00694 AudioTone(unsigned size, unsigned f1 = 0, unsigned f2 = 0, unsigned rate = 8000);
00695
00699 void fill(unsigned max = 0);
00700
00701
00702
00703
00704
00705
00706
00707 void setFreq(unsigned f1, unsigned f2 = 0);
00708 };
00709
00720 class CCXX_CLASS_EXPORT AudioCopy : public AudioSample
00721 {
00722 protected:
00723 unsigned char *next;
00724 unsigned left;
00725
00726 virtual AudioSample *fill(void) = 0;
00727
00728 public:
00729 AudioCopy(unsigned frame, Encoding encoding = pcm16Mono, unsigned rate = 8000);
00730 virtual ~AudioCopy() {};
00731 bool copy(void);
00732
00733 inline bool isEmpty(void)
00734 {return next == NULL;};
00735 };
00736
00742 class CCXX_CLASS_EXPORT DTMFDetect
00743 {
00744 public:
00745 DTMFDetect();
00746 ~DTMFDetect();
00747
00748 int putSamples(int16_t buffer[], int count);
00749 int getResult(char *buf, int max);
00750 protected:
00751 void goertzelInit(goertzel_state_t *s, tone_detection_descriptor_t *t);
00752 void goertzelUpdate(goertzel_state_t *s, int16_t x[], int samples);
00753 float goertzelResult(goertzel_state_t *s);
00754 private:
00755 dtmf_detect_state_t *state;
00756 tone_detection_descriptor_t dtmf_detect_row[4];
00757 tone_detection_descriptor_t dtmf_detect_col[4];
00758 tone_detection_descriptor_t dtmf_detect_row_2nd[4];
00759 tone_detection_descriptor_t dtmf_detect_col_2nd[4];
00760 tone_detection_descriptor_t fax_detect;
00761 tone_detection_descriptor_t fax_detect_2nd;
00762 };
00763
00764 #ifdef CCXX_NAMESPACES
00765 };
00766 #endif
00767
00768 #endif
00769