#ifndef BUFFER_H #define BUFFER_H #include #include #include #include "sound.h" /* ---------------------------------------------------------------------- */ /* *.wav I/O stolen from cdda2wav */ /* Copyright (C) by Heiko Eissfeldt */ typedef uint8_t BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; typedef uint32_t FOURCC; /* a four character code */ /* flags for 'wFormatTag' field of WAVEFORMAT */ #define WAVE_FORMAT_PCM 1 /* MMIO macros */ #define mmioFOURCC(ch0, ch1, ch2, ch3) \ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24)) #define FOURCC_RIFF mmioFOURCC ('R', 'I', 'F', 'F') #define FOURCC_LIST mmioFOURCC ('L', 'I', 'S', 'T') #define FOURCC_WAVE mmioFOURCC ('W', 'A', 'V', 'E') #define FOURCC_FMT mmioFOURCC ('f', 'm', 't', ' ') #define FOURCC_DATA mmioFOURCC ('d', 'a', 't', 'a') typedef struct CHUNKHDR { FOURCC ckid; /* chunk ID */ DWORD dwSize; /* chunk size */ } CHUNKHDR; /* simplified Header for standard WAV files */ typedef struct WAVEHDR { CHUNKHDR chkRiff; FOURCC fccWave; CHUNKHDR chkFmt; WORD wFormatTag; /* format type */ WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */ DWORD nSamplesPerSec; /* sample rate */ DWORD nAvgBytesPerSec; /* for buffer estimation */ WORD nBlockAlign; /* block size of data */ WORD wBitsPerSample; CHUNKHDR chkData; } WAVEHDR; #define IS_STD_WAV_HEADER(waveHdr) ( \ waveHdr.chkRiff.ckid == FOURCC_RIFF && \ waveHdr.fccWave == FOURCC_WAVE && \ waveHdr.chkFmt.ckid == FOURCC_FMT && \ waveHdr.chkData.ckid == FOURCC_DATA && \ waveHdr.wFormatTag == WAVE_FORMAT_PCM) /* ---------------------------------------------------------------------- */ class AudioBuffer { protected: struct SOUNDPARAMS params; int size; int busy; int position; public: AudioBuffer(); virtual ~AudioBuffer(); int clippedsamples; int is_busy(); void balloc(void); void bfree(void); virtual int start_write(struct SOUNDPARAMS *p); /* write */ virtual void stop_write(); /* can flush etc. */ virtual struct SOUNDPARAMS *get_params(); /* after recording or */ virtual int get_size(); /* for file readling */ virtual char *name(); virtual void *read_audio(int len); /* no comment ... */ virtual int write_audio(int len, void *data); virtual int seek(int pos); virtual int tell(); }; class RAMBuffer : public AudioBuffer { private: char **buffers; int bufcount; char bufname[32]; public: RAMBuffer(); virtual ~RAMBuffer(); virtual int start_write(struct SOUNDPARAMS *p); virtual void stop_write(); virtual struct SOUNDPARAMS *get_params(); virtual int get_size(); virtual char *name(); virtual void *read_audio(int len); virtual int write_audio(int len, void *data); virtual int seek(int pos); virtual int tell(); }; class FileBuffer : public AudioBuffer { private: int fd,ro; int offset,bstart,bstop; char filename[256]; WAVEHDR fileheader; char buffer[65536]; void init_header(); int parse_header(); public: FileBuffer(); virtual ~FileBuffer(); int attach(const char *file); virtual int start_write(struct SOUNDPARAMS *p); virtual void stop_write(); virtual struct SOUNDPARAMS *get_params(); virtual int get_size(); virtual char *name(); virtual void *read_audio(int len); virtual int write_audio(int len, void *data); virtual int seek(int pos); virtual int tell(); }; /* -- functions -------------------------------------------------------- */ class BufferList : public QObject { Q_OBJECT; public: BufferList(QListBox *l, Soundcard *c); int add_filebuffer(const char *filename); void save_buf(const char *filename); private: QListBox *listbox; Soundcard *card; int mon,level,wait; struct SOUNDPARAMS params; AudioBuffer **buffers; int count,brecord,bplayback; int new_buffer_count; int add_rambuffer(); void add_buffer(AudioBuffer *buf); void label_buffer(int buf); void del_buffer(int buf); void istop(); void set_pos_size(const char *start, int buf); public slots: void new_params(struct SOUNDPARAMS *params); void new_data(void *data); void post_data(void *data); void new_ram(); void del_buf(); void set_level(int l); void monitor(); void record(); void stop(); void play(); void forward(); void backward(); void next_buffer(); signals: void status(const char *text); }; #endif