root/ossiedev/branches/0.7.x/platform/AudioDevice/src/AudioDevice.cpp @ 8808

Revision 8808, 12.5 KB (checked in by jgaeddert, 4 years ago)

setting properties

Line 
1/****************************************************************************
2
3Copyright 2009 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE AudioDevice.
6
7OSSIE AudioDevice is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE AudioDevice is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OSSIE AudioDevice; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23#include <iostream>
24#include "AudioDevice.h"
25
26#define AUDIODEVICE_PROPID_SAMPLERATERECORD     "DCE:90b8fe0b-3b0b-4aee-bb2b-a9a989d22ba9"
27#define AUDIODEVICE_PROPID_SAMPLERATEPLAYBACK   "DCE:5a9b4f27-c604-4fe8-9661-4bf7a65e4ad4"
28#define AUDIODEVICE_PROPID_BUFFERSIZERECORD     "DCE:849f63b4-9b18-40cb-b318-956bedae94aa"
29#define AUDIODEVICE_PROPID_BUFFERSIZEPLAYBACK   "DCE:f3a3dd1f-b7e2-44a4-ad34-db0a6bea895f"
30
31#define AUDIODEVICE_NUMCHANNELS     (2)
32#define AUDIODEVICE_SAMPLEFORMAT    (paInt16)
33
34// Initializing constructor
35AudioDevice_i::AudioDevice_i(char *uuid, char *label, char *profile, omni_condition *condition)
36  : Device_impl(uuid, label, profile),
37    component_running(condition),
38    isRunning(false)
39{
40    DEBUG(3, AudioDevice, "constructor invoked")
41
42    // set configured flags to false
43    configured = false;
44    configured_prop_samplerate_record   = false;
45    configured_prop_samplerate_playback = false;
46    configured_prop_buffersize_record   = false;
47    configured_prop_buffersize_playback = false;
48
49    // Create Port for output sound
50    dataOut = new standardInterfaces_i::complexShort_u("complexShortOut");
51    // TODO: create port for input sound
52
53    // initialize portaudio stream
54    PaError err = Pa_Initialize();
55    if (err != paNoError) {
56        std::cerr << "ERROR: AudioDevice_i::AudioDevice_i(), could not initialize portaudio" << std::endl;
57        throw 0;
58    }
59
60    // Start the capture_sound thread
61    //capture_thread = new omni_thread(run_capture, (void *) this);
62    //capture_thread->start();
63
64    // Start playback_sound thread
65    //playback_thread = new omni_thread(run_playback, (void *) this);
66    //playback_thread->start();
67}
68
69// Default destructor
70AudioDevice_i::~AudioDevice_i()
71{
72    PaError err = Pa_Terminate();
73    if (err != paNoError) {
74        std::cerr << "ERROR: AudioDevice_i::~AudioDevice_i(), could not terminate portaudio" << std::endl;
75        throw 0;
76    }
77}
78
79// static function for omni thread
80void AudioDevice_i::run_capture( void * data )
81{
82    ((AudioDevice_i*) data)->capture_sound();
83}
84
85
86// static function for omni thread
87void AudioDevice_i::run_playback( void * data )
88{
89    ((AudioDevice_i*) data)->playback_sound();
90}
91
92void AudioDevice_i::start()
93throw (CF::Resource::StartError, CORBA::SystemException)
94{
95    DEBUG(3, AudioDevice, "start() invoked")
96
97    isRunning = true;
98
99    // start the streams
100    StartStreams();
101}
102
103
104void AudioDevice_i::stop()
105throw (CF::Resource::StopError, CORBA::SystemException)
106{
107    DEBUG(3, AudioDevice, "stop() invoked")
108
109    isRunning = false;
110
111    // stop the streams
112    StopStreams();
113}
114
115CORBA::Object_ptr AudioDevice_i::getPort(const char* portName)
116throw(CF::PortSupplier::UnknownPort, CORBA::SystemException)
117
118{
119    DEBUG(3, AudioDevice, "getPort() invoked with: " << portName)
120
121    CORBA::Object_var u;
122
123    u = dataOut->getPort(portName);
124
125    if (!CORBA::is_nil(u))
126        return u._retn();
127
128    // Port name not found; throw exception
129    throw CF::PortSupplier::UnknownPort();
130}
131
132void AudioDevice_i::initialize()
133throw (CF::LifeCycle::InitializeError, CORBA::SystemException)
134{
135    DEBUG(3, AudioDevice, "initialize() invoked")
136}
137
138void AudioDevice_i::configure(const CF::Properties &props)
139throw (CORBA::SystemException,
140       CF::PropertySet::InvalidConfiguration,
141       CF::PropertySet::PartialConfiguration)
142{
143    DEBUG(3, AudioDevice, "configure() invoked. Number of props = "
144              << props.length() 
145             )
146
147    // read properties from .prf
148   
149    CORBA::Short n;
150    for (unsigned int i=0; i<props.length(); i++)
151    {
152        DEBUG(3, AudioDevice, "configure property id : " << props[i].id)
153
154        if (strcmp(props[i].id, AUDIODEVICE_PROPID_SAMPLERATERECORD)==0) {
155            // sample rate: record
156            props[i].value >>= n;
157            samplerate_record = n;
158            configured_prop_samplerate_record = true;
159            DEBUG(3, AudioDevice, "sample rate (record): " << samplerate_record << " Hz")
160
161        } else if (strcmp(props[i].id, AUDIODEVICE_PROPID_SAMPLERATEPLAYBACK)==0) {
162            // sample rate: playback
163            props[i].value >>= n;
164            samplerate_playback = n;
165            configured_prop_samplerate_playback = true;
166            DEBUG(3, AudioDevice, "sample rate (playback): " << samplerate_playback << " Hz")
167
168        } else if (strcmp(props[i].id, AUDIODEVICE_PROPID_BUFFERSIZERECORD)==0) {
169            // buffer size: record
170            props[i].value >>= n;
171            buffersize_record = n;
172            configured_prop_samplerate_record = true;
173            DEBUG(3, AudioDevice, "buffer size (record): " << buffersize_record)
174
175        } else if (strcmp(props[i].id, AUDIODEVICE_PROPID_BUFFERSIZEPLAYBACK)==0) {
176            // buffer size: playback
177            props[i].value >>= n;
178            buffersize_playback = n;
179            configured_prop_buffersize_playback = true;
180            DEBUG(3, AudioDevice, "buffer size (playback): " << buffersize_playback)
181
182        } else {
183            std::cerr << "ERROR AudioDevice_i::configure(): unkown property id "
184                      << props[i].id << std::endl;
185            throw(CF::PropertySet::InvalidConfiguration());
186        }
187
188        // check configured flags
189        if (    configured_prop_samplerate_record   &&
190                configured_prop_samplerate_playback &&
191                configured_prop_buffersize_record   &&
192                configured_prop_buffersize_playback)
193        {
194            configured = true;
195            DEBUG(3, AudioDevice, "configured")
196        }
197    }
198
199    // TODO: reconfigure streams
200    if (!configured)
201        return;
202
203    if (isRunning) {
204        stop();
205        // ...
206        start();
207    } else {
208        // ...
209    }
210
211}
212
213void AudioDevice_i::releaseObject()
214throw (CF::LifeCycle::ReleaseError, CORBA::SystemException)
215{
216    DEBUG(3, AudioDevice, "releaseObject() invoked")
217
218    component_running->signal();
219}
220
221void AudioDevice_i::OpenStreams()
222    throw (CF::Resource::StartError)
223{
224    // ensure properties have been configured
225    if (!configured) {
226        std::cerr << "ERROR: AudioDevice_i::OpenStreams(), device not configured" << std::endl;
227        throw CF::Resource::StartError();
228    }
229
230    PaError err;
231
232    // open record stream
233    err = Pa_OpenStream(
234            &pa_stream_record,
235            NULL,               // no input
236            &pa_params_record,
237            samplerate_record,
238            buffersize_record,
239            paClipOff,          // disable clipping
240            portaudio_callback_record,
241            (void*)this);
242
243    if (err != paNoError) {
244        std::cerr << "ERROR: AudioDevice_i::OpenStreams(), could not open portaudio stream: record" << std::endl;
245        throw CF::Resource::StartError();
246    }
247
248    // open playback stream
249    err = Pa_OpenStream(
250            &pa_stream_playback,
251            &pa_params_playback,
252            NULL,               // no output
253            samplerate_playback,
254            buffersize_playback,
255            paClipOff,          // disable clipping
256            portaudio_callback_playback,
257            (void*)this);
258
259    if (err != paNoError) {
260        std::cerr << "ERROR: AudioDevice_i::OpenStreams(), could not open portaudio stream: playback" << std::endl;
261        throw CF::Resource::StartError();
262    }
263}
264
265void AudioDevice_i::StartStreams()
266    throw (CF::Resource::StartError)
267{
268    if (!configured) {
269        std::cerr << "ERROR: AudioDevice_i::StartStreams(), device not configured" << std::endl;
270        throw CF::Resource::StartError();
271    }
272
273    // start record, playback threads
274    PaError err;
275
276
277    err = Pa_StartStream(pa_stream_record);
278    if (err != paNoError) {
279        std::cerr << "ERROR: AudioDevice_i::StartStreams(), could not start portaudio stream: record" << std::endl;
280        throw CF::Resource::StartError();
281    }
282
283    err = Pa_StartStream(pa_stream_playback);
284    if (err != paNoError) {
285        std::cerr << "ERROR: AudioDevice_i::StartStreams(), could not start portaudio stream: playback" << std::endl;
286        throw CF::Resource::StartError();
287    }
288}
289
290void AudioDevice_i::StopStreams()
291    throw (CF::Resource::StopError)
292{
293    PaError err;
294
295    err = Pa_StopStream(pa_stream_record);
296    if (err != paNoError) {
297        std::cerr << "ERROR: AudioDevice_i::StopStreams(), could not stop portaudio stream: record" << std::endl;
298        throw CF::Resource::StopError();
299    }
300
301    err = Pa_StopStream(pa_stream_playback);
302    if (err != paNoError) {
303        std::cerr << "ERROR: AudioDevice_i::StopStreams(), could not stop portaudio stream: playback" << std::endl;
304        throw CF::Resource::StopError();
305    }
306
307}
308
309void AudioDevice_i::CloseStreams()
310    throw (CF::Resource::StopError)
311{
312    PaError err;
313   
314    err = Pa_CloseStream(pa_stream_record);
315    if (err != paNoError) {
316        std::cerr << "ERROR: AudioDevice_i::CloseStreams(), could not close portaudio stream: record" << std::endl;
317        throw CF::Resource::StopError();
318    }
319   
320    err = Pa_CloseStream(pa_stream_playback);
321    if (err != paNoError) {
322        std::cerr << "ERROR: AudioDevice_i::CloseStreams(), could not close portaudio stream: playback" << std::endl;
323        throw CF::Resource::StopError();
324    }
325}
326
327void AudioDevice_i::ConfigureStreams()
328{
329    // configure parameters: record
330    pa_params_record.device = Pa_GetDefaultOutputDevice();
331    pa_params_record.channelCount = AUDIODEVICE_NUMCHANNELS;
332    pa_params_record.sampleFormat = AUDIODEVICE_SAMPLEFORMAT;
333    pa_params_record.suggestedLatency =
334        Pa_GetDeviceInfo( pa_params_record.device )->defaultLowOutputLatency;
335    pa_params_record.hostApiSpecificStreamInfo = NULL;
336
337    // configure parameters: playback
338    pa_params_playback.device = Pa_GetDefaultOutputDevice();
339    pa_params_playback.channelCount = AUDIODEVICE_NUMCHANNELS;
340    pa_params_playback.sampleFormat = AUDIODEVICE_SAMPLEFORMAT;
341    pa_params_playback.suggestedLatency =
342        Pa_GetDeviceInfo( pa_params_playback.device )->defaultLowOutputLatency;
343    pa_params_playback.hostApiSpecificStreamInfo = NULL;
344}
345
346void AudioDevice_i::capture_sound()
347{
348    DEBUG(3, AudioDevice, "capture_sound() invoked")
349    PortTypes::ShortSequence L_out, R_out;
350
351    L_out.length(1);
352    R_out.length(1);
353   
354    while(isRunning && configured) {
355        //dataOut->pushPacket(L_out, R_out);
356    }
357}
358
359void AudioDevice_i::playback_sound()
360{
361    DEBUG(3, AudioDevice, "playback_sound() invoked")
362    PortTypes::ShortSequence L_out, R_out;
363
364    L_out.length(1);
365    R_out.length(1);
366   
367    while(isRunning && configured) {
368        //dataOut->pushPacket(L_out, R_out);
369    }
370}
371
372int portaudio_callback_record(
373    const void *inputBuffer,
374    void *outputBuffer,
375    unsigned long framesPerBuffer,
376    const PaStreamCallbackTimeInfo* timeInfo,
377    PaStreamCallbackFlags statusFlags,
378    void *userData )
379{
380    AudioDevice_i * device = (AudioDevice_i*)userData;
381    short int * in = (short int*)inputBuffer;
382
383    // prevent unused variable warnings
384    (void) timeInfo;
385    (void) statusFlags;
386    (void) inputBuffer;
387
388    unsigned long int i;
389    for (i=0; i<framesPerBuffer; i++) {
390        // write data to port
391    }
392
393    return paContinue;
394}
395
396int portaudio_callback_playback(
397    const void *inputBuffer,
398    void *outputBuffer,
399    unsigned long framesPerBuffer,
400    const PaStreamCallbackTimeInfo* timeInfo,
401    PaStreamCallbackFlags statusFlags,
402    void *userData )
403{
404    AudioDevice_i * device = (AudioDevice_i*)userData;
405    short int * out = (short int*)outputBuffer;
406
407    // prevent unused variable warnings
408    (void) timeInfo;
409    (void) statusFlags;
410    (void) inputBuffer;
411
412    unsigned long int i;
413    for (i=0; i<framesPerBuffer; i++) {
414        // left
415        //*out++ = device->playback_data_L[i];
416
417        // right
418        //*out++ = device->playback_data_R[i];
419    }
420
421    return paContinue;
422}
423
424
Note: See TracBrowser for help on using the browser.