summaryrefslogtreecommitdiffstats
path: root/applications/rview/rviewSound.hh
blob: e6a156ab8fae2f6ae37b3824de6c685c2cdc4b10 (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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see <http://www.rasdaman.org>
* or contact Peter Baumann via <baumann@rasdaman.com>.
/

/**
 *  PURPOSE:
 *
 *  rView sound ``viewer'' for playing back MDD as audio samples.
 *  This file consists of two parts: the highly platform dependent
 *  SoundPlayer class providing the actual low-level sound playback
 *  and the general purpose wxWindows class rviewSoundPlayer that
 *  implements a typical rView display mode window and playback
 *  controls.
 *  The SoundPlayer class currently has implementations for Solaris
 *  and WindowsNT. Supporting other Unix brands only requires
 *  changes to SoundPlayer::configureDevice, supporting other
 *  platforms is considerably more complicated (see Unix vs. NT
 *  implementations).
 *
 *	COMMENTS:
 * 		None
 */



#ifndef _RVIEW_SOUND_H_
#define _RVIEW_SOUND_H_


#include <stdio.h>
#include <signal.h>

#ifdef __VISUALC__
#include <windows.h>
#endif


#ifdef __HAL_ONLY__
#ifndef __VISUALC__
#include "bool.h"
#endif
typedef bool bool;
#ifndef TRUE
#define TRUE true
#define FALSE false
#endif
#else
#include "rviewUtils.hh"
#include "rviewDisplay.hh"
#endif // HAL



/* Default latency of sound playback */
#define RVIEW_SND_LATENCY   100
/* Timer interval relative to sample buffer runtime */
#define RVIEW_SND_RELPERIOD 0.5

/* Number of sample buffers (NT only) */
#define RVIEW_SND_BUFFERS   3


enum rviewSoundFormat {
  rsf_none,
  rsf_lin8,
  rsf_ulin8,
  rsf_ulaw8,
  rsf_lin16
};



/*
 *  soundPlayer: hardware abstraction layer
 */

class soundPlayer
{
  public:

  // Base constructor
  soundPlayer(void);
  // Constructor for input from file
  soundPlayer(int frq, int ch, FILE *fp, rviewSoundFormat fmt, int lat=RVIEW_SND_LATENCY);
  // Constructor for 8bit linear (default)
  soundPlayer(int frq, int ch, const signed char *data, int len, rviewSoundFormat fmt=rsf_lin8, int lat=RVIEW_SND_LATENCY);
  // Constructor for 8bit ulaw (default)
  soundPlayer(int frq, int ch, const unsigned char *data, int len, rviewSoundFormat fmt=rsf_ulaw8, int lat=RVIEW_SND_LATENCY);
  // Constructor for 16bit linear (default)
  soundPlayer(int frq, int ch, const short *data, int len, rviewSoundFormat fmt=rsf_lin16, int lat=RVIEW_SND_LATENCY);

  ~soundPlayer(void);

  // For changing during playback
  int newSample(int frq, int ch, FILE *fp, rviewSoundFormat fmt, int lat=RVIEW_SND_LATENCY);
  int newSample(int frq, int ch, const signed char *data, int len, rviewSoundFormat=rsf_lin8, int lat=RVIEW_SND_LATENCY);
  int newSample(int frq, int ch, const unsigned char *data, int len, rviewSoundFormat=rsf_ulaw8, int lat=RVIEW_SND_LATENCY);
  int newSample(int frq, int ch, const short *data, int len, rviewSoundFormat=rsf_lin16, int lat=RVIEW_SND_LATENCY);

  int playbackGetOffset(void);
  int playbackActive(void);
  void playbackSuspend(void);
  void playbackResume(void);
  void playbackStop(void);
  int  playbackSetPosition(int position);
  int  playbackLoopMode(int lpMode);

#ifdef __VISUALC__
  void writeSamples(DWORD systime);
#else
  void writeSamples(void);
#endif


  protected:

  void setupVariables(void);
  const char *ensureSamplesForDevice(const char *source, int len);
  const char *ensureSamples(int &num);
  int configureDevice(int frq, int ch, int len, rviewSoundFormat fmt, int lat);
  void ensureUlawTable(int ulawsize);
  void ensureLinearTable(void);
  char *ensureConvBuff(int size);
  char *ensureSampleBuff(int size);

  int setTimerInterval(unsigned int ti);
  int startTimer(int ap=1);
  int stopTimer(int ap=1);
  int handleOutOfData(int dataSize);

  rviewSoundFormat format;
  rviewSoundFormat devFormat;
  int sampleSize, devSampSize;
  FILE *sampleFile;
  int dataOffset, inLength;
  int frequency, channels, latency, samplesWriteahead;
  int buffSize, cbuffSize;
  char *buffer, *convBuff;
  const char *inData;
  unsigned char *LinToUlaw;
  short *UlawToLin;
  int ldUlawSize;
  int samplesWritten;
  soundPlayer *suspendedPlayer;
  int loopMode;
  bool timerActive;

  // Unix specifics
#ifdef __VISUALC__
  void freeWaveHeaders(void);

  HWAVEOUT waveOut;
  WAVEFORMATEX waveFmt;
  WAVEHDR waveHdrs[RVIEW_SND_BUFFERS];
  UINT timerID;
  DWORD lastSyncTime;
  int currentHeader;
  int emptyBuffers;
#else
  int audioDevice;
  struct timeval lastSyncTime;
  struct sigaction oact;
  struct itimerval ovalue;
#endif
};



#ifndef __HAL_ONLY__

/*
 *  rviewSoundPlayer: sound player widget
 */

class rviewSoundPlayer: public rviewDisplay
{
  public:

  rviewSoundPlayer(mdd_frame *mf, unsigned int flags=0);
  ~rviewSoundPlayer(void);

  void label(void);
  int process(wxObject &obj, wxEvent &evt);
  virtual int openViewer(void);

  virtual const char *getFrameName(void) const;
  virtual rviewFrameType getFrameType(void) const;
  virtual int getViewerType(void) const;

  void OnSize(int w, int h);

  int newProjection(void);
  void prepareToDie(void);

  typedef struct format_desc {
    const char *labelName;
    rviewSoundFormat fmt;
    int sampleSize;
  } format_desc;

  // constants
  // Sound player window button size
  static const int sound_bwidth;
  static const int sound_bheight;
  // Sound player window slider height
  static const int sound_sheight;
  // Sound player window text size
  static const int sound_twidth;
  static const int sound_theight;
  // Sount player choice size
  static const int sound_cwidth;
  static const int sound_cheight;
  // Sound player window ctrl area size
  static const int sound_ctrly;
  // Sound player frame size
  static const int sound_width;
  static const int sound_height;
  // Number of latency entries
  static const int sound_latencies;


  protected:

  int buildSample(void);
  int newSample(void);
  int startPlayback(void);
  int stopPlayback(void);
  void setSlider(int offset);
  bool setLoopMode(bool lm);

  soundPlayer player;
  rviewButton *toStart, *toEnd;
  rviewButton *pbPause, *pbStart, *pbStop, *pbLoop;
  rviewSlider *slider;
  rviewText *frqWidget;
  rviewChoice *fmtWidget, *latWidget;
  int frequency, channels, latency;
  int lastOffset;
  int *latencies;
  void *sampleBuffer;
  int sampleLength;
  bool paused;
  bool playbackOn;
  bool loopMode;
  int dim1, dim2;
  int typeLength;
  int currentFormat;
  unsigned int freeDims;

  static const format_desc soundFormatDesc[];
};

#endif // HAL

#endif