source: mediastreamer2/src/msandroid_webrtc.cpp @ 1421:2e72eb534ade

Last change on this file since 1421:2e72eb534ade was 1421:2e72eb534ade, checked in by Nikita Kozlov <nikita@…>, 20 months ago

adding experimental webrtc soundcard for android

File size: 19.6 KB
Line 
1/*
2 * msandroid.cpp -Android Media plugin for Linphone-
3 *
4 *
5 * Copyright (C) 2009  Belledonne Communications, Grenoble, France
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 2 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *  GNU Library General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with this program; if not, write to the Free Software
19 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include "mediastreamer2/mssndcard.h"
23#include "mediastreamer2/msfilter.h"
24#include "mediastreamer2/msticker.h"
25#include "mediastreamer2/msjava.h"
26#include "audio_device_impl.h"
27#include "critical_section_wrapper.h"
28#include "file_wrapper.h"
29#include "trace.h"
30#include <cassert>
31
32namespace webrtc {
33WebRtc_Word32 SetAndroidAudioDeviceObjects(void* javaVM, void* env,
34                                           void* context);
35                                           }
36using namespace webrtc;
37
38#define WEBRTC_VOICE_ENGINE_DEFAULT_DEVICE 0
39
40static uint32_t gl_sample_rate= 0;
41
42
43class MSandroidSoundCardImpl;
44
45/*
46 mediastreamer2 sound card functions
47 */
48class msandroid_sound_data {
49        public:
50                msandroid_sound_data() : started(false){
51                        ms_mutex_init(&mutex,NULL);
52                };
53                ~msandroid_sound_data() {
54                        ms_mutex_destroy(&mutex);
55                }
56                bool            started;
57                ms_mutex_t      mutex;
58};
59
60class msandroid_sound_write_data : public msandroid_sound_data{
61        public:
62                msandroid_sound_write_data(MSandroidSoundCardImpl *sndcard): _sndcard(sndcard) {
63                        ms_bufferizer_init(&bf);
64                };
65                ~msandroid_sound_write_data() {
66                        ms_bufferizer_uninit(&bf);
67                }
68                void StartPlayout();
69                void StopPlayout();
70                MSBufferizer    bf;
71                MSandroidSoundCardImpl *_sndcard; 
72};
73
74
75
76class msandroid_sound_read_data : public msandroid_sound_data{
77        public:
78                msandroid_sound_read_data(MSandroidSoundCardImpl *sndcard): _sndcard(sndcard) {
79                        ms_bufferizer_init(&rb);
80                }
81                ~msandroid_sound_read_data() {
82                        ms_bufferizer_uninit (&rb);
83                }
84                void StartRecording();
85                void StopRecording();
86                MSBufferizer            rb;
87                MSandroidSoundCardImpl *_sndcard; 
88};
89
90
91void msandroid_sound_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent)
92{
93}
94
95int msandroid_sound_get_level(MSSndCard *card, MSSndCardMixerElem e)
96{
97        return 0;
98}
99
100void msandroid_sound_set_source(MSSndCard *card, MSSndCardCapture source)
101{
102}
103
104class MSandroidSoundCardImpl : public AudioTransport {
105
106        public:
107
108                MSandroidSoundCardImpl();
109                int Init();
110                void Terminate();
111                // AudioTransport
112                virtual WebRtc_Word32
113                        RecordedDataIsAvailable(const WebRtc_Word8* audioSamples,
114                                        const WebRtc_UWord32 nSamples,
115                                        const WebRtc_UWord8 nBytesPerSample,
116                                        const WebRtc_UWord8 nChannels,
117                                        const WebRtc_UWord32 samplesPerSec,
118                                        const WebRtc_UWord32 totalDelayMS,
119                                        const WebRtc_Word32 clockDrift,
120                                        const WebRtc_UWord32 currentMicLevel,
121                                        WebRtc_UWord32& newMicLevel);
122
123                virtual WebRtc_Word32 NeedMorePlayData(const WebRtc_UWord32 nSamples,
124                                const WebRtc_UWord8 nBytesPerSample,
125                                const WebRtc_UWord8 nChannels,
126                                const WebRtc_UWord32 samplesPerSec,
127                                WebRtc_Word8* audioSamples,
128                                WebRtc_UWord32& nSamplesOut);
129                void SetAudioRead(msandroid_sound_read_data *reader);
130                void SetAudioWrite(msandroid_sound_write_data *writer);
131                WebRtc_Word32 StartRecording();
132                WebRtc_Word32 StopRecording();
133                WebRtc_Word32 StartPlayout();
134                WebRtc_Word32 StopPlayout();
135
136        private: 
137                AudioDeviceModule *_audioDevicePtr;
138                AudioDeviceModule::AudioLayer _audioDeviceLayer;
139                msandroid_sound_read_data *_audioRead; 
140                msandroid_sound_write_data *_audioWrite; 
141
142};
143
144
145void msandroid_sound_read_data::StartRecording() {
146        _sndcard->StartRecording();
147}
148
149void msandroid_sound_read_data::StopRecording() {
150        _sndcard->StopRecording();
151}
152
153
154void msandroid_sound_write_data::StartPlayout() {
155        _sndcard->StartPlayout();
156}
157
158void msandroid_sound_write_data::StopPlayout() {
159        _sndcard->StopPlayout();
160}
161
162
163
164MSandroidSoundCardImpl::MSandroidSoundCardImpl() {
165        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
166                        "Ctor called %x", this);
167}
168
169int MSandroidSoundCardImpl::Init() {
170        AudioDeviceModule* external_adm = NULL;
171        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
172                        "Init(external_adm=0x%p , this=%x)", external_adm, this);
173        if (external_adm == NULL)
174        {
175                JNIEnv *jni_env = ms_get_jni_env();
176                JavaVM *jvm = ms_get_jvm();
177                SetAndroidAudioDeviceObjects(jvm, jni_env, NULL);
178                // Create the internal ADM implementation.
179                _audioDeviceLayer = AudioDeviceModule::kPlatformDefaultAudio;
180                _audioDevicePtr = AudioDeviceModuleImpl::Create(10, _audioDeviceLayer);
181
182                if (_audioDevicePtr == NULL)
183                {
184                        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
185                                                     "Init() failed to create the ADM");
186                        return -1;
187                }
188                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
189                        "audiodevce ptr %x!!!!", _audioDevicePtr);
190
191        }
192        else
193        {
194                // Use the already existing external ADM implementation.
195                _audioDevicePtr = external_adm;
196                WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
197                                "An external ADM implementation will be used in VoiceEngine");
198        }
199
200        bool available(false);
201
202        // --------------------
203        // Reinitialize the ADM
204
205        // Register the AudioObserver implementation
206        //_audioDevicePtr->RegisterEventObserver(this);
207
208        _audioDevicePtr->AddRef();
209        // Register the AudioTransport implementation
210        _audioDevicePtr->RegisterAudioCallback(this);
211
212        // ADM initialization
213        if (_audioDevicePtr->Init() != 0)
214        {
215                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
216                                           "Init() failed to initialize the ADM");
217                return -1;
218        }
219
220        // Initialize the default speaker
221        if (_audioDevicePtr->SetPlayoutDevice(WEBRTC_VOICE_ENGINE_DEFAULT_DEVICE)
222                        != 0)
223        {
224                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
225                  "Init() failed to set the default output device");
226        }
227        if (_audioDevicePtr->SpeakerIsAvailable(&available) != 0)
228        {
229                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
230                  "Init() failed to check speaker availability, trying to "
231                 "initialize speaker anyway");
232        }
233        else if (!available)
234        {
235                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
236                    "Init() speaker not available, trying to initialize speaker "
237                   "anyway");
238        }
239        if (_audioDevicePtr->InitSpeaker() != 0)
240        {
241                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
242                   "Init() failed to initialize the speaker");
243        }
244
245        // Initialize the default microphone
246        if (_audioDevicePtr->SetRecordingDevice(WEBRTC_VOICE_ENGINE_DEFAULT_DEVICE)
247                        != 0)
248        {
249                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
250                    "Init() failed to set the default input device");
251        }
252        if (_audioDevicePtr->MicrophoneIsAvailable(&available) != 0)
253        {
254                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
255                   "Init() failed to check microphone availability, trying to "
256                  "initialize microphone anyway");
257        }
258        else if (!available)
259        {
260                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
261                      "Init() microphone not available, trying to initialize "
262                    "microphone anyway");
263        }
264        if (_audioDevicePtr->InitMicrophone() != 0)
265        {
266                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
267                    "Init() failed to initialize the microphone");
268        }
269
270        // Set number of channels
271        _audioDevicePtr->StereoPlayoutIsAvailable(&available);
272        if (_audioDevicePtr->SetStereoPlayout(available ? true : false) != 0)
273        {
274                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
275                   "Init() failed to set stereo playout mode");
276        }
277        _audioDevicePtr->StereoRecordingIsAvailable(&available);
278        if (_audioDevicePtr->SetStereoRecording(available ? true : false) != 0)
279        {
280                WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
281                   "Init() failed to set mono recording mode");
282        }
283        _audioDevicePtr->RecordingSampleRate(&gl_sample_rate);
284}
285
286void MSandroidSoundCardImpl::Terminate() {
287        if (_audioDevicePtr != NULL)
288        {
289                if (_audioDevicePtr->StopPlayout() != 0)
290                {
291                        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
292                                        "TerminateInternal() failed to stop "
293                                        "playout");
294                }
295                if (_audioDevicePtr->StopRecording() != 0)
296                {
297                        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
298                                        "TerminateInternal() failed to stop "
299                                        "recording");
300                }
301                _audioDevicePtr->RegisterEventObserver(NULL);
302                _audioDevicePtr->RegisterAudioCallback(NULL);
303                if (_audioDevicePtr->Terminate() != 0)
304                {
305                        WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_instanceId, -1), 
306                                        "TerminateInternal() failed to "
307                                        "terminate the ADM");
308                }
309
310                _audioDevicePtr->Release();
311                _audioDevicePtr = NULL;
312        }
313}
314
315
316void MSandroidSoundCardImpl::SetAudioRead(msandroid_sound_read_data *reader)
317{
318        _audioRead = reader;
319}
320
321void MSandroidSoundCardImpl::SetAudioWrite(msandroid_sound_write_data *writer)
322{
323        _audioWrite = writer;
324}
325
326WebRtc_Word32 MSandroidSoundCardImpl::StartRecording(){
327        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
328                        "VoEBaseImpl::StartSend()");
329        if (_audioDevicePtr->Recording())
330        {
331                return 0;
332        }
333        if (_audioDevicePtr->InitRecording() != 0)
334        {
335                WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
336                                "StartSend() failed to initialize recording");
337                return -1;
338        }
339        if (_audioDevicePtr->StartRecording() != 0)
340        {
341                WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
342                                "StartSend() failed to start recording");
343                return -1;
344        }
345
346        return 0;
347}
348
349WebRtc_Word32 MSandroidSoundCardImpl::StopRecording(){
350
351        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
352                        "VoEBaseImpl::StopSend()");
353        if (_audioDevicePtr->StopRecording() != 0)
354                return -1;
355
356        return 0;
357}
358
359WebRtc_Word32 MSandroidSoundCardImpl::StartPlayout(){
360        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
361                        "VoEBaseImpl::StartPlayout()");
362        if (_audioDevicePtr->Playing())
363        {
364                return 0;
365        }
366        if (_audioDevicePtr->InitPlayout() != 0)
367        {
368                WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
369                                "StartPlayout() failed to initialize playout");
370                return -1;
371        }
372        if (_audioDevicePtr->StartPlayout() != 0)
373        {
374                WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
375                                "StartPlayout() failed to start playout");
376                return -1;
377        }
378        return 0;
379
380}
381
382WebRtc_Word32 MSandroidSoundCardImpl::StopPlayout(){
383
384        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
385                        "VoEBaseImpl::StopPlayout()");
386
387        if (_audioDevicePtr->StopPlayout() != 0)
388        {
389                // _engineStatistics.SetLastError(VE_CANNOT_STOP_PLAYOUT, kTraceError,
390                //                  "StopPlayout() failed to stop "
391                //                  "playout");
392                return -1;
393        }
394        return 0;
395}
396
397WebRtc_Word32 MSandroidSoundCardImpl::RecordedDataIsAvailable(
398                const WebRtc_Word8* audioSamples,
399                const WebRtc_UWord32 nSamples,
400                const WebRtc_UWord8 nBytesPerSample,
401                const WebRtc_UWord8 nChannels,
402                const WebRtc_UWord32 samplesPerSec,
403                const WebRtc_UWord32 totalDelayMS,
404                const WebRtc_Word32 clockDrift,
405                const WebRtc_UWord32 currentMicLevel,
406                WebRtc_UWord32& newMicLevel)
407{
408/*      WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
409                        "VoEBaseImpl::RecordedDataIsAvailable(nSamples=%u, "
410                        "nBytesPerSample=%u, nChannels=%u, samplesPerSec=%u, "
411                        "totalDelayMS=%u, clockDrift=%d, currentMicLevel=%u)",
412                        nSamples, nBytesPerSample, nChannels, samplesPerSec,
413                        totalDelayMS, clockDrift, currentMicLevel);
414*/
415        assert(_audioDevicePtr != NULL);
416
417        // Always use mono representation within VoE
418        if (nChannels == 2)
419        {
420                WebRtc_Word16* audio16ptr = (WebRtc_Word16*) audioSamples;
421                WebRtc_Word32 audio32;
422                for (WebRtc_UWord32 i = 0; i < nSamples; i++)
423                {
424                        // y(i) = (1/2)*(x(2i) + x(2i+1)) => (1/2)*(left(i) + right(i))
425                        audio32 = audio16ptr[2 * i];
426                        audio32 += audio16ptr[2 * i + 1];
427                        audio32 >>= 1;
428                        audio16ptr[i] = static_cast<WebRtc_Word16> (audio32);
429                }
430        }
431
432        int length = nSamples * nBytesPerSample;
433
434        mblk_t *m = allocb(length,0);
435        memcpy((WebRtc_Word8 *)m->b_wptr, (WebRtc_Word8 *)audioSamples, length);
436//      ms_error("%i octets read",length);
437        m->b_wptr += length;
438        ms_mutex_lock(&_audioRead->mutex);
439        ms_bufferizer_put (&_audioRead->rb,m);
440        ms_mutex_unlock(&_audioRead->mutex);
441        return 0;
442}
443
444WebRtc_Word32 MSandroidSoundCardImpl::NeedMorePlayData(
445                const WebRtc_UWord32 nSamples,
446                const WebRtc_UWord8 nBytesPerSample,
447                const WebRtc_UWord8 nChannels,
448                const WebRtc_UWord32 samplesPerSec,
449                WebRtc_Word8* audioSamples,
450                WebRtc_UWord32& nSamplesOut)
451{
452        WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
453                        "VoEBaseImpl::NeedMorePlayData(nSamples=%u, "
454                        "nBytesPerSample=%d, nChannels=%d, samplesPerSec=%u)",
455                        nSamples, nBytesPerSample, nChannels, samplesPerSec);
456
457        int bufferizer_size;
458        int payloadDataLengthInBytes = nSamples * 2;
459        uint8_t tmpBuff[nSamples * 2 + 4];
460
461        ms_mutex_lock(&_audioWrite->mutex);
462
463        if((bufferizer_size = ms_bufferizer_get_avail(&_audioWrite->bf)) >= payloadDataLengthInBytes) {
464                ms_bufferizer_read(&_audioWrite->bf, tmpBuff, payloadDataLengthInBytes);
465                ms_mutex_unlock(&_audioWrite->mutex);
466                memcpy((WebRtc_Word16*) audioSamples,
467                        (const WebRtc_Word16*) tmpBuff ,
468                        sizeof(WebRtc_Word16) * (payloadDataLengthInBytes));
469
470                nSamplesOut = nSamples;
471        }else {
472                ms_mutex_unlock(&_audioWrite->mutex);
473
474                memset((WebRtc_Word16*) audioSamples,0 ,
475                        sizeof(WebRtc_Word16) * (payloadDataLengthInBytes));
476                nSamplesOut = 0;
477        }
478
479        return 0;
480}
481
482void msandroid_sound_init(MSSndCard *card){
483        MSandroidSoundCardImpl *sndcard = (MSandroidSoundCardImpl *)card->data; 
484        if (sndcard == NULL){
485        sndcard = new MSandroidSoundCardImpl();
486        card->data = sndcard;
487        sndcard->Init();
488        }
489}
490
491
492void msandroid_sound_uninit(MSSndCard *card){
493        MSandroidSoundCardImpl *sndcard = (MSandroidSoundCardImpl *)card->data; 
494        sndcard->Terminate();
495}
496
497void msandroid_sound_detect(MSSndCardManager *m);
498MSSndCard *msandroid_sound_duplicate(MSSndCard *obj);
499
500MSFilter *msandroid_sound_read_new(MSSndCard *card);
501MSFilter *msandroid_sound_write_new(MSSndCard *card);
502
503MSSndCardDesc msandroid_sound_card_desc = {
504        /*.driver_type=*/"ANDROID SND WEBRTC",
505        /*.detect=*/ msandroid_sound_detect,
506        /*.init=*/msandroid_sound_init,
507        /*.set_level=*/msandroid_sound_set_level,
508        /*.get_level=*/msandroid_sound_get_level,
509        /*.set_capture=*/msandroid_sound_set_source,
510        /*.set_control=*/NULL,
511        /*.get_control=*/NULL,
512        /*.create_reader=*/msandroid_sound_read_new,
513        /*.create_writer=*/msandroid_sound_write_new,
514        /*.uninit=*/msandroid_sound_uninit,
515        /*.duplicate=*/msandroid_sound_duplicate
516};
517
518MSSndCard *msandroid_sound_duplicate(MSSndCard *obj){
519        MSSndCard *card=ms_snd_card_new(&msandroid_sound_card_desc);
520        card->name=ms_strdup(obj->name);
521        MSandroidSoundCardImpl *sndcard = new MSandroidSoundCardImpl();
522        card->data = sndcard;
523        sndcard->Init();
524        return card;
525}
526
527MSSndCard *msandroid_sound_card_new(){
528        MSSndCard *card=ms_snd_card_new(&msandroid_sound_card_desc);
529        card->name=ms_strdup("Android Webrtc Sound card");
530        card->data = new MSandroidSoundCardImpl();
531        MSandroidSoundCardImpl *sndcard = new MSandroidSoundCardImpl();
532        card->data = sndcard;
533        sndcard->Init();
534        return card;
535}
536
537void msandroid_sound_detect(MSSndCardManager *m){
538        ms_debug("msandroid_sound_detect");
539        MSSndCard *card=msandroid_sound_card_new();
540        ms_snd_card_manager_add_card(m,card);
541}
542
543
544/*************filter commun functions*********/
545
546static int get_rate(MSFilter *f, void *data){
547        msandroid_sound_data *d=(msandroid_sound_data*)f->data;
548        *(int*)data=gl_sample_rate;
549        return 0;
550}
551
552
553static int set_nchannels(MSFilter *f, void *arg){
554        ms_debug("set_nchannels %d NOT IMPLENTED", *((int*)arg));
555        return -1;
556}
557
558
559
560
561/***********************************read filter********************/
562static int set_read_rate(MSFilter *f, void *arg){
563        ms_debug("set_rate %d NOT IMPLEMENTED",proposed_rate);
564        return -1;
565}
566
567static int get_latency(MSFilter *f, void *arg){
568        ms_debug("NOT IMPLEMENTED");
569        return -1;
570}
571
572
573MSFilterMethod msandroid_sound_read_methods[]={
574        {       MS_FILTER_SET_SAMPLE_RATE       , set_read_rate },
575        {       MS_FILTER_GET_SAMPLE_RATE       , get_rate      },
576        {       MS_FILTER_SET_NCHANNELS         , set_nchannels },
577        {       MS_FILTER_GET_LATENCY   , get_latency},
578        {       0                               , NULL          }
579};
580
581
582static void sound_read_preprocess(MSFilter *f){
583        msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data;
584        ms_warning("andsnd_read_preprocess");
585        d->StartRecording();
586        d->started = true;
587}
588
589static void sound_read_postprocess(MSFilter *f){
590        msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data;
591        d->StopRecording();
592        d->started = false;
593}
594
595static void sound_read_process(MSFilter *f){
596        msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data;
597        int nbytes=0.02*(float)gl_sample_rate*2.0;
598
599        int err;
600        if (d->started)
601        do {
602                mblk_t *om=allocb(nbytes,0);
603                ms_mutex_lock(&d->mutex);
604                err=ms_bufferizer_read(&d->rb,om->b_wptr,nbytes);
605                ms_mutex_unlock(&d->mutex);
606                if (err==nbytes){
607                        om->b_wptr+=nbytes;
608                        ms_queue_put(f->outputs[0],om);
609                }else freemsg(om);
610        }while(err==nbytes);
611}
612
613
614static MSFilterDesc msandroid_sound_read_desc={
615        /*.id=*/MS_FILTER_PLUGIN_ID,
616        /*.name=*/"MSAndSoundReadWebRTC",
617        /*.text=*/N_("Sound capture filter for Android using webrtc"),
618        /*.category=*/MS_FILTER_OTHER,
619        /*.enc_fmt*/NULL,
620        /*.ninputs=*/0,
621        /*.noutputs=*/1,
622        /*.init*/NULL,
623        /*.preprocess=*/sound_read_preprocess,
624        /*.process=*/sound_read_process,
625        /*.postprocess=*/sound_read_postprocess,
626        /*.uninit*/NULL,
627        /*.methods=*/msandroid_sound_read_methods
628};
629
630MSFilter *msandroid_sound_read_new(MSSndCard *card){
631        ms_debug("msandroid_sound_read_new");
632        MSandroidSoundCardImpl *sndcard = (MSandroidSoundCardImpl *)card->data; 
633        MSFilter *f=ms_filter_new_from_desc(&msandroid_sound_read_desc);
634        msandroid_sound_read_data *data=new msandroid_sound_read_data(sndcard);
635        f->data = data;
636        sndcard->SetAudioRead(data);
637        return f;
638}
639
640MS_FILTER_DESC_EXPORT(msandroid_sound_read_desc)
641
642/***********************************write filter********************/
643static int set_write_rate(MSFilter *f, void *arg){
644       
645        return -1;
646}
647
648MSFilterMethod msandroid_sound_write_methods[]={
649        {       MS_FILTER_SET_SAMPLE_RATE       , set_write_rate        },
650        {       MS_FILTER_GET_SAMPLE_RATE       , get_rate      },
651        {       MS_FILTER_SET_NCHANNELS         , set_nchannels },
652        {       0                               , NULL          }
653};
654
655void msandroid_sound_write_preprocess(MSFilter *f){
656        ms_debug("andsnd_write_preprocess");
657        msandroid_sound_write_data *d=(msandroid_sound_write_data*)f->data;
658        d->StartPlayout();
659        d->started = true;
660}
661
662void msandroid_sound_write_postprocess(MSFilter *f){
663        msandroid_sound_write_data *d=(msandroid_sound_write_data*)f->data;
664        d->StopPlayout();
665        d->started = false;
666}
667
668void msandroid_sound_write_process(MSFilter *f){
669        msandroid_sound_write_data *d=(msandroid_sound_write_data*)f->data;
670
671        mblk_t *m;
672        while((m=ms_queue_get(f->inputs[0]))!=NULL){
673                if (d->started){
674                        ms_mutex_lock(&d->mutex);
675                        ms_bufferizer_put(&d->bf,m);
676                        ms_mutex_unlock(&d->mutex);
677                }else freemsg(m);
678        }
679}
680
681static MSFilterDesc msandroid_sound_write_desc={
682        /*.id=*/MS_FILTER_PLUGIN_ID,
683        /*.name=*/"MSAndSoundWriteWebRTC",
684        /*.text=*/N_("Sound playback filter for Android using webrtc"),
685        /*.category=*/MS_FILTER_OTHER,
686        /*.enc_fmt*/NULL,
687        /*.ninputs=*/1,
688        /*.noutputs=*/0,
689        /*.init*/NULL,
690        /*.preprocess=*/msandroid_sound_write_preprocess,
691        /*.process=*/msandroid_sound_write_process,
692        /*.postprocess=*/msandroid_sound_write_postprocess,
693        /*.uninit*/NULL,
694        /*.methods=*/msandroid_sound_write_methods
695};
696
697
698MSFilter *msandroid_sound_write_new(MSSndCard *card){
699        ms_debug("msandroid_sound_write_new");
700        MSFilter *f=ms_filter_new_from_desc(&msandroid_sound_write_desc);
701        MSandroidSoundCardImpl *sndcard = (MSandroidSoundCardImpl *)card->data; 
702        msandroid_sound_write_data *data=new msandroid_sound_write_data(sndcard);
703        f->data = data;
704        sndcard->SetAudioWrite(data);
705        return f;
706}
707
708
709MS_FILTER_DESC_EXPORT(msandroid_sound_write_desc)
710
Note: See TracBrowser for help on using the repository browser.