1

I'm trying to implement a loop feature. Basically I save the music sample in a buffer. Then when I press the loop in button I set the initial loop in time, when press the loop out set the loop out time. To get the loop part i make loop out time - loop in time, that gives me the seconds of loop. Then I multiply the seconds * sample rate (44100), allocate a new buffer with that size and fill it with sound data. Everything works good but when I listen to the loop buffer via Open SL ES the sound is slower than the original one. I really don't know why...

SLmillisecond loopInPosition, loopOutPosition;
float loopDuration;
const char *lastPath;
short *sampleBuffer, *loopBuffer;
int xSampleBufferSize, xLoopBuffersize;

void playBuffer();

// get the position in the music sample when loop in or out button is pressed
SLmillisecond getCurrentPosition(jint playerIndex, SLmillisecond* whereToSave) {

    Player player = players[playerIndex];
    if (player.isReady == 1) {
        (*(player.playerPlayItf))->GetPosition(player.playerPlayItf,
                whereToSave);

        __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
                ">>NATIVE position is: %d", *whereToSave);
    }
}

void loopIn(JNIEnv* env,
        jclass clazz, jint selectedSlot, jstring filename) {

    lastPath = (*env)->GetStringUTFChars(env, filename, NULL);
    assert(NULL != path);

    getCurrentPosition(selectedSlot, &loopInPosition);
}

void loopOut(JNIEnv* env,
        jclass clazz, jint selectedSlot) {

    getCurrentPosition(selectedSlot, &loopOutPosition);

    loopDuration = (float) ((float) (loopOutPosition - loopInPosition) / 1000);

    __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
            ">>NATIVE loop duration is: %f", loopDuration);

    SF_INFO sndInfo;
    SNDFILE *sndFile = sf_open(lastPath, SFM_READ, &sndInfo);

    if (sndInfo.format != (SF_FORMAT_WAV | SF_FORMAT_PCM_16)) {
        fprintf(stderr, "Input should be 16bit Wav\n");
        sf_close(sndFile);
    } else {

        __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
                ">>NATIVE File info samplerate %d, channels %d, format %d, sections %d, seekable %d",
                sndInfo.samplerate, sndInfo.channels, sndInfo.format,
                sndInfo.sections, sndInfo.seekable);
    }

    // Sample Buffer
    int sampleBufferSize = sndInfo.frames * sizeof(short);
    xSampleBufferSize = sampleBufferSize;
    sampleBuffer = malloc(sampleBufferSize);


    __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
            ">>NATIVE allocated sample buffer: size %d, frames %d",
            sampleBufferSize, sndInfo.frames);

    sf_readf_short(sndFile, sampleBuffer, sndInfo.frames);

    // Loop Buffer
    int loopBufferSize = loopDuration * 44100 * sizeof(short);
    int loopBufferFrames = loopDuration * 44100;
    xLoopBuffersize = loopBufferSize;
    loopBuffer = malloc(loopBufferSize);

    __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
            ">>NATIVE allocated loop buffer: size %d, frames %d",
            loopBufferSize, loopBufferFrames);

    int index, i = 0;
    int startIndex = (int) ((float) (loopInPosition / 1000) * 44100);

    __android_log_print(ANDROID_LOG_DEBUG, "jajaja",
            ">>NATIVE start index is %d", startIndex);

    for (index = startIndex, i = 0; index < startIndex + loopBufferFrames;
            ++index, ++i) {

        loopBuffer[i] = sampleBuffer[index];
    }
}

thanks for your time

Stefano Vuerich
  • 996
  • 1
  • 7
  • 28
  • 1
    Sounds like a sample rate mismatch. How much slower is it? – dtech Aug 15 '15 at 12:43
  • Is it stereo audio? Also, do you hear the whole loop or just some of it (say, half)? – Tomer Aug 15 '15 at 13:21
  • Is the frequency also lower? – dtech Aug 15 '15 at 13:41
  • I hear all the loop and the frequancy seems to be the same, but I really didn't check it. I'm tying to work on it right now and I don0t know why if I change the lasts rows to loopBuffer[i] = sampleBuffer[index * 2]...it works quite good...can you explain me that? – Stefano Vuerich Aug 15 '15 at 14:37
  • If you know what to change to make it sound right, why are you asking on this forum? – Weather Vane Aug 15 '15 at 21:16
  • I just want to know more about the logic behind the scenes, Tomer gave me a good interpretation on this issue, and so I definitely improve my knowledge – Stefano Vuerich Aug 16 '15 at 18:50

1 Answers1

2

What seems to be happening is that you're dealing with an interleaved stereo data. This means that both channels are stored as one contiguous block: a sample for the first channel, a sample for the second channel, a sample for the first channel again and so on.

But, your buffer is played as mono, so when it's being played it thinks every sample intended for the second channel is intended for the first (and only) channel. This creates duplicate samples, making it sound slower.

When you're doing loopBuffer[i] = sampleBuffer[index * 2], you're actually skipping every sample intended for the first channel, copying only the samples intended for the second channel.

You may want to configure your audio player to interpret your buffer as interleaved stereo data.

Tomer
  • 3,149
  • 23
  • 26