android_media_ResampleInputStream.cpp revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2007, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "ResampleInputStream" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/mediarecorder.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <limits.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h" 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// helper function to throw an exception 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void throwException(JNIEnv *env, const char* ex, const char* fmt, int data) { 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jclass cls = env->FindClass(ex)) { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char msg[1000]; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(msg, fmt, data); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ThrowNew(cls, msg); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(cls); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIR_COEF(coef) (short)(0x10000 * coef) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const short fir21[] = { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.006965742326), 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.008428945737), 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.004241280174), 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.022141096893), 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.018765669437), 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.009871891152), 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.024842433247), 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.006121772058), 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.045890841611), 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.021573503509), 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.059681984668), 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.076036275138), 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.072405390275), 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.308255674582), 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.424321210495), 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.308255674582), 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.072405390275), 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.076036275138), 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.059681984668), 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.021573503509), 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.045890841611), 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.006121772058), 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.024842433247), 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.009871891152), 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.018765669437), 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.022141096893), 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF( 0.004241280174), 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.008428945737), 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FIR_COEF(-0.006965742326) 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int nFir21 = sizeof(fir21) / sizeof(fir21[0]); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int BUF_SIZE = 2048; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_ResampleInputStream_fir21(JNIEnv *env, jclass clazz, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray jIn, jint jInOffset, 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray jOut, jint jOutOffset, 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint jNpoints) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // safety first! 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nFir21 + jNpoints > BUF_SIZE) { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throwException(env, "java/lang/IllegalArgumentException", 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "FIR+data too long %d", nFir21 + jNpoints); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // get input data 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short in[BUF_SIZE]; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->GetByteArrayRegion(jIn, jInOffset, (jNpoints * 2 + nFir21 - 1) * 2, (jbyte*)in); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute filter 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short out[BUF_SIZE]; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < jNpoints; i++) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long sum = 0; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const short* firp = &fir21[0]; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const short* inp = &in[i * 2]; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int n = nFir21; --n >= 0; ) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sum += ((long)*firp++) * ((long)*inp++); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out[i] = (short)(sum >> 16); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // save new values 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetByteArrayRegion(jOut, jOutOffset, jNpoints * 2, (jbyte*)out); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"fir21", "([BI[BII)V", (void*)android_media_ResampleInputStream_fir21}, 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_media_ResampleInputStream(JNIEnv *env) 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* const kClassPathName = "android/media/ResampleInputStream"; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clazz = env->FindClass(kClassPathName); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Can't find %s", kClassPathName); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods(env, 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kClassPathName, gMethods, NELEM(gMethods)); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 144