2015-03-11 22 views
5

Superpowered SDK CrossExample projesini android stüdyosuna başarıyla aktardım ve Samsung galaxy S3 ve emülatörde test ettim. Artık SuperpoweredRecorder.h kullanarak uygulamanın oynadığı sesi kaydetmek için bir kayıt seçeneği uyguluyorum. Kaydı başarıyla kaydetmek için *tempPath ve *destinationPath değişkenlerini doğru şekilde nasıl ayarlayacağınız konusunda yardıma ihtiyacım olacak. Proje tamam, ancak ben Galaxy S3 veya emülatörde uygulamayı çalıştırmaya çalıştığımda aşağıdaki hata iletisini alıyorum: 19565-19565/com.superpowered.crossexample A/libc﹕ Fatal signal 11 (SIGSEGV) at 0x006f0070 (code=1), thread 19565 (ed.crossexample) Bu hatayı * tempPath ve * destinationPath işaretçileri ekledikten sonra oluştu, bu yüzden inanıyorum Kayıt yollarını başarıyla ayarladıktan sonra bu hata gider.Superpowered SDK: SuperpoweredRecorder.h'nin uygulanması ve kayıt yollarının ayarlanması

SuperpoweredRecorder.h belgelerine linki: http://superpowered.com/docs/class_superpowered_recorder.html başka ben tempPath ve destinationPath değişkenleri kullanmak koduna eklemek zorunda ne belgelerine bakarak?

Kendim eklenmiş kod ileri çift eğik çizgi arasındadır.

SuperpoweredExample.h

#ifndef Header_SuperpoweredExample 
#define Header_SuperpoweredExample 

#include <SLES/OpenSLES.h> 
#include <SLES/OpenSLES_Android.h> 
#include <math.h> 
#include <pthread.h> 

#include "SuperpoweredExample.h" 
#include "SuperpoweredAdvancedAudioPlayer.h" 
#include "SuperpoweredFilter.h" 
#include "SuperpoweredRoll.h" 
#include "SuperpoweredFlanger.h" 
#include "SuperpoweredMixer.h" 
#include "SuperpoweredRecorder.h" 

#define NUM_BUFFERS 2 
#define HEADROOM_DECIBEL 3.0f 
static const float headroom = powf(10.0f, -HEADROOM_DECIBEL * 0.025); 

class SuperpoweredExample { 
public: 

SuperpoweredExample(const char *path, int *params); 
~SuperpoweredExample(); 

void process(SLAndroidSimpleBufferQueueItf caller); 
void onPlayPause(bool play); 
void onCrossfader(int value); 
void onFxSelect(int value); 
void onFxOff(); 
void onFxValue(int value); 
//Added function declaration 
void onRecord(bool record); 
// 
private: 
SLObjectItf openSLEngine, outputMix, bufferPlayer; 
SLAndroidSimpleBufferQueueItf bufferQueue; 

SuperpoweredAdvancedAudioPlayer *playerA, *playerB; 
SuperpoweredRoll *roll; 
SuperpoweredFilter *filter; 
SuperpoweredFlanger *flanger; 
SuperpoweredStereoMixer *mixer; 
SuperpoweredRecorder *recorder; 
//added object variables 
const char *tempPath; 
const char *destinationPath; 
// 
unsigned char activeFx; 
float crossValue, volA, volB; 
pthread_mutex_t mutex; 

float *outputBuffer[NUM_BUFFERS]; 
int currentBuffer, buffersize; 
}; 

#endif 

SuperpoweredExample.cpp

#include "SuperpoweredExample.h" 
#include <jni.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <android/log.h> 

static void playerEventCallbackA(void *clientData,   SuperpoweredAdvancedAudioPlayerEvent event, void *value) { 
if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadSuccess) { 
    SuperpoweredAdvancedAudioPlayer *playerA = *  ((SuperpoweredAdvancedAudioPlayer **)clientData); 
    playerA->setBpm(126.0f); 
    playerA->setFirstBeatMs(353); 
    playerA->setPosition(playerA->firstBeatMs, false, false); 
}; 
} 

static void playerEventCallbackB(void *clientData,  SuperpoweredAdvancedAudioPlayerEvent event, void *value) { 
if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadSuccess) { 
    SuperpoweredAdvancedAudioPlayer *playerB = *((SuperpoweredAdvancedAudioPlayer **)clientData); 
    playerB->setBpm(123.0f); 
    playerB->setFirstBeatMs(40); 
    playerB->setPosition(playerB->firstBeatMs, false, false); 
}; 
} 

static void openSLESCallback(SLAndroidSimpleBufferQueueItf caller, void   *pContext) { 
((SuperpoweredExample *)pContext)->process(caller);} 

static const SLboolean requireds[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 

SuperpoweredExample::SuperpoweredExample(const char *path, int *params) :  currentBuffer(0), buffersize(params[5]), activeFx(0), crossValue(0.0f),  volB(0.0f), volA(1.0f * headroom) { 
pthread_mutex_init(&mutex, NULL); // This will keep our player volumes and  playback states in sync. 

for (int n = 0; n < NUM_BUFFERS; n++) outputBuffer[n] = (float  *)memalign(16, (buffersize + 16) * sizeof(float) * 2); 

unsigned int samplerate = params[4]; 

playerA = new SuperpoweredAdvancedAudioPlayer(&playerA ,  playerEventCallbackA, samplerate, 0); 
playerA->open(path, params[0], params[1]); 
playerB = new SuperpoweredAdvancedAudioPlayer(&playerB,  playerEventCallbackB, samplerate, 0); 
playerB->open(path, params[2], params[3]); 

playerA->syncMode = playerB->syncMode =  SuperpoweredAdvancedAudioPlayerSyncMode_TempoAndBeat; 

roll = new SuperpoweredRoll(samplerate); 
filter = new SuperpoweredFilter(SuperpoweredFilter_Resonant_Lowpass,  samplerate); 
flanger = new SuperpoweredFlanger(samplerate); 

mixer = new SuperpoweredStereoMixer(); 

//Create SuperpoweredRecorder and allocate memory for it 
recorder = new SuperpoweredRecorder(tempPath, samplerate); 
// 

// Create the OpenSL ES engine. 
slCreateEngine(&openSLEngine, 0, NULL, 0, NULL, NULL); 
(*openSLEngine)->Realize(openSLEngine, SL_BOOLEAN_FALSE); 
SLEngineItf openSLEngineInterface = NULL; 
(*openSLEngine)->GetInterface(openSLEngine, SL_IID_ENGINE,  &openSLEngineInterface); 
// Create the output mix. 
(*openSLEngineInterface)->CreateOutputMix(openSLEngineInterface, &outputMix,  0, NULL, NULL); 
(*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); 
SLDataLocator_OutputMix outputMixLocator = { SL_DATALOCATOR_OUTPUTMIX,  outputMix }; 

// Create the buffer queue player. 
SLDataLocator_AndroidSimpleBufferQueue bufferPlayerLocator = {  SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFERS }; 
SLDataFormat_PCM bufferPlayerFormat = { SL_DATAFORMAT_PCM, 2, samplerate *  1000, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,  SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN }; 
SLDataSource bufferPlayerSource = { &bufferPlayerLocator,  &bufferPlayerFormat }; 
const SLInterfaceID bufferPlayerInterfaces[1] = { SL_IID_BUFFERQUEUE }; 
SLDataSink bufferPlayerOutput = { &outputMixLocator, NULL }; 
(*openSLEngineInterface)->CreateAudioPlayer(openSLEngineInterface,  &bufferPlayer, &bufferPlayerSource, &bufferPlayerOutput, 1,  bufferPlayerInterfaces, requireds); 
(*bufferPlayer)->Realize(bufferPlayer, SL_BOOLEAN_FALSE); 

// Initialize and start the buffer queue. 
(*bufferPlayer)->GetInterface(bufferPlayer, SL_IID_BUFFERQUEUE,  &bufferQueue); 
(*bufferQueue)->RegisterCallback(bufferQueue, openSLESCallback, this); 
memset(outputBuffer[0], 0, buffersize * 4); 
memset(outputBuffer[1], 0, buffersize * 4); 
(*bufferQueue)->Enqueue(bufferQueue, outputBuffer[0], buffersize * 4); 
(*bufferQueue)->Enqueue(bufferQueue, outputBuffer[1], buffersize * 4); 
SLPlayItf bufferPlayerPlayInterface; 
(*bufferPlayer)->GetInterface(bufferPlayer, SL_IID_PLAY, &bufferPlayerPlayInterface); 
(*bufferPlayerPlayInterface)->SetPlayState(bufferPlayerPlayInterface,  SL_PLAYSTATE_PLAYING); 
} 

SuperpoweredExample::~SuperpoweredExample() { 
for (int n = 0; n < NUM_BUFFERS; n++) free(outputBuffer[n]); 
delete playerA; 
delete playerB; 
delete mixer; 
pthread_mutex_destroy(&mutex); 
} 

void SuperpoweredExample::onPlayPause(bool play) { 
pthread_mutex_lock(&mutex); 
if (!play) { 
    playerA->pause(); 
    playerB->pause(); 
} else { 
    bool masterIsA = (crossValue <= 0.5f); 
    playerA->play(!masterIsA); 
    playerB->play(masterIsA); 
}; 
pthread_mutex_unlock(&mutex); 
} 
//onRecord function 
void SuperpoweredExample::onRecord(bool record) { 
pthread_mutex_lock(&mutex); 
if (!record) { 
    recorder->stop(); 
} else { 
    recorder->start(destinationPath); 
}; 
pthread_mutex_unlock(&mutex); 
} 
// 

void SuperpoweredExample::onCrossfader(int value) { 
pthread_mutex_lock(&mutex); 
crossValue = float(value) * 0.01f; 
if (crossValue < 0.01f) { 
    volA = 1.0f * headroom; 
    volB = 0.0f; 
} else if (crossValue > 0.99f) { 
    volA = 0.0f; 
    volB = 1.0f * headroom; 
} else { // constant power curve 
    volA = cosf(M_PI_2 * crossValue) * headroom; 
    volB = cosf(M_PI_2 * (1.0f - crossValue)) * headroom; 
}; 
pthread_mutex_unlock(&mutex); 
} 

void SuperpoweredExample::onFxSelect(int value) { 
__android_log_print(ANDROID_LOG_VERBOSE, "SuperpoweredExample", "FXSEL %i",  value); 
activeFx = value; 
} 

void SuperpoweredExample::onFxOff() { 
filter->enable(false); 
roll->enable(false); 
flanger->enable(false); 
} 

#define MINFREQ 60.0f 
#define MAXFREQ 20000.0f 

static inline float floatToFrequency(float value) { 
if (value > 0.97f) return MAXFREQ; 
if (value < 0.03f) return MINFREQ; 
value = powf(10.0f, (value + ((0.4f - fabsf(value - 0.4f)) * 0.3f)) *  log10f(MAXFREQ - MINFREQ)) + MINFREQ; 
return value < MAXFREQ ? value : MAXFREQ; 
} 

void SuperpoweredExample::onFxValue(int ivalue) { 
float value = float(ivalue) * 0.01f; 
switch (activeFx) { 
    case 1: 
     filter->setResonantParameters(floatToFrequency(1.0f - value), 0.2f); 
     filter->enable(true); 
     flanger->enable(false); 
     roll->enable(false); 
     break; 
    case 2: 
     if (value > 0.8f) roll->beats = 0.0625f; 
     else if (value > 0.6f) roll->beats = 0.125f; 
     else if (value > 0.4f) roll->beats = 0.25f; 
     else if (value > 0.2f) roll->beats = 0.5f; 
     else roll->beats = 1.0f; 
     roll->enable(true); 
     filter->enable(false); 
     flanger->enable(false); 
     break; 
    default: 
     flanger->setWet(value); 
     flanger->enable(true); 
     filter->enable(false); 
     roll->enable(false); 
}; 
} 

void SuperpoweredExample::process(SLAndroidSimpleBufferQueueItf caller) { 
pthread_mutex_lock(&mutex); 
float *stereoBuffer = outputBuffer[currentBuffer]; 

bool masterIsA = (crossValue <= 0.5f); 
float masterBpm = masterIsA ? playerA->currentBpm : playerB->currentBpm; 
double msElapsedSinceLastBeatA = playerA->msElapsedSinceLastBeat; // When playerB needs it, playerA has already stepped this value, so save it now. 

bool silence = !playerA->process(stereoBuffer, false, buffersize, volA, masterBpm, playerB->msElapsedSinceLastBeat); 
if (playerB->process(stereoBuffer, !silence, buffersize, volB, masterBpm, msElapsedSinceLastBeatA)) silence = false; 

roll->bpm = flanger->bpm = masterBpm; // Syncing fx is one line. 

if (roll->process(silence ? NULL : stereoBuffer, stereoBuffer, buffersize) && silence) silence = false; 
if (!silence) { 
    filter->process(stereoBuffer, stereoBuffer, buffersize); 
    flanger->process(stereoBuffer, stereoBuffer, buffersize); 
    //adding buffer to process function 
    recorder->process(stereoBuffer, 0, buffersize); 
    // 
}; 


pthread_mutex_unlock(&mutex); 

// The stereoBuffer is ready now, let's put the finished audio into the requested buffers. 
if (silence) memset(stereoBuffer, 0, buffersize * 4); else SuperpoweredStereoMixer::floatToShortInt(stereoBuffer, (short int *)stereoBuffer, buffersize); 

(*caller)->Enqueue(caller, stereoBuffer, buffersize * 4); 
if (currentBuffer < NUM_BUFFERS - 1) currentBuffer++; else currentBuffer = 0; 
} 

extern "C" { 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_SuperpoweredExample(JNIEnv *javaEnvironment, jobject self, jstring apkPath, jlongArray offsetAndLength); 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onPlayPause(JNIEnv *javaEnvironment, jobject self, jboolean play); 
//connect onRecord with java 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onRecord(JNIEnv *javaEnvironment, jobject self, jboolean record); 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onCrossfader(JNIEnv *javaEnvironment, jobject self, jint value); 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxSelect(JNIEnv *javaEnvironment, jobject self, jint value); 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxOff(JNIEnv *javaEnvironment, jobject self); 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxValue(JNIEnv *javaEnvironment, jobject self, jint value); 
} 

static SuperpoweredExample *example = NULL; 

// Android is not passing more than 2 custom parameters, so we had to pack file offsets and lengths into an array. 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_SuperpoweredExample(JNIEnv *javaEnvironment, jobject self, jstring apkPath, jlongArray params) { 
// Convert the input jlong array to a regular int array. 
jlong *longParams = javaEnvironment->GetLongArrayElements(params, JNI_FALSE); 
int arr[6]; 
for (int n = 0; n < 6; n++) arr[n] = longParams[n]; 
javaEnvironment->ReleaseLongArrayElements(params, longParams, JNI_ABORT); 

const char *path = javaEnvironment->GetStringUTFChars(apkPath, JNI_FALSE); 
example = new SuperpoweredExample(path, arr); 
javaEnvironment->ReleaseStringUTFChars(apkPath, path); 

} 

JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onPlayPause(JNIEnv *javaEnvironment, jobject self, jboolean play) { 
example->onPlayPause(play); 
} 
//connect onRecord with java code 
JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onRecord(JNIEnv *javaEnvironment, jobject self, jboolean record) { 
example->onRecord(record); 
} 
// 

JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onCrossfader(JNIEnv *javaEnvironment, jobject self, jint value) { 
example->onCrossfader(value); 
} 

JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxSelect(JNIEnv *javaEnvironment, jobject self, jint value) { 
example->onFxSelect(value); 
} 

JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxOff(JNIEnv *javaEnvironment, jobject self) { 
example->onFxOff(); 
} 

JNIEXPORT void Java_com_superpowered_crossexample_MainActivity_onFxValue(JNIEnv *javaEnvironment, jobject self, jint value) { 
example->onFxValue(value); 
} 

MainActivity.java

package com.superpowered.crossexample; 

import android.content.Context; 
import android.content.res.AssetFileDescriptor; 
import android.media.AudioManager; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Button; 
import android.widget.RadioButton; 
import android.widget.RadioGroup; 
import android.widget.SeekBar; 
import android.widget.SeekBar.OnSeekBarChangeListener; 

import java.io.IOException; 

public class MainActivity extends ActionBarActivity { 
boolean playing = false; 
//Added variable 
boolean recording = false; 
// 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // Get the device's sample rate and buffer size to enable low-latency Android audio output, if available. 
    String samplerateString = null, buffersizeString = null; 
    if (Build.VERSION.SDK_INT >= 17) { 
     AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); 
     samplerateString = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); 
     buffersizeString = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER); 
    } 
    if (samplerateString == null) samplerateString = "44100"; 
    if (buffersizeString == null) buffersizeString = "512"; 

    // Files under res/raw are not compressed, just copied into the APK. Get the offset and length to know where our files are located. 
    AssetFileDescriptor fd0 = getResources().openRawResourceFd(R.raw.lycka), fd1 = getResources().openRawResourceFd(R.raw.nuyorica); 
    long[] params = { 
      fd0.getStartOffset(), 
      fd0.getLength(), 
      fd1.getStartOffset(), 
      fd1.getLength(), 
      Integer.parseInt(samplerateString), 
      Integer.parseInt(buffersizeString) 
    }; 
    try { 
     fd0.getParcelFileDescriptor().close(); 
     fd1.getParcelFileDescriptor().close(); 
    } catch (IOException e) {} 

    // Arguments: path to the APK file, offset and length of the two resource files, sample rate, audio buffer size. 
    SuperpoweredExample(getPackageResourcePath(), params); 

    // crossfader events 
    final SeekBar crossfader = (SeekBar)findViewById(R.id.crossFader); 
    crossfader.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 

     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      onCrossfader(progress); 
     } 

     public void onStartTrackingTouch(SeekBar seekBar) {} 
     public void onStopTrackingTouch(SeekBar seekBar) {} 
    }); 

    // fx fader events 
    final SeekBar fxfader = (SeekBar)findViewById(R.id.fxFader); 
    fxfader.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 

     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      onFxValue(progress); 
     } 

     public void onStartTrackingTouch(SeekBar seekBar) { 
      onFxValue(seekBar.getProgress()); 
     } 

     public void onStopTrackingTouch(SeekBar seekBar) { 
      onFxOff(); 
     } 
    }); 

    // fx select event 
    final RadioGroup group = (RadioGroup)findViewById(R.id.radioGroup1); 
    group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 
     public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { 
      RadioButton checkedRadioButton = (RadioButton)radioGroup.findViewById(checkedId); 
      onFxSelect(radioGroup.indexOfChild(checkedRadioButton)); 
     } 
    }); 
} 

public void SuperpoweredExample_PlayPause(View button) { // Play/pause. 
    playing = !playing; 
    onPlayPause(playing); 
    Button b = (Button) findViewById(R.id.playPause); 
    b.setText(playing ? "Pause" : "Play"); 
} 
//Added the following Record method 
public void SuperpoweredExample_Record(View button) { // Record/Stop Recording. 
    recording = !recording; 
    onRecord(recording); 
    Button r = (Button) findViewById(R.id.rec); 
    r.setText(recording ? "Start Recording" : "Stop Recording"); 
} 
// 
@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

private native void SuperpoweredExample(String apkPath, long[] offsetAndLength); 
private native void onPlayPause(boolean play); 
private native void onCrossfader(int value); 
private native void onFxSelect(int value); 
private native void onFxOff(); 
private native void onFxValue(int value); 
//Added the following line 
private native void onRecord(boolean record); 
// 

static { 
    System.loadLibrary("SuperpoweredExample"); 
} 
} 
+0

bunu çözdünüz mü? –

+0

Çözünürlük yok –

+0

Aynı konuyla karşı karşıyayım, herhangi bir yardım buldunuz mu ya da tamir ettiniz ???? –

cevap

2

bir segment hataya alıyorsanız, bu sizin uygulama kokan olasıdır t WRITE_EXTERNAL_STORAGE iznini bildirin (CrossExample bunun gibi değil) hiçbir şey yazmıyor. Devam ederse, içeren dizin mevcut olmayabilir - ör. "/ Sdcard/varolmayan/out".

1

Bunun çok geç olduğunu anlıyorum ama eğer herhangi bir kullanım varsa, moe'nun doğru olduğuna inanıyorum; Ancak, API 23'ten itibaren, yalnızca manifestinizde WRITE_EXTERNAL_STORAGE iznine sahip olmak yeterli değildir. Ayrıca, yeni izin modelleri nedeniyle bu izni açıkça kontrol etmeniz ve sormanız gerekecektir. Geliştirme sırasında, uygulamanız için uygulama bilgileri -> izinler sayfasına da gidebilir ve izinleri el ile etkinleştirebilirsiniz (açıklamanızın içinde olduğunu varsayarak).

Bu son adımı alana kadar seg hatam vardı ve artık artık gerçekleşmiyor.

Umarım bu, benim gibi kafamın karışmasına yardımcı olur.