Merge "Make SoundPool use MediaCodec"
This commit is contained in:
@ -543,11 +543,6 @@ public class SoundPool {
|
||||
|
||||
public int load(String path, int priority)
|
||||
{
|
||||
// pass network streams to player
|
||||
if (path.startsWith("http:"))
|
||||
return _load(path, priority);
|
||||
|
||||
// try local path
|
||||
int id = 0;
|
||||
try {
|
||||
File f = new File(path);
|
||||
@ -562,6 +557,7 @@ public class SoundPool {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(Context context, int resId, int priority) {
|
||||
AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
|
||||
int id = 0;
|
||||
@ -576,6 +572,7 @@ public class SoundPool {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(AssetFileDescriptor afd, int priority) {
|
||||
if (afd != null) {
|
||||
long len = afd.getLength();
|
||||
@ -588,16 +585,17 @@ public class SoundPool {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(FileDescriptor fd, long offset, long length, int priority) {
|
||||
return _load(fd, offset, length, priority);
|
||||
}
|
||||
|
||||
private native final int _load(String uri, int priority);
|
||||
|
||||
private native final int _load(FileDescriptor fd, long offset, long length, int priority);
|
||||
|
||||
@Override
|
||||
public native final boolean unload(int soundID);
|
||||
|
||||
@Override
|
||||
public final int play(int soundID, float leftVolume, float rightVolume,
|
||||
int priority, int loop, float rate) {
|
||||
if (isRestricted()) {
|
||||
@ -620,16 +618,22 @@ public class SoundPool {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public native final void pause(int streamID);
|
||||
|
||||
@Override
|
||||
public native final void resume(int streamID);
|
||||
|
||||
@Override
|
||||
public native final void autoPause();
|
||||
|
||||
@Override
|
||||
public native final void autoResume();
|
||||
|
||||
@Override
|
||||
public native final void stop(int streamID);
|
||||
|
||||
@Override
|
||||
public final void setVolume(int streamID, float leftVolume, float rightVolume) {
|
||||
if (isRestricted()) {
|
||||
return;
|
||||
@ -639,16 +643,21 @@ public class SoundPool {
|
||||
|
||||
private native final void _setVolume(int streamID, float leftVolume, float rightVolume);
|
||||
|
||||
@Override
|
||||
public void setVolume(int streamID, float volume) {
|
||||
setVolume(streamID, volume, volume);
|
||||
}
|
||||
|
||||
@Override
|
||||
public native final void setPriority(int streamID, int priority);
|
||||
|
||||
@Override
|
||||
public native final void setLoop(int streamID, int loop);
|
||||
|
||||
@Override
|
||||
public native final void setRate(int streamID, float rate);
|
||||
|
||||
@Override
|
||||
public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
|
||||
{
|
||||
synchronized(mLock) {
|
||||
@ -729,52 +738,69 @@ public class SoundPool {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(Context context, int resId, int priority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(AssetFileDescriptor afd, int priority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int load(FileDescriptor fd, long offset, long length, int priority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean unload(int soundID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int play(int soundID, float leftVolume, float rightVolume,
|
||||
int priority, int loop, float rate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void pause(int streamID) { }
|
||||
|
||||
@Override
|
||||
public final void resume(int streamID) { }
|
||||
|
||||
@Override
|
||||
public final void autoPause() { }
|
||||
|
||||
@Override
|
||||
public final void autoResume() { }
|
||||
|
||||
@Override
|
||||
public final void stop(int streamID) { }
|
||||
|
||||
@Override
|
||||
public final void setVolume(int streamID,
|
||||
float leftVolume, float rightVolume) { }
|
||||
|
||||
@Override
|
||||
public void setVolume(int streamID, float volume) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setPriority(int streamID, int priority) { }
|
||||
|
||||
@Override
|
||||
public final void setLoop(int streamID, int loop) { }
|
||||
|
||||
@Override
|
||||
public final void setRate(int streamID, float rate) { }
|
||||
|
||||
@Override
|
||||
public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void release() { }
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
android_media_SoundPool_SoundPoolImpl.cpp
|
||||
android_media_SoundPool_SoundPoolImpl.cpp \
|
||||
SoundPool.cpp \
|
||||
SoundPoolThread.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
@ -10,7 +12,9 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libutils \
|
||||
libandroid_runtime \
|
||||
libnativehelper \
|
||||
libmedia
|
||||
libmedia \
|
||||
libmediandk \
|
||||
libbinder
|
||||
|
||||
LOCAL_MODULE:= libsoundpool
|
||||
|
||||
|
1018
media/jni/soundpool/SoundPool.cpp
Normal file
1018
media/jni/soundpool/SoundPool.cpp
Normal file
File diff suppressed because it is too large
Load Diff
232
media/jni/soundpool/SoundPool.h
Normal file
232
media/jni/soundpool/SoundPool.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDPOOL_H_
|
||||
#define SOUNDPOOL_H_
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <media/AudioTrack.h>
|
||||
#include <binder/MemoryHeapBase.h>
|
||||
#include <binder/MemoryBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
static const int IDLE_PRIORITY = -1;
|
||||
|
||||
// forward declarations
|
||||
class SoundEvent;
|
||||
class SoundPoolThread;
|
||||
class SoundPool;
|
||||
|
||||
// for queued events
|
||||
class SoundPoolEvent {
|
||||
public:
|
||||
SoundPoolEvent(int msg, int arg1=0, int arg2=0) :
|
||||
mMsg(msg), mArg1(arg1), mArg2(arg2) {}
|
||||
int mMsg;
|
||||
int mArg1;
|
||||
int mArg2;
|
||||
enum MessageType { INVALID, SAMPLE_LOADED };
|
||||
};
|
||||
|
||||
// callback function prototype
|
||||
typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user);
|
||||
|
||||
// tracks samples used by application
|
||||
class Sample : public RefBase {
|
||||
public:
|
||||
enum sample_state { UNLOADED, LOADING, READY, UNLOADING };
|
||||
Sample(int sampleID, int fd, int64_t offset, int64_t length);
|
||||
~Sample();
|
||||
int sampleID() { return mSampleID; }
|
||||
int numChannels() { return mNumChannels; }
|
||||
int sampleRate() { return mSampleRate; }
|
||||
audio_format_t format() { return mFormat; }
|
||||
size_t size() { return mSize; }
|
||||
int state() { return mState; }
|
||||
uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); }
|
||||
status_t doLoad();
|
||||
void startLoad() { mState = LOADING; }
|
||||
sp<IMemory> getIMemory() { return mData; }
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
size_t mSize;
|
||||
volatile int32_t mRefCount;
|
||||
uint16_t mSampleID;
|
||||
uint16_t mSampleRate;
|
||||
uint8_t mState : 3;
|
||||
uint8_t mNumChannels : 2;
|
||||
audio_format_t mFormat;
|
||||
int mFd;
|
||||
int64_t mOffset;
|
||||
int64_t mLength;
|
||||
sp<IMemory> mData;
|
||||
sp<MemoryHeapBase> mHeap;
|
||||
};
|
||||
|
||||
// stores pending events for stolen channels
|
||||
class SoundEvent
|
||||
{
|
||||
public:
|
||||
SoundEvent() : mChannelID(0), mLeftVolume(0), mRightVolume(0),
|
||||
mPriority(IDLE_PRIORITY), mLoop(0), mRate(0) {}
|
||||
void set(const sp<Sample>& sample, int channelID, float leftVolume,
|
||||
float rightVolume, int priority, int loop, float rate);
|
||||
sp<Sample> sample() { return mSample; }
|
||||
int channelID() { return mChannelID; }
|
||||
float leftVolume() { return mLeftVolume; }
|
||||
float rightVolume() { return mRightVolume; }
|
||||
int priority() { return mPriority; }
|
||||
int loop() { return mLoop; }
|
||||
float rate() { return mRate; }
|
||||
void clear() { mChannelID = 0; mSample.clear(); }
|
||||
|
||||
protected:
|
||||
sp<Sample> mSample;
|
||||
int mChannelID;
|
||||
float mLeftVolume;
|
||||
float mRightVolume;
|
||||
int mPriority;
|
||||
int mLoop;
|
||||
float mRate;
|
||||
};
|
||||
|
||||
// for channels aka AudioTracks
|
||||
class SoundChannel : public SoundEvent {
|
||||
public:
|
||||
enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING };
|
||||
SoundChannel() : mState(IDLE), mNumChannels(1),
|
||||
mPos(0), mToggle(0), mAutoPaused(false) {}
|
||||
~SoundChannel();
|
||||
void init(SoundPool* soundPool);
|
||||
void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume,
|
||||
int priority, int loop, float rate);
|
||||
void setVolume_l(float leftVolume, float rightVolume);
|
||||
void setVolume(float leftVolume, float rightVolume);
|
||||
void stop_l();
|
||||
void stop();
|
||||
void pause();
|
||||
void autoPause();
|
||||
void resume();
|
||||
void autoResume();
|
||||
void setRate(float rate);
|
||||
int state() { return mState; }
|
||||
void setPriority(int priority) { mPriority = priority; }
|
||||
void setLoop(int loop);
|
||||
int numChannels() { return mNumChannels; }
|
||||
void clearNextEvent() { mNextEvent.clear(); }
|
||||
void nextEvent();
|
||||
int nextChannelID() { return mNextEvent.channelID(); }
|
||||
void dump();
|
||||
|
||||
private:
|
||||
static void callback(int event, void* user, void *info);
|
||||
void process(int event, void *info, unsigned long toggle);
|
||||
bool doStop_l();
|
||||
|
||||
SoundPool* mSoundPool;
|
||||
sp<AudioTrack> mAudioTrack;
|
||||
SoundEvent mNextEvent;
|
||||
Mutex mLock;
|
||||
int mState;
|
||||
int mNumChannels;
|
||||
int mPos;
|
||||
int mAudioBufferSize;
|
||||
unsigned long mToggle;
|
||||
bool mAutoPaused;
|
||||
};
|
||||
|
||||
// application object for managing a pool of sounds
|
||||
class SoundPool {
|
||||
friend class SoundPoolThread;
|
||||
friend class SoundChannel;
|
||||
public:
|
||||
SoundPool(int maxChannels, const audio_attributes_t* pAttributes);
|
||||
~SoundPool();
|
||||
int load(int fd, int64_t offset, int64_t length, int priority);
|
||||
bool unload(int sampleID);
|
||||
int play(int sampleID, float leftVolume, float rightVolume, int priority,
|
||||
int loop, float rate);
|
||||
void pause(int channelID);
|
||||
void autoPause();
|
||||
void resume(int channelID);
|
||||
void autoResume();
|
||||
void stop(int channelID);
|
||||
void setVolume(int channelID, float leftVolume, float rightVolume);
|
||||
void setPriority(int channelID, int priority);
|
||||
void setLoop(int channelID, int loop);
|
||||
void setRate(int channelID, float rate);
|
||||
const audio_attributes_t* attributes() { return &mAttributes; }
|
||||
|
||||
// called from SoundPoolThread
|
||||
void sampleLoaded(int sampleID);
|
||||
|
||||
// called from AudioTrack thread
|
||||
void done_l(SoundChannel* channel);
|
||||
|
||||
// callback function
|
||||
void setCallback(SoundPoolCallback* callback, void* user);
|
||||
void* getUserData() { return mUserData; }
|
||||
|
||||
private:
|
||||
SoundPool() {} // no default constructor
|
||||
bool startThreads();
|
||||
void doLoad(sp<Sample>& sample);
|
||||
sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); }
|
||||
SoundChannel* findChannel (int channelID);
|
||||
SoundChannel* findNextChannel (int channelID);
|
||||
SoundChannel* allocateChannel_l(int priority);
|
||||
void moveToFront_l(SoundChannel* channel);
|
||||
void notify(SoundPoolEvent event);
|
||||
void dump();
|
||||
|
||||
// restart thread
|
||||
void addToRestartList(SoundChannel* channel);
|
||||
void addToStopList(SoundChannel* channel);
|
||||
static int beginThread(void* arg);
|
||||
int run();
|
||||
void quit();
|
||||
|
||||
Mutex mLock;
|
||||
Mutex mRestartLock;
|
||||
Condition mCondition;
|
||||
SoundPoolThread* mDecodeThread;
|
||||
SoundChannel* mChannelPool;
|
||||
List<SoundChannel*> mChannels;
|
||||
List<SoundChannel*> mRestart;
|
||||
List<SoundChannel*> mStop;
|
||||
DefaultKeyedVector< int, sp<Sample> > mSamples;
|
||||
int mMaxChannels;
|
||||
audio_attributes_t mAttributes;
|
||||
int mAllocated;
|
||||
int mNextSampleID;
|
||||
int mNextChannelID;
|
||||
bool mQuit;
|
||||
|
||||
// callback
|
||||
Mutex mCallbackLock;
|
||||
SoundPoolCallback* mCallback;
|
||||
void* mUserData;
|
||||
};
|
||||
|
||||
} // end namespace android
|
||||
|
||||
#endif /*SOUNDPOOL_H_*/
|
114
media/jni/soundpool/SoundPoolThread.cpp
Normal file
114
media/jni/soundpool/SoundPoolThread.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "SoundPoolThread"
|
||||
#include "utils/Log.h"
|
||||
|
||||
#include "SoundPoolThread.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
void SoundPoolThread::write(SoundPoolMsg msg) {
|
||||
Mutex::Autolock lock(&mLock);
|
||||
while (mMsgQueue.size() >= maxMessages) {
|
||||
mCondition.wait(mLock);
|
||||
}
|
||||
|
||||
// if thread is quitting, don't add to queue
|
||||
if (mRunning) {
|
||||
mMsgQueue.push(msg);
|
||||
mCondition.signal();
|
||||
}
|
||||
}
|
||||
|
||||
const SoundPoolMsg SoundPoolThread::read() {
|
||||
Mutex::Autolock lock(&mLock);
|
||||
while (mMsgQueue.size() == 0) {
|
||||
mCondition.wait(mLock);
|
||||
}
|
||||
SoundPoolMsg msg = mMsgQueue[0];
|
||||
mMsgQueue.removeAt(0);
|
||||
mCondition.signal();
|
||||
return msg;
|
||||
}
|
||||
|
||||
void SoundPoolThread::quit() {
|
||||
Mutex::Autolock lock(&mLock);
|
||||
if (mRunning) {
|
||||
mRunning = false;
|
||||
mMsgQueue.clear();
|
||||
mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
|
||||
mCondition.signal();
|
||||
mCondition.wait(mLock);
|
||||
}
|
||||
ALOGV("return from quit");
|
||||
}
|
||||
|
||||
SoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
|
||||
mSoundPool(soundPool)
|
||||
{
|
||||
mMsgQueue.setCapacity(maxMessages);
|
||||
if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
|
||||
mRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
SoundPoolThread::~SoundPoolThread()
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
int SoundPoolThread::beginThread(void* arg) {
|
||||
ALOGV("beginThread");
|
||||
SoundPoolThread* soundPoolThread = (SoundPoolThread*)arg;
|
||||
return soundPoolThread->run();
|
||||
}
|
||||
|
||||
int SoundPoolThread::run() {
|
||||
ALOGV("run");
|
||||
for (;;) {
|
||||
SoundPoolMsg msg = read();
|
||||
ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData);
|
||||
switch (msg.mMessageType) {
|
||||
case SoundPoolMsg::KILL:
|
||||
ALOGV("goodbye");
|
||||
return NO_ERROR;
|
||||
case SoundPoolMsg::LOAD_SAMPLE:
|
||||
doLoadSample(msg.mData);
|
||||
break;
|
||||
default:
|
||||
ALOGW("run: Unrecognized message %d\n",
|
||||
msg.mMessageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPoolThread::loadSample(int sampleID) {
|
||||
write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID));
|
||||
}
|
||||
|
||||
void SoundPoolThread::doLoadSample(int sampleID) {
|
||||
sp <Sample> sample = mSoundPool->findSample(sampleID);
|
||||
status_t status = -1;
|
||||
if (sample != 0) {
|
||||
status = sample->doLoad();
|
||||
}
|
||||
mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status));
|
||||
}
|
||||
|
||||
} // end namespace android
|
66
media/jni/soundpool/SoundPoolThread.h
Normal file
66
media/jni/soundpool/SoundPoolThread.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDPOOLTHREAD_H_
|
||||
#define SOUNDPOOLTHREAD_H_
|
||||
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <media/AudioTrack.h>
|
||||
|
||||
#include "SoundPool.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class SoundPoolMsg {
|
||||
public:
|
||||
enum MessageType { INVALID, KILL, LOAD_SAMPLE };
|
||||
SoundPoolMsg() : mMessageType(INVALID), mData(0) {}
|
||||
SoundPoolMsg(MessageType MessageType, int data) :
|
||||
mMessageType(MessageType), mData(data) {}
|
||||
uint16_t mMessageType;
|
||||
uint16_t mData;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class handles background requests from the SoundPool
|
||||
*/
|
||||
class SoundPoolThread {
|
||||
public:
|
||||
SoundPoolThread(SoundPool* SoundPool);
|
||||
~SoundPoolThread();
|
||||
void loadSample(int sampleID);
|
||||
void quit();
|
||||
void write(SoundPoolMsg msg);
|
||||
|
||||
private:
|
||||
static const size_t maxMessages = 5;
|
||||
|
||||
static int beginThread(void* arg);
|
||||
int run();
|
||||
void doLoadSample(int sampleID);
|
||||
const SoundPoolMsg read();
|
||||
|
||||
Mutex mLock;
|
||||
Condition mCondition;
|
||||
Vector<SoundPoolMsg> mMsgQueue;
|
||||
SoundPool* mSoundPool;
|
||||
bool mRunning;
|
||||
};
|
||||
|
||||
} // end namespace android
|
||||
|
||||
#endif /*SOUNDPOOLTHREAD_H_*/
|
@ -23,7 +23,7 @@
|
||||
#include <nativehelper/jni.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <media/SoundPool.h>
|
||||
#include "SoundPool.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
@ -45,20 +45,6 @@ struct audio_attributes_fields_t {
|
||||
static audio_attributes_fields_t javaAudioAttrFields;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint
|
||||
android_media_SoundPool_SoundPoolImpl_load_URL(JNIEnv *env, jobject thiz, jstring path, jint priority)
|
||||
{
|
||||
ALOGV("android_media_SoundPool_SoundPoolImpl_load_URL");
|
||||
SoundPool *ap = MusterSoundPool(env, thiz);
|
||||
if (path == NULL) {
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
|
||||
return 0;
|
||||
}
|
||||
const char* s = env->GetStringUTFChars(path, NULL);
|
||||
int id = ap->load(s, priority);
|
||||
env->ReleaseStringUTFChars(path, s);
|
||||
return (jint) id;
|
||||
}
|
||||
|
||||
static jint
|
||||
android_media_SoundPool_SoundPoolImpl_load_FD(JNIEnv *env, jobject thiz, jobject fileDescriptor,
|
||||
@ -248,10 +234,6 @@ android_media_SoundPool_SoundPoolImpl_release(JNIEnv *env, jobject thiz)
|
||||
|
||||
// Dalvik VM type signatures
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{ "_load",
|
||||
"(Ljava/lang/String;I)I",
|
||||
(void *)android_media_SoundPool_SoundPoolImpl_load_URL
|
||||
},
|
||||
{ "_load",
|
||||
"(Ljava/io/FileDescriptor;JJI)I",
|
||||
(void *)android_media_SoundPool_SoundPoolImpl_load_FD
|
||||
|
Reference in New Issue
Block a user