int sa_stream_open(sa_stream_t *s) { if (s == NULL) { return SA_ERROR_NO_INIT; } if (s->output_unit != NULL) { return SA_ERROR_INVALID; } JNIEnv *jenv = GetJNIForThread(); if (!jenv) return SA_ERROR_NO_DEVICE; if ((*jenv)->PushLocalFrame(jenv, 4)) { return SA_ERROR_OOM; } s->at_class = init_jni_bindings(jenv); int32_t chanConfig = s->channels == 1 ? CHANNEL_OUT_MONO : CHANNEL_OUT_STEREO; jobject obj = (*jenv)->NewObject(jenv, s->at_class, at.constructor, STREAM_MUSIC, s->rate, chanConfig, ENCODING_PCM_16BIT, s->bufferSize, MODE_STREAM); jthrowable exception = (*jenv)->ExceptionOccurred(jenv); if (exception) { (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); (*jenv)->DeleteGlobalRef(jenv, s->at_class); (*jenv)->PopLocalFrame(jenv, NULL); return SA_ERROR_INVALID; } if (!obj) { (*jenv)->DeleteGlobalRef(jenv, s->at_class); (*jenv)->PopLocalFrame(jenv, NULL); return SA_ERROR_OOM; } s->output_unit = (*jenv)->NewGlobalRef(jenv, obj); (*jenv)->PopLocalFrame(jenv, NULL); ALOG("%x - New stream %d %d", s, s->rate, s->channels); return SA_SUCCESS; }
ANPAudioTrack* anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz ANPSampleFormat format, int channelCount, // MONO=1, STEREO=2 ANPAudioCallbackProc proc, void* user) { ANPAudioTrack *s = (ANPAudioTrack*) malloc(sizeof(ANPAudioTrack)); if (s == NULL) { return NULL; } JNIEnv *jenv = GetJNIForThread(); if (!jenv) return NULL; s->at_class = init_jni_bindings(jenv); s->rate = sampleRate; s->channels = channelCount; s->bufferSize = s->rate * s->channels; s->isStopped = true; s->keepGoing = false; s->user = user; s->proc = proc; s->format = format; int jformat; switch (format) { case kPCM16Bit_ANPSampleFormat: jformat = ENCODING_PCM_16BIT; break; case kPCM8Bit_ANPSampleFormat: jformat = ENCODING_PCM_8BIT; break; default: LOG("Unknown audio format. defaulting to 16bit."); jformat = ENCODING_PCM_16BIT; break; } int jChannels; switch (channelCount) { case 1: jChannels = CHANNEL_OUT_MONO; break; case 2: jChannels = CHANNEL_OUT_STEREO; break; default: LOG("Unknown channel count. defaulting to mono."); jChannels = CHANNEL_OUT_MONO; break; } mozilla::AutoLocalJNIFrame autoFrame(jenv); jobject obj = jenv->NewObject(s->at_class, at.constructor, STREAM_MUSIC, s->rate, jChannels, jformat, s->bufferSize, MODE_STREAM); if (autoFrame.CheckForException() || obj == NULL) { jenv->DeleteGlobalRef(s->at_class); free(s); return NULL; } jint state = jenv->CallIntMethod(obj, at.getstate); if (autoFrame.CheckForException() || state == STATE_UNINITIALIZED) { jenv->DeleteGlobalRef(s->at_class); free(s); return NULL; } s->output_unit = jenv->NewGlobalRef(obj); return s; }