Subversion Repositories shark

Rev

Rev 1676 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1676 tullio 1
%----------------------------------------------------------------------------
2
\chapter{The Sound Library}
3
%----------------------------------------------------------------------------
4
 
5
If a SoundBlaster16 sound card is available, S.Ha.R.K. allows to sample and play
6
sounds by using the functions provided by the sound library \footnote{Currently
7
only the sound blaster 16 is supported; the code of the library is directly
8
inherited from the Hartik 3.3.0 Kernel...}. The library currently supports
9
either program or DMA controlled sampling an playing, according to 4 possible
10
operating modes:
11
 
12
\begin{itemize}
13
\item PIO mode;
14
\item DMA-Raw mode;
15
\item DMA-Double-buffering mode;
16
\item DMA-Self-buffering mode.
17
\end{itemize}
18
 
19
Working under PIO mode, sounds can be sampled and played only with 8 bit PCM.
20
The frequence depends on the hardware speeds but cannot in any case overcome 10
21
Khz. This mode is reserved for the pure classical hard real-time approach which
22
refuses the usage of DMA controlled I/O.
23
 
24
The DMA-Raw mode uses DMA controller to sample and play directly on a memory
25
buffer. Owing to technical problems related to the structure of the PC DMA
26
controller, the buffer's size can be no bigger than 64K. This mode is the one
27
that minimizes the DMA operations' impact on CPU.
28
 
29
The DMA Double-Buffering mode uses an internal buffer in order to overcome the
30
64k limitation. The internal buffer is split into two parts: while the DMA
31
tranfers data to one half, an ad-hoc task moves data between the second half and
32
a user-provided external memory region. In this way, it is possible for a user
33
to work on samples much bigger than 64K, paying the fee of a higher CPU load
34
\footnote{This is possible only if the protected mode is used.}.
35
 
36
The DMA-Self-Buffering mode allows the user to directly handle the internal
37
buffer. The user specifies a function to be activated every time the DMA
38
controller has finished transferring data on one half of the internal buyffer.
39
In this mode, the user can obtain the data while they are being sampled; the
40
time lag between sampling and data delivery is thus reduced. Such a feature
41
makes this working mode interesting for real-time applications. Independently of
42
the chosen working mode, an operation can be either synchronous or asynchronous.
43
A synchronous operation provides the task invoking the operation with a
44
synchronizing point located at its ending. In order to use the sound library
45
functions, the files \texttt{drivers/sound.h} and \texttt{drivers/dma.h} must be
46
included. The former contains the prototypes of the declared functions, the
47
latter is necessary because the sound library uses DMA.
48
 
49
The first step to be performed is initializing the audio drivers by the
50
\texttt{sound\_init} function. Then, if one wishes to work in DMA-Raw mode, it
51
is necessary to allocate a memory buffer and align it by calling
52
\texttt{dma\_getpage()} (in the remaining modes no particular alignment is
53
required for the buffer). If the DMA-Self-buffering mode is chosen, the
54
programmer has to properly set the functions to be called every time the DMA
55
finishes working on one half of the internal buffer; this can be done by calling
56
the \texttt{sound\_setfun()} primitive. As soon as these operations have been
57
performed, sampling or playing can be made through \texttt{sound\_sample()} and
58
\texttt{sound\_play()}, respectively.
59
 
60
\vspace{7mm}
61
 
62
\begin{intest}
63
SOUND\_INIT\index{sound\_init()}
64
\end{intest}
65
 
66
\begin{description}
67
\item [\textbf{void sound\_init(WORD rawbufsize, WORD tick);}]
68
\item [\textbf{Description:}] It initializes the audio driver by allocating the
69
internal
70
buffer for the DMA-Double-buffering and DMA-Self-Buffering modes. The
71
\texttt{rawbufsize} parameter contains the dimension of this buffer. Higher
72
values reduce the CPU load and are thus advised when using the
73
DMA-Double-buffering mode. Lower values, on the contrary, can be used to shorten
74
the latency between sampling and data delivering (particularly when using
75
DMA-Self-buffering). The \texttt{tick} parameter contains the value of the
76
system tick; its correctness is fundamental for the PIO mode.
77
\end{description}
78
 
79
\begin{intest}
80
SOUND\_INFO\index{sound\_info()}
81
\end{intest}
82
 
83
\begin{description}
84
\item [\textbf{void sound\_info(void);}]
85
\item [\textbf{Description:}] It outputs on the screen some information concerning
86
the soundcard and the drivers.
87
\end{description}
88
 
89
\begin{intest}
90
SOUND\_SETFUN\index{sound\_setfun()}
91
\end{intest}
92
 
93
\begin{description}
94
\item [\textbf{void sound\_setfun(int ({*}infun)(BYTE {*}rawbuff),}\\
95
\texttt{int ({*}outfun)(BYTE {*}rawbuff));}]
96
\item [\textbf{Description:}] It specifies the functions to be called when the DMA
97
finishes working on one of the two internal buffer's halves when using
98
DMA-Self-Buffering mode. The function pointed by \texttt{infun} is used when
99
performing sampling operations, whereas \texttt{outfun} is used for playing
100
operations. Both functions receive a pointer to the half-buffer not currently
101
acted upon by the DMA (the half-buffer sizes are equal to one half of the
102
\texttt{sound\_init()} parameter) and have to return 0 if the operation has not
103
yet been finished, 1 if it is going to finish in the next DMA cycle, and 2 if it
104
finishes immediately. Attention should be paid to the fact that these functions
105
are periodically called with a frequency equal to the operation's frequency
106
divided by the half-buffer's size; thus, they should be very short in order not
107
to overload the system.
108
\end{description}
109
 
110
\begin{description}
111
\item [Example:]
112
\end{description}
113
 
114
\begin{tt}
115
\begin{verbatim}
116
int osc_fun(BYTE *b) {
117
    int i;
118
    int sum = 0;
119
    BYTE *p;
120
 
121
    /* Averages the values read from the buffer */
122
    /* and writes the result on a CAB shared */
123
    /* with a task */
124
    for (i = 0; i < (BUFFDIM >> 1); i++)
125
        sum += b[i];
126
    sum = (BUFFDIM >> 1);
127
    p = cab_reserve(cc);
128
    *p = (BYTE) sum;
129
    cab_putmes(cc, p);
130
    return 0;
131
}
132
...
133
 
134
void *io_task(void *arg) {
135
    int x, y;
136
    BYTE *p;
137
    BYTE page = 0;
138
    char str[50];
139
    short int talk, silencecount;
140
 
141
    /* This task reads the value put on the CAB by */
142
    /* the self-buffering function */
143
    /* sets the self-buffering function */
144
    sound_setfun(osc_infun, -1);
145
 
146
    /* starts the sampling operation */
147
    sound_sample(NULL, 20000, 0, DMA_OP | PCM8 | MYFUN);
148
    cc = cab_create("osc_cab", sizeof(BYTE), 3);
149
    for (;;) {
150
        /* reads and proccesses */
151
        /* the CAB's value */
152
        ...
153
        task_endcycle();
154
    }
155
    return 0;
156
}
157
\end{verbatim}
158
\end{tt}
159
 
160
\begin{intest}
161
SOUND\_SAMPLE\index{sound\_sample()}
162
\end{intest}
163
 
164
\begin{description}
165
\item [\textbf{void sound\_sample(BYTE {*}buf, DWORD sps, DWORD len, BYTE t);}]
166
\item [\textbf{Description:}] It samples \texttt{len} bytes in the \texttt{buf}
167
buffer at the frequency of \texttt{sps} samples per second with the mode
168
expressed by \texttt{t}. The latter can be assigned one of the following
169
constants:
170
 
171
\begin{itemize}
172
\item \texttt{PIO\_OP} operates using PIO mode: as said earlier, in this mode
173
values for \texttt{sps} higher than 10000 make no sense. Moreover, for the
174
sampling and playing to happen with the correct timing, it is necessary that the
175
audio driver be initialized with the \texttt{tick} parameter set to the system
176
tick expressed in microseconds (see \texttt{sound\_init()} for more details).
177
\item \texttt{DMA\_OP} operates using one of the DMA modes (the default is
178
DMA-Double-Buffering). The internal buffer size is specified in
179
\texttt{sound\_init}.
180
\item \texttt{PCM8} operates using 8 bit PCM format (it is the default). It is
181
the only possible format in PIO mode.
182
\item \texttt{PCM16} operates using 16 bit PCM format. This choice is
183
meaningless in PIO mode.
184
\item \texttt{SYNCH} synchronous operation: it is necessary to call
185
\texttt{sound\_wait()} after \texttt{sound\_sample()}.
186
\item \texttt{ASYNCH} asynchronous operation.
187
\item \texttt{MYFUN} operates with DMA-Self-buffering mode; it makes sense only
188
if \texttt{DMA\_OP} has been set.
189
\item \texttt{NOBUFF} operates in DMA-Raw-Mode; it makes sense only if
190
\texttt{DMA\_OP} has been set.
191
\end{itemize}
192
\end{description}
193
 
194
\begin{description}
195
\item [Example:]
196
\end{description}
197
 
198
\begin{tt}
199
\begin{verbatim}
200
BYTE buff[0xFFFFF]; /* buffer for sampling */
201
 
202
void main() {
203
    sys_init(\&s);
204
    keyb_init(NULL);
205
    clear();
206
 
207
    sound_init(0x4000, TICK);
208
    sound_info();
209
 
210
    cprintf("Recording...");
211
    sound_sample(buff, 44000, 0x8FFFF, DMA_OP | PCM8 | SYNCH);
212
    ...
213
}
214
\end{verbatim}
215
\end{tt}
216
 
217
\begin{intest}
218
SOUND\_PLAY\index{sound\_play()}
219
\end{intest}
220
 
221
\begin{description}
222
\item [\textbf{void sound\_play(BYTE {*}buff, DWORD sps, DWORD len, BYTE t);}]
223
\item [\textbf{Description:}] It plays \texttt{len} bytes taken from the \texttt{b}
224
buffer
225
at the frequency of \texttt{sps} samples per second with the mode expressed by
226
\texttt{t}. As far as the values of \texttt{t} are concerned, the reader can
227
refer to \texttt{sound\_sample}.
228
\end{description}
229
 
230
\begin{intest}
231
DMA\_GETPAGE\index{dma\_getpage()}
232
\end{intest}
233
 
234
\begin{description}
235
\item [\textbf{BYTE {*}dma\_getpage(DWORD {*}dim);}]
236
\item [\textbf{Description:}] It allocates a buffer having size \texttt{dim} fitting
237
for
238
use in DMA operations. Such a usage is possible only if the buffer does not
239
contain bytes whose address differs in the Most Significant Bits. The best way
240
to achieve this feature is to allocate buffers sized less than 64K starting from
241
addresses having the LSB equal to 0. This job is performed by
242
\texttt{dma\_getpage}. It should be noted that such a feature is necessary only
243
using DMA-Raw-Mode, since the buffer allocation is automatically performed by
244
\texttt{sound\_init} when using DMA-Double-Buffering and DMA-Self-Bufering
245
modes.
246
\end{description}
247
 
248
\begin{description}
249
\item [Example:]
250
\end{description}
251
 
252
\begin{tt} \begin{verbatim}
253
void main(void) {
254
    BYTE *p;
255
    int i;
256
 
257
    /* Monitors the time stolen by the DMA */
258
    /* to the CPU during a 10 Khz sampling */
259
    sys_init(&s);
260
    keyb_init(NULL);
261
    ...
262
    clear();
263
    p = dma_getpage(0xFFFF);
264
    sound_init(0x200, TICK);
265
    sound_info();
266
 
267
    for (i = 0; i < 80; i++) cprintf("_");
268
    cprintf("ref_time: %f ", myrif);
269
    cprintf("Unloaded system: %f", load(&myrif));
270
 
271
    cprintf("DMA Recording...");
272
    sound_sample(p, 10000, 0xFFFF, DMA_OP | PCM8 | NOBUFF);
273
    ...
274
\end{verbatim}
275
\end{tt}
276
 
277
\begin{intest}
278
SOUND\_WAIT\index{sound\_wait()}
279
\end{intest}
280
 
281
\begin{description}
282
\item [\textbf{void sound\_wait(void);}]
283
\item [\textbf{Description:}] It is the synchronization primitive for synchronous
284
operations. The task calling \texttt{sound\_wait()} blocks itself until the
285
synchronous operation is finished. The call to this function is mandatory for
286
synchronous operations. On the other hand, using the function in conjunction
287
with an asynchronous operation is an error.
288
\end{description}
289
 
290
\begin{description}
291
\item [Example:]
292
\end{description}
293
 
294
\begin{tt}
295
\begin{verbatim}
296
    sound_sample(buff, 44000, 0x8FFFF, DMA_OP | PCM8 | SYNCH);
297
    ...
298
    /* waits until the sampling termination */
299
    sound_wait();
300
    ...
301
\end{verbatim}
302
\end{tt}