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
00044 #ifndef CCXX_AUDIO_H_
00045 #define CCXX_AUDIO_H_
00046
00047 #ifndef CCXX_PACKING
00048 #if defined(__GNUC__)
00049 #define CCXX_PACKED
00050 #elif !defined(__hpux) && !defined(_AIX)
00051 #define CCXX_PACKED
00052 #endif
00053 #endif
00054
00055 #ifndef W32
00056 #if defined(_WIN32) && defined(_MSC_VER)
00057 #define W32
00058 #endif
00059 #if defined(__BORLANDC__) && defined(__Windows)
00060 #define W32
00061 #endif
00062 #endif
00063
00064 #if !defined(__EXPORT) && defined(W32)
00065 #define __EXPORT __declspec(dllimport)
00066 #endif
00067
00068 #ifndef __EXPORT
00069 #define __EXPORT
00070 #endif
00071
00072 #ifdef W32
00073 #include <windows.h>
00074 #ifndef ssize_t
00075 #define ssize_t int
00076 #endif
00077 #else
00078 #include <cstddef>
00079 #include <cstdlib>
00080 #include <sys/types.h>
00081 #include <netinet/in.h>
00082 #endif
00083
00084 #include <ctime>
00085
00086 namespace ost {
00087
00088 #define AUDIO_SIGNED_LINEAR_RAW 1
00089 #define AUDIO_LINEAR_CONVERSION 1
00090 #define AUDIO_CODEC_MODULES 1
00091 #define AUDIO_LINEAR_FRAMING 1
00092 #define AUDIO_NATIVE_METHODS 1
00093
00094 class __EXPORT AudioCodec;
00095 class __EXPORT AudioDevice;
00096
00105 class __EXPORT Audio
00106 {
00107 public:
00108 #ifdef W32
00109 typedef short Sample;
00110 typedef short *Linear;
00111 typedef short Level;
00112 typedef DWORD timeout_t;
00113 typedef WORD snd16_t;
00114 typedef DWORD snd32_t;
00115 #else
00116 typedef int16_t snd16_t;
00117 typedef int32_t snd32_t;
00118 typedef int16_t Level;
00119 typedef int16_t Sample;
00120 typedef int16_t *Linear;
00121 typedef unsigned long timeout_t;
00122 #endif
00123
00124 typedef struct
00125 {
00126 float v2;
00127 float v3;
00128 float fac;
00129 } goertzel_state_t;
00130
00131 typedef struct
00132 {
00133 int hit1;
00134 int hit2;
00135 int hit3;
00136 int hit4;
00137 int mhit;
00138
00139 goertzel_state_t row_out[4];
00140 goertzel_state_t col_out[4];
00141 goertzel_state_t row_out2nd[4];
00142 goertzel_state_t col_out2nd[4];
00143 goertzel_state_t fax_tone;
00144 goertzel_state_t fax_tone2nd;
00145 float energy;
00146
00147 int current_sample;
00148 char digits[129];
00149 int current_digits;
00150 int detected_digits;
00151 int lost_digits;
00152 int digit_hits[16];
00153 int fax_hits;
00154 } dtmf_detect_state_t;
00155
00156 typedef struct
00157 {
00158 float fac;
00159 } tone_detection_descriptor_t;
00160
00161 typedef unsigned char *Encoded;
00162
00166 enum Rate
00167 {
00168 rateUnknown,
00169 rate6khz = 6000,
00170 rate8khz = 8000,
00171 rate16khz = 16000,
00172 rate44khz = 44100
00173 };
00174
00175 typedef enum Rate Rate;
00176
00180 enum Mode
00181 {
00182 modeRead,
00183 modeReadAny,
00184 modeReadOne,
00185 modeWrite,
00186 modeCache,
00187 modeInfo,
00188 modeFeed,
00189
00190 modeAppend,
00191 modeCreate
00192 };
00193
00194 typedef enum Mode Mode;
00195
00199 enum Encoding
00200 {
00201 unknownEncoding = 0,
00202 g721ADPCM,
00203 g722Audio,
00204 g722_7bit,
00205 g722_6bit,
00206 g723_2bit,
00207 g723_3bit,
00208 g723_5bit,
00209 gsmVoice,
00210 msgsmVoice,
00211 mulawAudio,
00212 alawAudio,
00213 mp1Audio,
00214 mp2Audio,
00215 mp3Audio,
00216 okiADPCM,
00217 voxADPCM,
00218 sx73Voice,
00219 sx96Voice,
00220
00221
00222
00223
00224 cdaStereo,
00225 cdaMono,
00226 pcm8Stereo,
00227 pcm8Mono,
00228 pcm16Stereo,
00229 pcm16Mono,
00230 pcm32Stereo,
00231 pcm32Mono,
00232
00233
00234 speexVoice,
00235 speexAudio
00236 };
00237 typedef enum Encoding Encoding;
00238
00242 enum Format
00243 {
00244 raw,
00245 snd,
00246 riff,
00247 mpeg,
00248 wave
00249 };
00250 typedef enum Format Format;
00251
00255 enum DeviceMode
00256 {
00257 PLAY,
00258 RECORD,
00259 PLAYREC
00260 };
00261 typedef enum DeviceMode DeviceMode;
00262
00266 enum Error
00267 {
00268 errSuccess = 0,
00269 errReadLast,
00270 errNotOpened,
00271 errEndOfFile,
00272 errStartOfFile,
00273 errRateInvalid,
00274 errEncodingInvalid,
00275 errReadInterrupt,
00276 errWriteInterrupt,
00277 errReadFailure,
00278 errWriteFailure,
00279 errReadIncomplete,
00280 errWriteIncomplete,
00281 errRequestInvalid,
00282 errTOCFailed,
00283 errStatFailed,
00284 errInvalidTrack,
00285 errPlaybackFailed,
00286 errNotPlaying,
00287 errNoCodec
00288 };
00289 typedef enum Error Error;
00290
00291
00292 #ifdef CCXX_PACKED
00293 #pragma pack(1)
00294 #endif
00295
00296 typedef struct
00297 {
00298 #if __BYTE_ORDER == __LITTLE_ENDIAN
00299 unsigned char mp_sync1 : 8;
00300 unsigned char mp_crc : 1;
00301 unsigned char mp_layer : 2;
00302 unsigned char mp_ver : 2;
00303 unsigned char mp_sync2 : 3;
00304
00305 unsigned char mp_priv : 1;
00306 unsigned char mp_pad : 1;
00307 unsigned char mp_srate : 2;
00308 unsigned char mp_brate : 4;
00309
00310 unsigned char mp_emp : 2;
00311 unsigned char mp_original : 1;
00312 unsigned char mp_copyright: 1;
00313 unsigned char mp_extend : 2;
00314 unsigned char mp_channels : 2;
00315
00316 #else
00317 unsigned char mp_sync1 : 8;
00318
00319 unsigned char mp_sync2 : 3;
00320 unsigned char mp_ver : 2;
00321 unsigned char mp_layer : 2;
00322 unsigned char mp_crc : 1;
00323
00324 unsigned char mp_brate : 4;
00325 unsigned char mp_srate : 2;
00326 unsigned char mp_pad : 1;
00327 unsigned char mp_priv : 1;
00328
00329 unsigned char mp_channels : 2;
00330 unsigned char mp_extend : 2;
00331 unsigned char mp_copyright : 1;
00332 unsigned char mp_original : 1;
00333 unsigned char mp_emp : 2;
00334 #endif
00335 } mpeg_audio;
00336
00337 typedef struct
00338 {
00339 char tag_id[3];
00340 char tag_title[30];
00341 char tag_artist[30];
00342 char tag_album[30];
00343 char tag_year[4];
00344 char tag_note[30];
00345 unsigned char genre;
00346 } mpeg_tagv1;
00347
00348 #ifdef CCXX_PACKED
00349 #pragma pack()
00350 #endif
00351
00355 class __EXPORT Info
00356 {
00357 public:
00358 Format format;
00359 Encoding encoding;
00360 unsigned long rate;
00361 unsigned long bitrate;
00362 unsigned order;
00363 unsigned framesize, framecount, headersize, padding;
00364 timeout_t framing;
00365 char *annotation;
00366
00367 Info();
00368 void clear(void);
00369 void set(void);
00370 void setFraming(timeout_t frame);
00371 };
00372
00379 static Level tolevel(float dbm);
00380
00387 static float todbm(Level power);
00388
00396 static bool hasDevice(unsigned device = 0);
00397
00408 static AudioDevice *getDevice(unsigned device = 0, DeviceMode mode = PLAY);
00409
00415 static const char *getCodecPath(void);
00416
00424 static const char *getMIME(Info &info);
00425
00433 static const char *getName(Encoding encoding);
00434
00442 static const char *getExtension(Encoding encoding);
00443
00454 static Encoding getEncoding(const char *name);
00455
00462 static Encoding getStereo(Encoding encoding);
00463
00470 static Encoding getMono(Encoding encoding);
00471
00478 static bool isLinear(Encoding encoding);
00479
00488 static bool isBuffered(Encoding encoding);
00489
00496 static bool isMono(Encoding encoding);
00497
00504 static bool isStereo(Encoding encoding);
00505
00513 static Rate getRate(Encoding encoding);
00514
00522 static timeout_t getFraming(Encoding encoding, timeout_t timeout = 0);
00523
00531 static timeout_t getFraming(Info &info, timeout_t timeout = 0);
00532
00540 static bool isEndian(Encoding encoding);
00541
00549 static bool isEndian(Info &info);
00550
00560 static bool swapEndian(Encoding encoding, void *buffer, unsigned number);
00561
00570 static void swapEncoded(Info &info, Encoded data, size_t bytes);
00571
00582 static bool swapEndian(Info &info, void *buffer, unsigned number);
00583
00592 static Level getImpulse(Encoding encoding, void *buffer, unsigned number);
00593
00602 static Level getImpulse(Info &info, void *buffer, unsigned number = 0);
00603
00613 static Level getPeak(Encoding encoding, void *buffer, unsigned number);
00614
00624 static Level getPeak(Info &info, void *buffer, unsigned number = 0);
00625
00633 static void toTimestamp(timeout_t duration, char *address, size_t size);
00634
00641 static timeout_t toTimeout(const char *timestamp);
00642
00665 static int getFrame(Encoding encoding, int samples = 0);
00666
00679 static int getCount(Encoding encoding);
00680
00689 static unsigned long toSamples(Encoding encoding, size_t bytes);
00690
00699 static unsigned long toSamples(Info &info, size_t bytes);
00700
00709 static size_t toBytes(Info &info, unsigned long number);
00710
00719 static size_t toBytes(Encoding encoding, unsigned long number);
00720
00729 static void fill(unsigned char *address, int number, Encoding encoding);
00730
00737 static bool loadPlugin(const char *path);
00738
00746 static size_t maxFramesize(Info &info);
00747 };
00748
00757 class __EXPORT AudioTone : public Audio
00758 {
00759 protected:
00760 Rate rate;
00761 unsigned samples;
00762 Linear frame;
00763 double df1, df2, p1, p2;
00764 Level m1, m2;
00765 bool silencer;
00766
00770 void silence(void);
00771
00775 void reset(void);
00776
00780 void cleanup(void);
00781
00788 void single(unsigned freq, Level level);
00789
00798 void dual(unsigned f1, unsigned f2, Level l1, Level l2);
00799
00800 public:
00806 inline Rate getRate(void)
00807 {return rate;};
00808
00814 inline size_t getSamples(void)
00815 {return samples;};
00816
00822 bool isSilent(void);
00823
00831 virtual Linear getFrame(void);
00832
00841 unsigned getFrames(Linear buffer, unsigned number);
00842
00849 virtual bool isComplete(void);
00850
00857 AudioTone(timeout_t duration = 20, Rate rate = rate8khz);
00858
00869 AudioTone(unsigned f1, unsigned f2, Level l1, Level l2,
00870 timeout_t duration = 20, Rate sample = rate8khz);
00871
00880 AudioTone(unsigned freq, Level level, timeout_t duration = 20, Rate sample = rate8khz);
00881
00882 virtual ~AudioTone();
00883 };
00884
00891 class __EXPORT AudioBase : public Audio
00892 {
00893 protected:
00894 Info info;
00895
00896 public:
00900 AudioBase();
00901
00907 AudioBase(Info *info);
00908
00912 virtual ~AudioBase();
00913
00919 inline Encoding getEncoding(void)
00920 {return info.encoding;};
00921
00927 inline unsigned getSampleRate(void)
00928 {return info.rate;};
00929
00937 virtual ssize_t putBuffer(Encoded data, size_t size) = 0;
00938
00947 ssize_t putNative(Encoded data, size_t size);
00948
00956 virtual ssize_t getBuffer(Encoded data, size_t size) = 0;
00957
00965 ssize_t getNative(Encoded data, size_t size);
00966 };
00967
00975 class __EXPORT AudioBuffer : public AudioBase
00976 {
00977 public:
00978 AudioBuffer(Info *info, size_t size = 4096);
00979 virtual ~AudioBuffer();
00980
00988 ssize_t getBuffer(Encoded data, size_t number);
00989
00997 ssize_t putBuffer(Encoded data, size_t number);
00998
00999 private:
01000 char *buf;
01001 size_t size, start, len;
01002 void *mutexObject;
01003
01004 void enter(void);
01005 void leave(void);
01006 };
01007
01016 class __EXPORT AudioFile: public AudioBase
01017 {
01018 protected:
01019 char *pathname;
01020 Error error;
01021 unsigned long header;
01022 unsigned long minimum;
01023 unsigned long length;
01024
01025 void initialize(void);
01026 void getWaveFormat(int size);
01027 void mp3info(mpeg_audio *mp3);
01028
01029 union
01030 {
01031 int fd;
01032 void *handle;
01033 } file;
01034
01035 Mode mode;
01036 unsigned long iolimit;
01037
01038 virtual bool afCreate(const char *path, bool exclusive = false);
01039 virtual bool afOpen(const char *path, Mode m = modeWrite);
01040 virtual bool afPeek(unsigned char *data, unsigned size);
01041
01042 AudioCodec *getCodec(void);
01043
01056 virtual int afRead(unsigned char *data, unsigned size);
01057
01069 virtual int afWrite(unsigned char *data, unsigned size);
01070
01080 virtual bool afSeek(unsigned long pos);
01081
01085 virtual void afClose(void);
01086
01094 virtual char *getContinuation(void)
01095 {return NULL;};
01096
01105 const char * getErrorStr(Error err);
01106
01107 Error setError(Error err);
01108
01115 inline unsigned long getHeader(void)
01116 {return header;};
01117
01126 unsigned short getShort(unsigned char *data);
01127
01136 void setShort(unsigned char *data, unsigned short value);
01137
01146 unsigned long getLong(unsigned char *data);
01147
01156 void setLong(unsigned char *data, unsigned long value);
01157
01158 public:
01165 AudioFile(const char *name, unsigned long offset = 0);
01166
01174 AudioFile(const char *name, Info *info, unsigned long minimum = 0);
01175
01179 inline AudioFile()
01180 {initialize();};
01181
01182 virtual ~AudioFile();
01183
01194 void open(const char *name, Mode mode = modeWrite, timeout_t framing = 0);
01195
01206 void create(const char *name, Info *info, bool exclusive = false, timeout_t framing = 0);
01207
01214 time_t getAge(void);
01215
01221 inline size_t getSize(void)
01222 {return maxFramesize(info);};
01223
01229 void close(void);
01230
01238 void clear(void);
01239
01251 ssize_t getBuffer(Encoded buffer, size_t len = 0);
01252
01261 unsigned getLinear(Linear buffer, unsigned request = 0);
01262
01274 ssize_t putBuffer(Encoded buffer, size_t len = 0);
01275
01284 unsigned putLinear(Linear buffer, unsigned request = 0);
01285
01300 Error getSamples(void *buffer, unsigned samples = 0);
01301
01315 Error putSamples(void *buffer, unsigned samples = 0);
01316
01324 Error skip(long number);
01325
01333 Error setPosition(unsigned long samples = ~0l);
01334
01342 Error position(const char *timestamp);
01343
01350 void getPosition(char *timestamp, size_t size);
01351
01359 Error setLimit(unsigned long maximum = 0l);
01360
01368 Error getInfo(Info *info);
01369
01378 Error setMinimum(unsigned long minimum);
01379
01389 unsigned long getAbsolutePosition(void);
01390
01402 unsigned long getPosition(void);
01403
01409 virtual bool isOpen(void);
01410
01418 virtual bool hasPositioning(void)
01419 {return true;};
01420
01426 inline Encoding getEncoding(void)
01427 {return info.encoding;};
01428
01434 inline Format getFormat(void)
01435 {return info.format;};
01436
01443 inline unsigned getSampleRate(void)
01444 {return info.rate;};
01445
01451 inline char *getAnnotation(void)
01452 {return info.annotation;};
01453
01459 inline Error getError(void)
01460 {return error;};
01461
01462 inline bool operator!(void)
01463 {return (bool)!isOpen();};
01464
01470 bool isSigned(void);
01471 };
01472
01484 class __EXPORT AudioStream : public AudioFile
01485 {
01486 protected:
01487 AudioCodec *codec;
01488 Encoded framebuf;
01489 bool streamable;
01490 Linear bufferFrame;
01491 unsigned bufferPosition;
01492 unsigned bufferChannels;
01493 Linear encBuffer, decBuffer;
01494 unsigned encSize, decSize;
01495
01496 unsigned bufAudio(Linear samples, unsigned count, unsigned size);
01497
01498 public:
01502 AudioStream();
01503
01511 AudioStream(const char *name, Mode mode = modeRead, timeout_t framing = 0);
01512
01521 AudioStream(const char *name, Info *info, bool exclusive = false, timeout_t framing = 0);
01522
01523 virtual ~AudioStream();
01524
01532 void open(const char *name, Mode mode = modeRead, timeout_t framing = 0);
01533
01542 void create(const char *name, Info *info, bool exclusive = false, timeout_t framing = 0);
01543
01547 void close(void);
01548
01552 void flush(void);
01553
01560 bool isStreamable(void);
01561
01565 unsigned getCount(void);
01566
01576 unsigned getEncoded(AudioCodec *codec, Encoded address, unsigned frames = 1);
01577
01587 unsigned putEncoded(AudioCodec *codec, Encoded address, unsigned frames = 1);
01588
01596 unsigned getEncoded(Encoded address, unsigned frames = 1);
01597
01605 unsigned putEncoded(Encoded address, unsigned frames = 1);
01606
01615 unsigned getMono(Linear buffer, unsigned frames = 1);
01616
01625 unsigned getStereo(Linear buffer, unsigned frames = 1);
01626
01635 unsigned putMono(Linear buffer, unsigned frames = 1);
01636
01645 unsigned putStereo(Linear buffer, unsigned frames = 1);
01646
01656 unsigned bufMono(Linear buffer, unsigned count);
01657
01667 unsigned bufStereo(Linear buffer, unsigned count);
01668
01674 inline AudioCodec *getCodec(void)
01675 {return codec;};
01676 };
01677
01690 class __EXPORT AudioCodec : public Audio
01691 {
01692 protected:
01693 static AudioCodec *first;
01694 AudioCodec *next;
01695 Encoding encoding;
01696 const char *name;
01697 Info info;
01698
01699 AudioCodec();
01700
01708 virtual AudioCodec *getByFormat(const char *format)
01709 {return this;};
01710
01717 virtual AudioCodec *getByInfo(Info &info)
01718 {return this;};
01719
01720 public:
01727 AudioCodec(const char *name, Encoding encoding);
01728
01729 virtual ~AudioCodec() {};
01730
01737 static void endCodec(AudioCodec *codec);
01738
01748 static AudioCodec *getCodec(Encoding encoding, const char *format = NULL, bool loaded = false);
01749
01758 static AudioCodec *getCodec(Info &info, bool loaded = false);
01759
01766 static bool load(const char *name);
01767
01775 static bool load(Encoding encoding);
01776
01785 virtual Level getImpulse(void *buffer, unsigned number = 0);
01786
01794 virtual Level getPeak(void *buffer, unsigned number = 0);
01795
01806 virtual bool isSilent(Level threashold, void *buffer, unsigned number = 0);
01807
01817 virtual unsigned encode(Linear buffer, void *dest, unsigned number = 0, bool buffered = false) = 0;
01818
01828 virtual unsigned decode(Linear buffer, void *source, unsigned number = 0, bool buffered = false) = 0;
01829
01835 inline Info getInfo(void)
01836 {return info;};
01837 };
01838
01839 class __EXPORT AudioDevice : public AudioBase
01840 {
01841 protected:
01842 bool enabled;
01843
01844 public:
01845 virtual ~AudioDevice() {};
01846
01854 virtual unsigned putSamples(Linear buffer, unsigned count) = 0;
01855
01863 virtual unsigned getSamples(Linear buffer, unsigned count) = 0;
01864
01873 virtual ssize_t putBuffer(Encoded data, size_t count);
01874
01883 virtual ssize_t getBuffer(Encoded data, size_t count);
01884
01892 virtual bool setEncoded(Info &info)
01893 {return false;};
01894
01903 virtual bool setAudio(Rate rate = rate8khz, bool stereo = false, timeout_t framing = 20) = 0;
01904
01911 virtual void sync(void)
01912 {return;};
01913
01917 virtual void flush(void) = 0;
01918
01928 unsigned bufMono(Linear buffer, unsigned count);
01929
01939 unsigned bufStereo(Linear buffer, unsigned count);
01940
01946 inline Info *getInfo(void)
01947 {return &info;};
01948
01957 inline bool isEnabled(void)
01958 {return enabled;};
01959 };
01960
01969 class __EXPORT TelTone : public AudioTone
01970 {
01971 public:
01972 typedef struct _tonedef
01973 {
01974 struct _tonedef *next;
01975 timeout_t duration, silence;
01976 unsigned count;
01977 unsigned short f1, f2;
01978 } tonedef_t;
01979
01980 typedef struct _tonekey
01981 {
01982 struct _tonekey *next;
01983 struct _tonedef *first;
01984 struct _tonedef *last;
01985 char id[1];
01986 } tonekey_t;
01987
01996 TelTone(tonekey_t *key, Level level, timeout_t frame = 20);
01997 ~TelTone();
01998
02005 Linear getFrame(void);
02006
02013 bool isComplete(void);
02014
02015
02023 static bool load(const char *pathname, const char *locale = NULL);
02024
02032 static tonekey_t *find(const char *tone, const char *locale = NULL);
02033
02034 protected:
02035 tonekey_t *tone;
02036 tonedef_t *def;
02037 unsigned remaining, silent, count;
02038 timeout_t framing;
02039 Level level;
02040 bool complete;
02041 };
02042
02052 class __EXPORT DTMFTones : public AudioTone
02053 {
02054 protected:
02055 unsigned remaining, dtmfframes;
02056 timeout_t frametime;
02057 const char *digits;
02058 Level level;
02059 bool complete;
02060
02061 public:
02070 DTMFTones(const char *digits, Level level, timeout_t duration = 20, timeout_t interdigit = 60);
02071
02072 ~DTMFTones();
02073
02074 Linear getFrame(void);
02075 bool isComplete(void);
02076 };
02077
02087 class __EXPORT MFTones : public AudioTone
02088 {
02089 protected:
02090 unsigned remaining, mfframes;
02091 timeout_t frametime;
02092 const char *digits;
02093 Level level;
02094 bool complete, kflag;
02095
02096 public:
02105 MFTones(const char *digits, Level level, timeout_t duration = 20, timeout_t interdigit = 60);
02106
02107 ~MFTones();
02108
02109 Linear getFrame(void);
02110 bool isComplete(void);
02111 };
02112
02113
02118 class __EXPORT DTMFDetect : public Audio
02119 {
02120 public:
02121 DTMFDetect();
02122 ~DTMFDetect();
02123
02132 int putSamples(Linear buffer, int count);
02133
02140 int getResult(char *data, int size);
02141
02142 protected:
02143 void goertzelInit(goertzel_state_t *s, tone_detection_descriptor_t *t);
02144 void goertzelUpdate(goertzel_state_t *s, Sample x[], int samples);
02145 float goertzelResult(goertzel_state_t *s);
02146
02147 private:
02148 dtmf_detect_state_t *state;
02149 tone_detection_descriptor_t dtmf_detect_row[4];
02150 tone_detection_descriptor_t dtmf_detect_col[4];
02151 tone_detection_descriptor_t dtmf_detect_row_2nd[4];
02152 tone_detection_descriptor_t dtmf_detect_col_2nd[4];
02153 tone_detection_descriptor_t fax_detect;
02154 tone_detection_descriptor_t fax_detect_2nd;
02155 };
02156
02157 }
02158
02159 #endif
02160