aboutsummaryrefslogtreecommitdiffstats
path: root/buffer.h
blob: 5bf635ee4d21322ab59e2a85eb5bf1e80d5ad13b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#ifndef BUFFER_H
#define BUFFER_H

#include <inttypes.h>
#include <qobject.h>
#include <qlistbox.h>

#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