Альтернатива для ifstream (c ++) при попытке прочитать WAV-файл в Android

Я пытаюсь вычислить коэффициенты MFCC из файлов WAV, хранящихся на SD-карте. Я использую библиотеку: https://github.com/dspavankumar/compute-mfcc

Входными данными является путь к файлу wav с использованием ifstream. Мне нужно иметь доступ к различным файлам PCM, разделенным из одного файла WAV в соответствии с временными сегментами и вычислить MFCC для каждого сегмента. У меня возникли проблемы с поиском способа получить эти данные (необработанные данные PCM) в буфер, показанный в методе ниже, из класса Java. (Используя JNI)

int process (std::ifstream &wavFp, std::ofstream &mfcFp) {
// Read the wav header
wavHeader hdr;
int headerSize = sizeof(wavHeader);

wavFp.read((char *) &hdr, headerSize);

// Check audio format
if (hdr.AudioFormat != 1 || hdr.bitsPerSample != 16) {
std::cerr << "Unsupported audio format, use 16 bit PCM Wave" <<
std::endl;
return 1;
}
// Check sampling rate
if (hdr.SamplesPerSec != fs) {
std::cerr << "Sampling rate mismatch: Found " << hdr.SamplesPerSec << " instead of " << fs <<std::endl;
return 1;
}

// Initialise buffer
uint16_t bufferLength = winLengthSamples-frameShiftSamples;
int16_t* buffer = new int16_t[bufferLength];
int bufferBPS = (sizeof buffer[0]);

// Read and set the initial samples
wavFp.read((char *) buffer, bufferLength*bufferBPS);
for (int i=0; i<bufferLength; i++)
prevsamples[i] = buffer[i];
delete [] buffer;

// Recalculate buffer size
bufferLength = frameShiftSamples;
buffer = new int16_t[bufferLength];

// Read data and process each frame
wavFp.read((char *) buffer, bufferLength*bufferBPS);
while (wavFp.gcount() == bufferLength*bufferBPS && !wavFp.eof()) {
mfcFp << processFrame(buffer, bufferLength);
wavFp.read((char *) buffer, bufferLength*bufferBPS);
}
delete [] buffer;
buffer = nullptr;
return 0;
}

`

Кажется, я не могу получить доступ к файлу WAV на SD-карте непосредственно из библиотеки C ++. Поэтому я попытался передать jbytearray и преобразовать его в char *, используя:

extern "C"JNIEXPORT void JNICALL
Java_com_example_nikhar_mst04v10_RecordActivity_doMFCC(JNIEnv *env, jobject
instance,
jbyteArray wavBytes_) {
int len = env ->GetArrayLength(wavBytes_);
char* buf = new char[len];
env->GetByteArrayRegion(wavBytes_,0,len, reinterpret_cast<jbyte *>(buf));

// TODO

/* env->ReleaseStringUTFChars(wavPath_, wavPath);
env->ReleaseStringUTFChars(mfccPath_, mfccPath);*/
// Assign variables
int numCepstra =  12;
int numFilters =  40;
int samplingRate = 16000;
int winLength = 25;
int frameShift = 10;
int lowFreq = 50;
int highFreq = samplingRate/2;

// Initialise MFCC class instance
MFCC mfccComputer (samplingRate, numCepstra, winLength, frameShift,
numFilters, lowFreq, highFreq);
mfccComputer.process(buf);
}

но это было неудачно. Любые предложения о том, как я могу выполнить это?

-1

Решение

Посмотрите здесь:

http://jnicookbook.owsiak.org/recipe-No-012/

познакомиться с передачей массивов между Java и C.

Что касается jbyte — этот тип зависит от машины. Как правило, это будет «подписанный символ». Я предлагаю передать ваши данные в C, а затем привести массив к char *. Он должен работать.

Но! Удостоверьтесь, что дважды проверьте, как объявлен jbyte в вашей целевой системе. Вы можете найти его здесь: $ YOUR_PLATFORM_NAME / jni_md.h

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]