1 /* PROJECT:         ReactOS sndrec32
2  * LICENSE:         GPL - See COPYING in the top level directory
3  * FILE:            base/applications/sndrec32/audio_wavein.hpp
4  * PURPOSE:         Windows MM wave in abstraction
5  * PROGRAMMERS:     Marco Pagliaricci (irc: rendar)
6  */
7 
8 #ifndef _AUDIOWAVEIN_H_
9 #define _AUDIOWAVEIN_H_
10 
11 #include "audio_format.hpp"
12 #include "audio_receiver.hpp"
13 
14 _AUDIO_NAMESPACE_START_
15 
16 enum audio_wavein_status
17 {
18     WAVEIN_NOTREADY,
19     WAVEIN_READY,
20     WAVEIN_RECORDING,
21     WAVEIN_ERR,
22     WAVEIN_STOP,
23     WAVEIN_FLUSHING
24 };
25 
26 class audio_wavein
27 {
28     private:
29         /* The new recording thread sends message to this procedure
30            about open recording, close, and sound data recorded */
31         static DWORD WINAPI recording_procedure(LPVOID);
32 
33         /* When this event is signaled, then the previously created
34            recording thread will wake up and start recording audio
35            and will pass audio data to an `audio_receiver' object. */
36         HANDLE wakeup_recthread;
37         HANDLE data_flushed_event;
38 
39     protected:
40         /* TODO: puts these structs in private?! */
41 
42         /* Audio wavein device stuff */
43         WAVEFORMATEX wave_format;
44         WAVEHDR *wave_headers;
45         HWAVEIN wavein_handle;
46 
47         audio_format aud_info;
48         audio_receiver &audio_rcvd;
49 
50         /* Audio Recorder Thread id */
51         DWORD recthread_id;
52 
53         /* Object status */
54         audio_wavein_status status;
55 
56         /* How many seconds of audio can record the internal buffer before
57            flushing audio data to the `audio_receiver' class? */
58         float buf_secs;
59 
60         /* The temporary buffers for the audio data incoming from the wavein
61            device and its size, and its total number */
62         BYTE *main_buffer;
63         unsigned int mb_size;
64         unsigned int buffers;
65 
66         /* Protected Functions */
67 
68         /* initialize all structures and variables */
69         void init_(void);
70 
71         void alloc_buffers_mem_(unsigned int, float);
72         void free_buffers_mem_(void);
73 
74         void init_headers_(void);
75         void prep_headers_(void);
76         void unprep_headers_(void);
77         void add_buffers_to_driver_(void);
78 
79     public:
80         /* Ctors */
audio_wavein(const audio_format & a_info,audio_receiver & a_receiver)81         audio_wavein(const audio_format &a_info,
82                      audio_receiver &a_receiver) : wave_headers(0),
83                                                    aud_info(a_info),
84                                                    audio_rcvd(a_receiver),
85                                                    status(WAVEIN_NOTREADY),
86                                                    main_buffer(0),
87                                                    mb_size(0),
88                                                    buffers(_AUDIO_DEFAULT_WAVEINBUFFERS)
89         {
90             /* Initializing internal wavein data */
91             init_();
92             aud_info = a_info;
93         }
94 
95         /* Dtor */
~audio_wavein(void)96         ~audio_wavein(void)
97         {
98             //close(); TODO!
99         }
100 
101         /* Public functions */
102 
103         void open(void);
104         void close(void);
105 
106         void start_recording(void);
107         void stop_recording(void);
108 
current_status(void) const109         audio_wavein_status current_status (void) const
110         {
111             return status;
112         }
113 
buffer_secs(void) const114         float buffer_secs(void) const
115         {
116             return buf_secs;
117         }
118 
buffer_secs(float bsecs)119         void buffer_secs(float bsecs)
120         {
121             /* Some checking */
122             if (bsecs <= 0)
123                 return;
124 
125             /* Set seconds length for each buffer */
126             buf_secs = bsecs;
127         }
128 
total_buffers(void) const129         unsigned int total_buffers(void) const
130         {
131             return buffers;
132         }
133 
total_buffers(unsigned int tot_bufs)134         void total_buffers(unsigned int tot_bufs)
135         {
136             /* Some checking */
137             if (tot_bufs == 0)
138                 return;
139 
140             /* Sets the number of total buffers */
141             buffers = tot_bufs;
142         }
143 
format(void) const144         audio_format format(void) const
145         {
146             return aud_info;
147         }
148 
buf(void)149         BYTE *buf(void)
150         {
151             return main_buffer;
152         }
153 
bufsz(void)154         unsigned int bufsz(void)
155         {
156             return mb_size;
157         }
158 
samplevalue_max(void)159         unsigned int samplevalue_max(void)
160         {
161             if (aud_info.bits() == 16)
162                 return (unsigned int)65535;
163 
164             else if (aud_info.bits() == 8)
165                 return (unsigned int)255;
166 
167             else
168                 return 0;
169         }
170 
tot_samples_buf(void)171         unsigned tot_samples_buf(void)
172         {
173             return aud_info.samples_in_bytes(mb_size);
174         }
175 
nsample(unsigned int nsamp)176         unsigned int nsample(unsigned int nsamp)
177         {
178             unsigned int svalue;
179 
180             if (aud_info.bits() == 16)
181                 svalue = (unsigned int)abs(*((short *)(main_buffer + aud_info.bytes_in_samples(nsamp))));
182             else if (aud_info.bits() == 8)
183                svalue = (unsigned int)((ptrdiff_t) *(main_buffer + aud_info.bytes_in_samples(nsamp)));
184             else
185                 svalue = 0;
186 
187             return svalue;
188         }
189 };
190 
191 _AUDIO_NAMESPACE_END_
192 
193 #endif /* _AUDIOWAVEIN_H_ */
194