Android native video + audio

Started by
3 comments, last by polyfrag 11 years ago

How?

I've got ffmpeg for android. Should I just follow tutorials for linux?

The audio is in .wav files.

Advertisement

Why can't I play a sound more than once? What am I doing wrong?


 SLresult result = (*fdPlayerSeek)->SetPosition(fdPlayerSeek, 0, SL_SEEKMODE_FAST);
  if(result != SL_RESULT_SUCCESS) 
  { 
    LOGE("SetPosition(0) error %s", file); 
  }

  result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, SL_PLAYSTATE_PLAYING);

  if(result != SL_RESULT_SUCCESS) 
  { 
    LOGE("SetPlayState(SL_PLAYSTATE_PLAYING) error %s", file); 
  }

[edit] Oh, needed to make sure it's stopped before seeking.

I just got the 'Too many objects' error from OpenSL ES.

04-06 12:18:38.887: E/libOpenSLES(8466): Too many objects

04-06 12:18:38.887: W/libOpenSLES(8466): Leaving Engine::CreateAudioPlayer (SL_RESULT_MEMORY_FAILURE)
04-06 12:18:38.887: A/libc(8466): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 8493 (engame.pathogen)

Is there really such a low limit on sounds? How do I overcome this? I have ~30 sound effects.

I use buffer queue now. I load the wav file manually.

But I hear high-pitched noise when I play the file. What am I doing wrong?


void CSound::channelplay(CChannel* c) 
{ 
  c->Destroy();
  // PCM data source format 
  SLDataFormat_PCM dataSourceFormat = { 
  SL_DATAFORMAT_PCM, // format type 
  channels, // channel count 
  rate, // samples per second in millihertz 
  bits, // bits per sample 
  bits, // container size 
  SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, 
  //SL_SPEAKER_FRONT_CENTER, // channel mask 
  SL_BYTEORDER_LITTLEENDIAN // endianness 
  };

  // Android simple buffer queue locator for the data source 
  SLDataLocator_AndroidSimpleBufferQueue dataSourceLocator = { 
  SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locator type 
  1 // buffer count 
  };

  // Data source is a simple buffer queue with PCM format 
  SLDataSource dataSource = { 
  &dataSourceLocator, // data locator 
  &dataSourceFormat // data format 
  }; 
  // Output mix locator for data sink 
  SLDataLocator_OutputMix dataSinkLocator = { 
  SL_DATALOCATOR_OUTPUTMIX, // locator type 
  outputMixObject // output mix 
  }; 
  // Data sink is an output mix 
  SLDataSink dataSink = { 
  &dataSinkLocator, // locator 
  0 // format 
  }; 
  // Interfaces that are requested 
  SLInterfaceID interfaceIds[] = { 
  SL_IID_BUFFERQUEUE 
  }; 
  // Required interfaces. If the required interfaces 
  // are not available the request will fail 
  SLboolean requiredInterfaces[] = { 
  SL_BOOLEAN_TRUE, // for SL IID BUFFERQUEUE 
  };

  // Create audio player object 
  SLresult result = (*engineEngine)->CreateAudioPlayer( 
  engineEngine, 
  &(c->bqPlayerObject), 
  &dataSource, 
  &dataSink, 
  ARRAY_LEN(interfaceIds), 
  interfaceIds, 
  requiredInterfaces);

  result = (*(c->bqPlayerObject))->Realize(c->bqPlayerObject, SL_BOOLEAN_FALSE);

  LOGI("SL_IID_PLAY"); 
  result = (*(c->bqPlayerObject))->GetInterface(c->bqPlayerObject, 
                                SL_IID_PLAY, &(c->bqPlayerPlay));

  LOGI("SL_IID_BUFFERQUEUE"); 
  result = (*(c->bqPlayerObject))->GetInterface(c->bqPlayerObject, SL_IID_BUFFERQUEUE, &(c->bqBufferQueue));

  //result = (*(c->bqPlayerObject))->GetInterface(c->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(c->bqBufferQueue));

  LOGI("RegCall"); 
  //result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p); 
    result = (*(c->bqBufferQueue))->RegisterCallback(c->bqBufferQueue, bqPlayerCallback, c);

  c->sound = this; 
  c->nextBuffer = data; 
  c->nextSize = min(datalen, SBC_AUDIO_OUT_BUFFER_SIZE); 
  c->position = 0;

  LOGI("setplaystate"); 
  result = (*(c->bqPlayerPlay))->SetPlayState(c->bqPlayerPlay, SL_PLAYSTATE_PLAYING);

  LOGI("enqueue"); 
  result = (*(c->bqBufferQueue))->Enqueue(c->bqBufferQueue, c->nextBuffer, c->nextSize); 
}

static int wav_parse_header(WAV handle, WAVError *err) 
{ 
    uint8_t hdr[WAV_HEADER_LEN]; 
    ssize_t r = 0; 
    uint16_t wav_fmt = 0; 
    uint32_t fmt_len = 0;
    //if (!handle || handle->fd == -1 || !(handle->mode & WAV_READ)) { 
    if (!handle || handle->file.mFile == 0 || !(handle->mode & WAV_READ)) { 
        return -1; 
    }

    //r = plat_read(handle->fd, hdr, WAV_HEADER_LEN); 
    r = plat_read(&handle->file, hdr, WAV_HEADER_LEN); 
    if (r != WAV_HEADER_LEN) { 
        WAV_SET_ERROR(err, WAV_BAD_FORMAT); 
        goto bad_wav; 
    } 
    if ((wav_get_bits32(hdr) != make_tag('R', 'I', 'F', 'F')) 
    || (wav_get_bits32(hdr + 8) != make_tag('W', 'A', 'V', 'E')) 
    || (wav_get_bits32(hdr + 12) != make_tag('f', 'm', 't', ' '))) { 
        WAV_SET_ERROR(err, WAV_BAD_FORMAT); 
        goto bad_wav; 
    }

    fmt_len = wav_get_bits32(hdr + 16); 
    wav_fmt = wav_get_bits16(hdr + 20); 
    if (fmt_len != WAV_FORMAT_LEN || wav_fmt != PCM_ID) { 
        WAV_SET_ERROR(err, WAV_UNSUPPORTED); 
        goto bad_wav; 
    }

    handle->len = wav_get_bits32(hdr + 4); 
    handle->channels = wav_get_bits16(hdr + 22); 
    handle->rate = wav_get_bits32(hdr + 24); 
    handle->bitrate = (wav_get_bits32(hdr + 28) * 8) / 1000; 
    handle->block_align = wav_get_bits16(hdr + 32); 
    handle->bits = wav_get_bits16(hdr + 34); 
    /* skip 'data' tag (4 bytes) */ 
    handle->len = wav_get_bits32(hdr + 40);

    return 0;

bad_wav: 
    //lseek(handle->fd, 0, SEEK_SET); 
  handle->file.seek(0, SEEK_SET);

    return 1; 
}
Sound works now. Except I think there's a problem with 1536+ kbps. Code is here if anyone needs it.

https://github.com/polyf/pathogenandroid/tree/master/jni/pathogen

Now for the video...

This topic is closed to new replies.

Advertisement