AudioGroup.cpp revision 3459d3037cc0c482a27422f1cc000b5e9d289ae8
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdint.h>
19#include <string.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <sys/epoll.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <sys/stat.h>
26#include <sys/time.h>
27#include <time.h>
28#include <arpa/inet.h>
29#include <netinet/in.h>
30
31#define LOG_TAG "AudioGroup"
32#include <cutils/atomic.h>
33#include <utils/Log.h>
34#include <utils/Errors.h>
35#include <utils/RefBase.h>
36#include <utils/threads.h>
37#include <utils/SystemClock.h>
38#include <media/AudioSystem.h>
39#include <media/AudioRecord.h>
40#include <media/AudioTrack.h>
41#include <media/mediarecorder.h>
42
43#include "jni.h"
44#include "JNIHelp.h"
45
46#include "AudioCodec.h"
47
48extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);
49
50namespace {
51
52using namespace android;
53
54int gRandom = -1;
55
56// We use a circular array to implement jitter buffer. The simplest way is doing
57// a modulo operation on the index while accessing the array. However modulo can
58// be expensive on some platforms, such as ARM. Thus we round up the size of the
59// array to the nearest power of 2 and then use bitwise-and instead of modulo.
60// Currently we make it 256ms long and assume packet interval is 32ms or less.
61// The first 64ms is the place where samples get mixed. The rest 192ms is the
62// real jitter buffer. For a stream at 8000Hz it takes 4096 bytes. These numbers
63// are chosen by experiments and each of them can be adjusted as needed.
64
65// Other notes:
66// + We use elapsedRealtime() to get the time. Since we use 32bit variables
67//   instead of 64bit ones, comparison must be done by subtraction.
68// + Sampling rate must be multiple of 1000Hz, and packet length must be in
69//   milliseconds. No floating points.
70// + If we cannot get enough CPU, we drop samples and simulate packet loss.
71// + Resampling is not done yet, so streams in one group must use the same rate.
72//   For the first release we might only support 8kHz and 16kHz.
73
74class AudioStream
75{
76public:
77    AudioStream();
78    ~AudioStream();
79    bool set(int mode, int socket, sockaddr_storage *remote,
80        const char *codecName, int sampleRate, int sampleCount,
81        int codecType, int dtmfType);
82
83    void sendDtmf(int event);
84    bool mix(int32_t *output, int head, int tail, int sampleRate);
85    void encode(int tick, AudioStream *chain);
86    void decode(int tick);
87
88private:
89    enum {
90        NORMAL = 0,
91        SEND_ONLY = 1,
92        RECEIVE_ONLY = 2,
93        LAST_MODE = 2,
94    };
95
96    int mMode;
97    int mSocket;
98    sockaddr_storage mRemote;
99    AudioCodec *mCodec;
100    uint32_t mCodecMagic;
101    uint32_t mDtmfMagic;
102
103    int mTick;
104    int mSampleRate;
105    int mSampleCount;
106    int mInterval;
107
108    int16_t *mBuffer;
109    int mBufferMask;
110    int mBufferHead;
111    int mBufferTail;
112    int mLatencyScore;
113
114    uint16_t mSequence;
115    uint32_t mTimestamp;
116    uint32_t mSsrc;
117
118    int mDtmfEvent;
119    int mDtmfStart;
120
121    AudioStream *mNext;
122
123    friend class AudioGroup;
124};
125
126AudioStream::AudioStream()
127{
128    mSocket = -1;
129    mCodec = NULL;
130    mBuffer = NULL;
131    mNext = NULL;
132}
133
134AudioStream::~AudioStream()
135{
136    close(mSocket);
137    delete mCodec;
138    delete [] mBuffer;
139    LOGD("stream[%d] is dead", mSocket);
140}
141
142bool AudioStream::set(int mode, int socket, sockaddr_storage *remote,
143    const char *codecName, int sampleRate, int sampleCount,
144    int codecType, int dtmfType)
145{
146    if (mode < 0 || mode > LAST_MODE) {
147        return false;
148    }
149    mMode = mode;
150
151    if (codecName) {
152        mRemote = *remote;
153        mCodec = newAudioCodec(codecName);
154        if (!mCodec || !mCodec->set(sampleRate, sampleCount)) {
155            return false;
156        }
157    }
158
159    mCodecMagic = (0x8000 | codecType) << 16;
160    mDtmfMagic = (dtmfType == -1) ? 0 : (0x8000 | dtmfType) << 16;
161
162    mTick = elapsedRealtime();
163    mSampleRate = sampleRate / 1000;
164    mSampleCount = sampleCount;
165    mInterval = mSampleCount / mSampleRate;
166
167    // Allocate jitter buffer.
168    for (mBufferMask = 8192; mBufferMask < sampleRate; mBufferMask <<= 1);
169    mBufferMask >>= 2;
170    mBuffer = new int16_t[mBufferMask];
171    --mBufferMask;
172    mBufferHead = 0;
173    mBufferTail = 0;
174    mLatencyScore = 0;
175
176    // Initialize random bits.
177    read(gRandom, &mSequence, sizeof(mSequence));
178    read(gRandom, &mTimestamp, sizeof(mTimestamp));
179    read(gRandom, &mSsrc, sizeof(mSsrc));
180
181    mDtmfEvent = -1;
182    mDtmfStart = 0;
183
184    // Only take over the socket when succeeded.
185    mSocket = socket;
186
187    LOGD("stream[%d] is configured as %s %dkHz %dms", mSocket,
188        (codecName ? codecName : "RAW"), mSampleRate, mInterval);
189    return true;
190}
191
192void AudioStream::sendDtmf(int event)
193{
194    if (mDtmfMagic != 0) {
195        mDtmfEvent = event << 24;
196        mDtmfStart = mTimestamp + mSampleCount;
197    }
198}
199
200bool AudioStream::mix(int32_t *output, int head, int tail, int sampleRate)
201{
202    if (mMode == SEND_ONLY) {
203        return false;
204    }
205
206    if (head - mBufferHead < 0) {
207        head = mBufferHead;
208    }
209    if (tail - mBufferTail > 0) {
210        tail = mBufferTail;
211    }
212    if (tail - head <= 0) {
213        return false;
214    }
215
216    head *= mSampleRate;
217    tail *= mSampleRate;
218
219    if (sampleRate == mSampleRate) {
220        for (int i = head; i - tail < 0; ++i) {
221            output[i - head] += mBuffer[i & mBufferMask];
222        }
223    } else {
224        // TODO: implement resampling.
225        return false;
226    }
227    return true;
228}
229
230void AudioStream::encode(int tick, AudioStream *chain)
231{
232    if (tick - mTick >= mInterval) {
233        // We just missed the train. Pretend that packets in between are lost.
234        int skipped = (tick - mTick) / mInterval;
235        mTick += skipped * mInterval;
236        mSequence += skipped;
237        mTimestamp += skipped * mSampleCount;
238        LOGD("stream[%d] skips %d packets", mSocket, skipped);
239    }
240
241    tick = mTick;
242    mTick += mInterval;
243    ++mSequence;
244    mTimestamp += mSampleCount;
245
246    if (mMode == RECEIVE_ONLY) {
247        return;
248    }
249
250    // If there is an ongoing DTMF event, send it now.
251    if (mDtmfEvent != -1) {
252        int duration = mTimestamp - mDtmfStart;
253        // Make sure duration is reasonable.
254        if (duration >= 0 && duration < mSampleRate * 100) {
255            duration += mSampleCount;
256            int32_t buffer[4] = {
257                htonl(mDtmfMagic | mSequence),
258                htonl(mDtmfStart),
259                mSsrc,
260                htonl(mDtmfEvent | duration),
261            };
262            if (duration >= mSampleRate * 100) {
263                buffer[3] |= htonl(1 << 23);
264                mDtmfEvent = -1;
265            }
266            sendto(mSocket, buffer, sizeof(buffer), MSG_DONTWAIT,
267                (sockaddr *)&mRemote, sizeof(mRemote));
268            return;
269        }
270        mDtmfEvent = -1;
271    }
272
273    // It is time to mix streams.
274    bool mixed = false;
275    int32_t buffer[mSampleCount + 3];
276    memset(buffer, 0, sizeof(buffer));
277    while (chain) {
278        if (chain != this &&
279            chain->mix(buffer, tick - mInterval, tick, mSampleRate)) {
280            mixed = true;
281        }
282        chain = chain->mNext;
283    }
284    if (!mixed) {
285        LOGD("stream[%d] no data", mSocket);
286        return;
287    }
288
289    // Cook the packet and send it out.
290    int16_t samples[mSampleCount];
291    for (int i = 0; i < mSampleCount; ++i) {
292        int32_t sample = buffer[i];
293        if (sample < -32768) {
294            sample = -32768;
295        }
296        if (sample > 32767) {
297            sample = 32767;
298        }
299        samples[i] = sample;
300    }
301    if (!mCodec) {
302        // Special case for device stream.
303        send(mSocket, samples, sizeof(samples), MSG_DONTWAIT);
304        return;
305    }
306
307    buffer[0] = htonl(mCodecMagic | mSequence);
308    buffer[1] = htonl(mTimestamp);
309    buffer[2] = mSsrc;
310    int length = mCodec->encode(&buffer[3], samples);
311    if (length <= 0) {
312        LOGD("stream[%d] encoder error", mSocket);
313        return;
314    }
315    sendto(mSocket, buffer, length + 12, MSG_DONTWAIT, (sockaddr *)&mRemote,
316        sizeof(mRemote));
317}
318
319void AudioStream::decode(int tick)
320{
321    char c;
322    if (mMode == SEND_ONLY) {
323        recv(mSocket, &c, 1, MSG_DONTWAIT);
324        return;
325    }
326
327    // Make sure mBufferHead and mBufferTail are reasonable.
328    if ((unsigned int)(tick + 256 - mBufferHead) > 1024) {
329        mBufferHead = tick - 64;
330        mBufferTail = mBufferHead;
331    }
332
333    if (tick - mBufferHead > 64) {
334        // Throw away outdated samples.
335        mBufferHead = tick - 64;
336        if (mBufferTail - mBufferHead < 0) {
337            mBufferTail = mBufferHead;
338        }
339    }
340
341    if (mBufferTail - tick <= 80) {
342        mLatencyScore = tick;
343    } else if (tick - mLatencyScore >= 5000) {
344        // Reset the jitter buffer to 40ms if the latency keeps larger than 80ms
345        // in the past 5s. This rarely happens, so let us just keep it simple.
346        LOGD("stream[%d] latency control", mSocket);
347        mBufferTail = tick + 40;
348    }
349
350    if (mBufferTail - mBufferHead > 256 - mInterval) {
351        // Buffer overflow. Drop the packet.
352        LOGD("stream[%d] buffer overflow", mSocket);
353        recv(mSocket, &c, 1, MSG_DONTWAIT);
354        return;
355    }
356
357    // Receive the packet and decode it.
358    int16_t samples[mSampleCount];
359    int length = 0;
360    if (!mCodec) {
361        // Special case for device stream.
362        length = recv(mSocket, samples, sizeof(samples),
363            MSG_TRUNC | MSG_DONTWAIT) >> 1;
364    } else {
365        __attribute__((aligned(4))) uint8_t buffer[2048];
366        length = recv(mSocket, buffer, sizeof(buffer),
367            MSG_TRUNC | MSG_DONTWAIT);
368
369        // Do we need to check SSRC, sequence, and timestamp? They are not
370        // reliable but at least they can be used to identity duplicates?
371        if (length < 12 || length > (int)sizeof(buffer) ||
372            (ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
373            LOGD("stream[%d] malformed packet", mSocket);
374            return;
375        }
376        int offset = 12 + ((buffer[0] & 0x0F) << 2);
377        if ((buffer[0] & 0x10) != 0) {
378            offset += 4 + (ntohs(*(uint16_t *)&buffer[offset + 2]) << 2);
379        }
380        if ((buffer[0] & 0x20) != 0) {
381            length -= buffer[length - 1];
382        }
383        length -= offset;
384        if (length >= 0) {
385            length = mCodec->decode(samples, &buffer[offset], length);
386        }
387    }
388    if (length != mSampleCount) {
389        LOGD("stream[%d] decoder error", mSocket);
390        return;
391    }
392
393    if (tick - mBufferTail > 0) {
394        // Buffer underrun. Reset the jitter buffer to 40ms.
395        LOGD("stream[%d] buffer underrun", mSocket);
396        if (mBufferTail - mBufferHead <= 0) {
397            mBufferHead = tick + 40;
398            mBufferTail = mBufferHead;
399        } else {
400            int tail = (tick + 40) * mSampleRate;
401            for (int i = mBufferTail * mSampleRate; i - tail < 0; ++i) {
402                mBuffer[i & mBufferMask] = 0;
403            }
404            mBufferTail = tick + 40;
405        }
406    }
407
408    // Append to the jitter buffer.
409    int tail = mBufferTail * mSampleRate;
410    for (int i = 0; i < mSampleCount; ++i) {
411        mBuffer[tail & mBufferMask] = samples[i];
412        ++tail;
413    }
414    mBufferTail += mInterval;
415}
416
417//------------------------------------------------------------------------------
418
419class AudioGroup
420{
421public:
422    AudioGroup();
423    ~AudioGroup();
424    bool set(int sampleRate, int sampleCount);
425
426    bool setMode(int mode);
427    bool sendDtmf(int event);
428    bool add(AudioStream *stream);
429    bool remove(int socket);
430
431private:
432    enum {
433        ON_HOLD = 0,
434        MUTED = 1,
435        NORMAL = 2,
436        EC_ENABLED = 3,
437        LAST_MODE = 3,
438    };
439    int mMode;
440    AudioStream *mChain;
441    int mEventQueue;
442    volatile int mDtmfEvent;
443
444    int mSampleCount;
445    int mDeviceSocket;
446    AudioTrack mTrack;
447    AudioRecord mRecord;
448
449    bool networkLoop();
450    bool deviceLoop();
451
452    class NetworkThread : public Thread
453    {
454    public:
455        NetworkThread(AudioGroup *group) : Thread(false), mGroup(group) {}
456
457        bool start()
458        {
459            if (run("Network", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
460                LOGE("cannot start network thread");
461                return false;
462            }
463            return true;
464        }
465
466    private:
467        AudioGroup *mGroup;
468        bool threadLoop()
469        {
470            return mGroup->networkLoop();
471        }
472    };
473    sp<NetworkThread> mNetworkThread;
474
475    class DeviceThread : public Thread
476    {
477    public:
478        DeviceThread(AudioGroup *group) : Thread(false), mGroup(group) {}
479
480        bool start()
481        {
482            char c;
483            while (recv(mGroup->mDeviceSocket, &c, 1, MSG_DONTWAIT) == 1);
484
485            if (run("Device", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
486                LOGE("cannot start device thread");
487                return false;
488            }
489            return true;
490        }
491
492    private:
493        AudioGroup *mGroup;
494        bool threadLoop()
495        {
496            return mGroup->deviceLoop();
497        }
498    };
499    sp<DeviceThread> mDeviceThread;
500};
501
502AudioGroup::AudioGroup()
503{
504    mMode = ON_HOLD;
505    mChain = NULL;
506    mEventQueue = -1;
507    mDtmfEvent = -1;
508    mDeviceSocket = -1;
509    mNetworkThread = new NetworkThread(this);
510    mDeviceThread = new DeviceThread(this);
511}
512
513AudioGroup::~AudioGroup()
514{
515    mNetworkThread->requestExitAndWait();
516    mDeviceThread->requestExitAndWait();
517    mTrack.stop();
518    mRecord.stop();
519    close(mEventQueue);
520    close(mDeviceSocket);
521    while (mChain) {
522        AudioStream *next = mChain->mNext;
523        delete mChain;
524        mChain = next;
525    }
526    LOGD("group[%d] is dead", mDeviceSocket);
527}
528
529bool AudioGroup::set(int sampleRate, int sampleCount)
530{
531    mEventQueue = epoll_create(2);
532    if (mEventQueue == -1) {
533        LOGE("epoll_create: %s", strerror(errno));
534        return false;
535    }
536
537    mSampleCount = sampleCount;
538
539    // Find out the frame count for AudioTrack and AudioRecord.
540    int output = 0;
541    int input = 0;
542    if (AudioTrack::getMinFrameCount(&output, AudioSystem::VOICE_CALL,
543        sampleRate) != NO_ERROR || output <= 0 ||
544        AudioRecord::getMinFrameCount(&input, sampleRate,
545        AudioSystem::PCM_16_BIT, 1) != NO_ERROR || input <= 0) {
546        LOGE("cannot compute frame count");
547        return false;
548    }
549    LOGD("reported frame count: output %d, input %d", output, input);
550
551    output = (output + sampleCount - 1) / sampleCount * sampleCount;
552    input = (input + sampleCount - 1) / sampleCount * sampleCount;
553    if (input < output * 2) {
554        input = output * 2;
555    }
556    LOGD("adjusted frame count: output %d, input %d", output, input);
557
558    // Initialize AudioTrack and AudioRecord.
559    if (mTrack.set(AudioSystem::VOICE_CALL, sampleRate, AudioSystem::PCM_16_BIT,
560        AudioSystem::CHANNEL_OUT_MONO, output) != NO_ERROR ||
561        mRecord.set(AUDIO_SOURCE_MIC, sampleRate, AudioSystem::PCM_16_BIT,
562        AudioSystem::CHANNEL_IN_MONO, input) != NO_ERROR) {
563        LOGE("cannot initialize audio device");
564        return false;
565    }
566    LOGD("latency: output %d, input %d", mTrack.latency(), mRecord.latency());
567
568    // TODO: initialize echo canceler here.
569
570    // Create device socket.
571    int pair[2];
572    if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair)) {
573        LOGE("socketpair: %s", strerror(errno));
574        return false;
575    }
576    mDeviceSocket = pair[0];
577
578    // Create device stream.
579    mChain = new AudioStream;
580    if (!mChain->set(AudioStream::NORMAL, pair[1], NULL, NULL,
581        sampleRate, sampleCount, -1, -1)) {
582        close(pair[1]);
583        LOGE("cannot initialize device stream");
584        return false;
585    }
586
587    // Give device socket a reasonable timeout and buffer size.
588    timeval tv;
589    tv.tv_sec = 0;
590    tv.tv_usec = 1000 * sampleCount / sampleRate * 500;
591    if (setsockopt(pair[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) ||
592        setsockopt(pair[0], SOL_SOCKET, SO_RCVBUF, &output, sizeof(output)) ||
593        setsockopt(pair[1], SOL_SOCKET, SO_SNDBUF, &output, sizeof(output))) {
594        LOGE("setsockopt: %s", strerror(errno));
595        return false;
596    }
597
598    // Add device stream into event queue.
599    epoll_event event;
600    event.events = EPOLLIN;
601    event.data.ptr = mChain;
602    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, pair[1], &event)) {
603        LOGE("epoll_ctl: %s", strerror(errno));
604        return false;
605    }
606
607    // Anything else?
608    LOGD("stream[%d] joins group[%d]", pair[1], pair[0]);
609    return true;
610}
611
612bool AudioGroup::setMode(int mode)
613{
614    if (mode < 0 || mode > LAST_MODE) {
615        return false;
616    }
617    if (mMode == mode) {
618        return true;
619    }
620
621    LOGD("group[%d] switches from mode %d to %d", mDeviceSocket, mMode, mode);
622    mMode = mode;
623
624    mDeviceThread->requestExitAndWait();
625    if (mode == ON_HOLD) {
626        mTrack.stop();
627        mRecord.stop();
628        return true;
629    }
630
631    mTrack.start();
632    if (mode == MUTED) {
633        mRecord.stop();
634    } else {
635        mRecord.start();
636    }
637
638    if (!mDeviceThread->start()) {
639        mTrack.stop();
640        mRecord.stop();
641        return false;
642    }
643    return true;
644}
645
646bool AudioGroup::sendDtmf(int event)
647{
648    if (event < 0 || event > 15) {
649        return false;
650    }
651
652    // DTMF is rarely used, so we try to make it as lightweight as possible.
653    // Using volatile might be dodgy, but using a pipe or pthread primitives
654    // or stop-set-restart threads seems too heavy. Will investigate later.
655    timespec ts;
656    ts.tv_sec = 0;
657    ts.tv_nsec = 100000000;
658    for (int i = 0; mDtmfEvent != -1 && i < 20; ++i) {
659        nanosleep(&ts, NULL);
660    }
661    if (mDtmfEvent != -1) {
662        return false;
663    }
664    mDtmfEvent = event;
665    nanosleep(&ts, NULL);
666    return true;
667}
668
669bool AudioGroup::add(AudioStream *stream)
670{
671    mNetworkThread->requestExitAndWait();
672
673    epoll_event event;
674    event.events = EPOLLIN;
675    event.data.ptr = stream;
676    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, stream->mSocket, &event)) {
677        LOGE("epoll_ctl: %s", strerror(errno));
678        return false;
679    }
680
681    stream->mNext = mChain->mNext;
682    mChain->mNext = stream;
683    if (!mNetworkThread->start()) {
684        // Only take over the stream when succeeded.
685        mChain->mNext = stream->mNext;
686        return false;
687    }
688
689    LOGD("stream[%d] joins group[%d]", stream->mSocket, mDeviceSocket);
690    return true;
691}
692
693bool AudioGroup::remove(int socket)
694{
695    mNetworkThread->requestExitAndWait();
696
697    for (AudioStream *stream = mChain; stream->mNext; stream = stream->mNext) {
698        AudioStream *target = stream->mNext;
699        if (target->mSocket == socket) {
700            stream->mNext = target->mNext;
701            LOGD("stream[%d] leaves group[%d]", socket, mDeviceSocket);
702            delete target;
703            break;
704        }
705    }
706
707    // Do not start network thread if there is only one stream.
708    if (!mChain->mNext || !mNetworkThread->start()) {
709        return false;
710    }
711    return true;
712}
713
714bool AudioGroup::networkLoop()
715{
716    int tick = elapsedRealtime();
717    int deadline = tick + 10;
718    int count = 0;
719
720    for (AudioStream *stream = mChain; stream; stream = stream->mNext) {
721        if (!stream->mTick || tick - stream->mTick >= 0) {
722            stream->encode(tick, mChain);
723        }
724        if (deadline - stream->mTick > 0) {
725            deadline = stream->mTick;
726        }
727        ++count;
728    }
729
730    if (mDtmfEvent != -1) {
731        int event = mDtmfEvent;
732        for (AudioStream *stream = mChain; stream; stream = stream->mNext) {
733            stream->sendDtmf(event);
734        }
735        mDtmfEvent = -1;
736    }
737
738    deadline -= tick;
739    if (deadline < 1) {
740        deadline = 1;
741    }
742
743    epoll_event events[count];
744    count = epoll_wait(mEventQueue, events, count, deadline);
745    if (count == -1) {
746        LOGE("epoll_wait: %s", strerror(errno));
747        return false;
748    }
749    for (int i = 0; i < count; ++i) {
750        ((AudioStream *)events[i].data.ptr)->decode(tick);
751    }
752
753    return true;
754}
755
756bool AudioGroup::deviceLoop()
757{
758    int16_t output[mSampleCount];
759
760    if (recv(mDeviceSocket, output, sizeof(output), 0) <= 0) {
761        memset(output, 0, sizeof(output));
762    }
763    if (mTrack.write(output, sizeof(output)) != (int)sizeof(output)) {
764        LOGE("cannot write to AudioTrack");
765        return false;
766    }
767
768    if (mMode != MUTED) {
769        uint32_t frameCount = mRecord.frameCount();
770        AudioRecord::Buffer input;
771        input.frameCount = frameCount;
772
773        if (mRecord.obtainBuffer(&input, -1) != NO_ERROR) {
774            LOGE("cannot read from AudioRecord");
775            return false;
776        }
777
778        if (input.frameCount < (uint32_t)mSampleCount) {
779            input.frameCount = 0;
780        } else {
781            if (mMode == NORMAL) {
782                send(mDeviceSocket, input.i8, sizeof(output), MSG_DONTWAIT);
783            } else {
784                // TODO: Echo canceller runs here.
785                send(mDeviceSocket, input.i8, sizeof(output), MSG_DONTWAIT);
786            }
787            if (input.frameCount < frameCount) {
788                input.frameCount = mSampleCount;
789            }
790        }
791
792        mRecord.releaseBuffer(&input);
793    }
794
795    return true;
796}
797
798//------------------------------------------------------------------------------
799
800static jfieldID gNative;
801static jfieldID gMode;
802
803jint add(JNIEnv *env, jobject thiz, jint mode,
804    jint socket, jstring jRemoteAddress, jint remotePort,
805    jstring jCodecName, jint sampleRate, jint sampleCount,
806    jint codecType, jint dtmfType)
807{
808    const char *codecName = NULL;
809    AudioStream *stream = NULL;
810    AudioGroup *group = NULL;
811
812    // Sanity check.
813    sockaddr_storage remote;
814    if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
815        // Exception already thrown.
816        return -1;
817    }
818    if (sampleRate < 0 || sampleCount < 0 || codecType < 0 || codecType > 127) {
819        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
820        goto error;
821    }
822    if (!jCodecName) {
823        jniThrowNullPointerException(env, "codecName");
824        return -1;
825    }
826    codecName = env->GetStringUTFChars(jCodecName, NULL);
827    if (!codecName) {
828        // Exception already thrown.
829        return -1;
830    }
831
832    // Create audio stream.
833    stream = new AudioStream;
834    if (!stream->set(mode, socket, &remote, codecName, sampleRate, sampleCount,
835        codecType, dtmfType)) {
836        jniThrowException(env, "java/lang/IllegalStateException",
837            "cannot initialize audio stream");
838        goto error;
839    }
840    socket = -1;
841
842    // Create audio group.
843    group = (AudioGroup *)env->GetIntField(thiz, gNative);
844    if (!group) {
845        int mode = env->GetIntField(thiz, gMode);
846        group = new AudioGroup;
847        if (!group->set(8000, 256) || !group->setMode(mode)) {
848            jniThrowException(env, "java/lang/IllegalStateException",
849                "cannot initialize audio group");
850            goto error;
851        }
852    }
853
854    // Add audio stream into audio group.
855    if (!group->add(stream)) {
856        jniThrowException(env, "java/lang/IllegalStateException",
857            "cannot add audio stream");
858        goto error;
859    }
860
861    // Succeed.
862    env->SetIntField(thiz, gNative, (int)group);
863    env->ReleaseStringUTFChars(jCodecName, codecName);
864    return socket;
865
866error:
867    delete group;
868    delete stream;
869    close(socket);
870    env->SetIntField(thiz, gNative, NULL);
871    env->ReleaseStringUTFChars(jCodecName, codecName);
872    return -1;
873}
874
875void remove(JNIEnv *env, jobject thiz, jint socket)
876{
877    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
878    if (group) {
879        if (socket == -1 || !group->remove(socket)) {
880            delete group;
881            env->SetIntField(thiz, gNative, NULL);
882        }
883    }
884}
885
886void setMode(JNIEnv *env, jobject thiz, jint mode)
887{
888    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
889    if (group && !group->setMode(mode)) {
890        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
891        return;
892    }
893    env->SetIntField(thiz, gMode, mode);
894}
895
896void sendDtmf(JNIEnv *env, jobject thiz, jint event)
897{
898    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
899    if (group && !group->sendDtmf(event)) {
900        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
901    }
902}
903
904JNINativeMethod gMethods[] = {
905    {"add", "(IILjava/lang/String;ILjava/lang/String;IIII)I", (void *)add},
906    {"remove", "(I)V", (void *)remove},
907    {"setMode", "(I)V", (void *)setMode},
908    {"sendDtmf", "(I)V", (void *)sendDtmf},
909};
910
911} // namespace
912
913int registerAudioGroup(JNIEnv *env)
914{
915    gRandom = open("/dev/urandom", O_RDONLY);
916    if (gRandom == -1) {
917        LOGE("urandom: %s", strerror(errno));
918        return -1;
919    }
920
921    jclass clazz;
922    if ((clazz = env->FindClass("android/net/rtp/AudioGroup")) == NULL ||
923        (gNative = env->GetFieldID(clazz, "mNative", "I")) == NULL ||
924        (gMode = env->GetFieldID(clazz, "mMode", "I")) == NULL ||
925        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
926        LOGE("JNI registration failed");
927        return -1;
928    }
929    return 0;
930}
931