1 /* 2 * Copyright (C) 2011 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 package com.android.ex.variablespeed; 18 19 import com.android.common.io.MoreCloseables; 20 21 import android.content.Context; 22 import android.content.res.AssetFileDescriptor; 23 import android.net.Uri; 24 25 import java.io.FileDescriptor; 26 import java.io.FileNotFoundException; 27 import java.lang.reflect.Field; 28 29 /** 30 * Provides all the native calls through to the underlying audio library. 31 * <p> 32 * You should not use this class directly. Prefer to use the {@link VariableSpeed} 33 * class instead. 34 */ 35 /*package*/ class VariableSpeedNative { 36 /*package*/ static void loadLibrary() throws UnsatisfiedLinkError, SecurityException { 37 System.loadLibrary("variablespeed"); 38 } 39 40 /*package*/ static boolean playFromContext(Context context, Uri uri) 41 throws FileNotFoundException { 42 AssetFileDescriptor afd = context.getContentResolver().openAssetFileDescriptor(uri, "r"); 43 try { 44 FileDescriptor fileDescriptor = afd.getFileDescriptor(); 45 Field descriptorField = fileDescriptor.getClass().getDeclaredField("descriptor"); 46 descriptorField.setAccessible(true); 47 int fd = descriptorField.getInt(fileDescriptor); 48 VariableSpeedNative.playFileDescriptor(fd, afd.getStartOffset(), afd.getLength()); 49 return true; 50 } catch (SecurityException e) { 51 // Fall through. 52 } catch (NoSuchFieldException e) { 53 // Fall through. 54 } catch (IllegalArgumentException e) { 55 // Fall through. 56 } catch (IllegalAccessException e) { 57 // Fall through. 58 } finally { 59 MoreCloseables.closeQuietly(afd); 60 } 61 return false; 62 } 63 64 /*package*/ static native void playUri(String uri); 65 66 /*package*/ static native void playFileDescriptor(int fd, long offset, long length); 67 68 /*package*/ static native void setVariableSpeed(float speed); 69 70 /*package*/ static native void startPlayback(); 71 72 /*package*/ static native void stopPlayback(); 73 74 /*package*/ static native void shutdownEngine(); 75 76 /*package*/ static native int getCurrentPosition(); 77 78 /*package*/ static native int getTotalDuration(); 79 80 /*package*/ static void initializeEngine(EngineParameters params) { 81 initializeEngine(params.getTargetFrames(), 82 params.getWindowDuration(), params.getWindowOverlapDuration(), 83 params.getMaxPlayBufferCount(), params.getInitialRate(), 84 params.getDecodeBufferInitialSize(), params.getDecodeBufferMaxSize(), 85 params.getStartPositionMillis(), params.getAudioStreamType()); 86 } 87 88 private static native void initializeEngine(int targetFrames, 89 float windowDuration, float windowOverlapDuration, int maxPlayBufferCount, 90 float initialRate, int decodeBufferInitialSize, int decodeBufferMaxSize, 91 int startPositionMillis, int audioStreamType); 92 } 93