簡體   English   中英

嘗試在Android中讀取.wav文件時使用ifstream(C ++)的替代方法

[英]Alternative for ifstream (c++) whilst trying to read a .wav file in android

我正在嘗試從存儲在SD卡上的wav文件計算MFCC系數。 我正在使用該庫: https : //github.com/dspavankumar/compute-mfcc

輸入是使用ifstream的wav文件路徑。 我需要能夠根據時間段訪問從單個wav文件分割的不同pcm文件,並為每個段計算MFCC。 我在尋找一種方法來從java類將數據(原始pcm數據)獲取到下面方法所示的緩沖區中時遇到麻煩。 (使用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;
}

`

看來我無法直接從c ++庫訪問sd卡上的wav文件。 所以我嘗試傳遞一個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);
}

但這是不成功的。 任何建議,我如何才能做到這一點?

在這里看看:

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

熟悉在Java和C之間傳遞數組。

至於jbyte-這種類型取決於機器。 通常,它將是“ signed char”。 我建議將您的數據傳遞給C,然后將數組轉換為char *。 它應該工作。

但! 確保仔細檢查目標系統中如何聲明jbyte。 您可以在這里找到它:$ YOUR_PLATFORM_NAME / jni_md.h

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM