2

我正在尝试使用 Superpowered SDK 创建 android 应用程序,这将允许我将麦克风输入重定向到耳机,并为麦克风添加混响效果,以模拟巨大的房间效果。我找到了这个带有代码片段的存储库:https ://bitbucket.org/snippets/kasurd/Mynnp/nativesuperpoweredrecorder-with ,但我无法让它工作。这是我当前的代码:

#include <jni.h>
#include <stdio.h>
#include "SuperpoweredExample.h"
#include <SuperpoweredSimple.h>
#include <SuperpoweredCPU.h>
#include <pthread.h>
#include <malloc.h>

static void playerEventCallback(void *clientData, SuperpoweredAdvancedAudioPlayerEvent event, void * __unused value) {
    if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadSuccess) {
        SuperpoweredAdvancedAudioPlayer *player = *((SuperpoweredAdvancedAudioPlayer **)clientData);
        //player->setBpm(126.0f);
        //player->setFirstBeatMs(353);
        player->setPosition(player->firstBeatMs, false, false);
    }else if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadError) {
    } else if (event == SuperpoweredAdvancedAudioPlayerEvent_EOF) {
    };
}

static bool audioProcessingPlayback(void *clientdata, short int *audioIO, int numberOfSamples, int samplerate) {
    return ((SuperpoweredPlayer *)clientdata)->processPlayback(0, audioIO, numberOfSamples);
}

static bool audioProcessingRecording(void *clientdata, short int *audioIO, int numberOfSamples, int samplerate) {
    return ((SuperpoweredPlayer *)clientdata)->processRecording(audioIO, numberOfSamples);
}

bool SuperpoweredPlayer::process(short int *output, unsigned int numberOfSamples) {
    bool processResult =  player->process(stereoBuffer, false, numberOfSamples);
    SuperpoweredFloatToShortInt(stereoBuffer, output, numberOfSamples);
    return processResult;
}

static bool audioProcessing(void *clientdata, short int *audioIO, int numberOfSamples, int __unused samplerate) {
    return ((SuperpoweredPlayer *)clientdata)->process(audioIO, (unsigned int)numberOfSamples);
}

SuperpoweredPlayer::SuperpoweredPlayer(unsigned int sampleRate, unsigned int bufferSize, const char *path, int fileOffset, int fileLength) {

    stereoBuffer = (float *)memalign(16, (bufferSize + 16) * sizeof(float) * 2);
    stereoBufferRecording = (float *)memalign(16, (bufferSize + 16) * sizeof(float) * 2);

    this->sampleRate = sampleRate;
    this->bufferSize = bufferSize;

    playerA = NULL;
    recorder = NULL;
    audioSystemRecording = new SuperpoweredAndroidAudioIO(sampleRate, bufferSize, true, false, audioProcessingRecording, this, bufferSize * 2);

    initPlayerA(path, fileOffset, fileLength, 0);
}

void SuperpoweredPlayer::initPlayerA(const char *path, int fileOffset, int fileSize, double startOffsetMs) {
    audioSystemA = new SuperpoweredAndroidAudioIO(sampleRate, bufferSize, false, true, audioProcessingPlayback, this, bufferSize * 2);
    playerA = new SuperpoweredAdvancedAudioPlayer(&playerA , playerEventCallback, sampleRate, 0);
    playerA->open(path, fileOffset, fileSize);
    playerA->syncMode = SuperpoweredAdvancedAudioPlayerSyncMode_TempoAndBeat;
}

void SuperpoweredPlayer::playPause(bool play) {
    if (!play) {
        askPlaying = false;
        if (playerA != NULL) {
            playerA->pause();
        }
    } else {
        if (playerA != NULL) {
            playerA->play(false);
        }
        askPlaying = true;
    };
    SuperpoweredCPU::setSustainedPerformanceMode(play);
}

void SuperpoweredPlayer::startRecording(const char *tempPath, const char *destinationPath) {
    recorder = new SuperpoweredRecorder(tempPath, sampleRate);
    askRecording = true;
    recorder->start(destinationPath);
    playPause(true);
}

void SuperpoweredPlayer::stopRecording() {
    if (!askRecording) {
        return;
    }
    askPlaying = false;
    askRecording = false;
    recorder->stop();
    playPause(false);
}

// method to receive playback parts
bool SuperpoweredPlayer::processPlayback(int playerId, short int *output, unsigned int numberOfSamples) {
    pthread_mutex_lock(&mutex);
    if (!askPlaying) {
        pthread_mutex_unlock(&mutex);
        return false;
    }
    playerA->process(stereoBuffer, false, numberOfSamples, 1.0f, 0.0f, -1.0f);

    SuperpoweredFloatToShortInt(stereoBuffer, output, numberOfSamples);

    pthread_mutex_unlock(&mutex);
    return true;
}

// method to receive recording parts
bool SuperpoweredPlayer::processRecording(short int *input, unsigned int numberOfSamples) {
    pthread_mutex_lock(&mutex);
    if (askRecording) {
        unsigned int data = 0;
        SuperpoweredShortIntToFloat(input, stereoBufferRecording, numberOfSamples);
        data = recorder->process(stereoBufferRecording, NULL, numberOfSamples);
        pthread_mutex_unlock(&mutex);
        return true;
    }
    pthread_mutex_unlock(&mutex);
    return false;
}

//void SuperpoweredPlayer::setTempo(double value) {
//    player->setTempo(value, true);
//}

SuperpoweredPlayer::~SuperpoweredPlayer() {
    delete playerA;
    free(stereoBuffer);
    pthread_mutex_destroy(&mutex);
}

static SuperpoweredPlayer *player = NULL;
static const char *path;

extern "C" JNIEXPORT void Java_com_example_pc_superpoweredsdk_SuperPoweredPlayerWrapper_SuperpoweredPlayer(JNIEnv *javaEnvironment, jobject __unused obj, jint sampleRate, jint bufferSize, jstring apkPath, jint fileOffset, jint fileLength) {
    path = javaEnvironment->GetStringUTFChars(apkPath, JNI_FALSE);
    player = new SuperpoweredPlayer((unsigned int)sampleRate, ((unsigned int)bufferSize), path + 'temp.wav', fileOffset, fileLength);
    javaEnvironment->ReleaseStringUTFChars(apkPath, path);
}

extern "C" JNIEXPORT void Java_com_example_pc_superpoweredsdk_SuperPoweredPlayerWrapper_playPause(JNIEnv * __unused javaEnvironment, jobject __unused obj, jboolean play) {
    player->startRecording(path + 'temp.wav', path + 'dest.wav');
}

sampleRate 是 44100,bufferSize 是 512,路径是 context.getFilesDir().getAbsolutePath()

我现在被困住了,试图弄清楚,我应该如何播放带有混响滤波器的麦克风输入,并以尽可能少的延迟实时播放耳机。

4

1 回答 1

2

附加的代码在这里并不重要,因为它主要处理玩家。我建议从头开始编写自己的代码。使用 SuperpoweredAndroidAudioIO 进行音频输入/输出,并使用 SuperpoweredRecorder 处理传入的音频。总共不会超过几行。

于 2017-07-06T07:11:32.143 回答