static int decoded (FishSound * fsound, float ** pcm, long frames, void * user_data) { FS_DecEnc * ed = (FS_DecEnc *) user_data; FishSoundInfo fsinfo; int i; if (!ed->begun) { fish_sound_command (fsound, FISH_SOUND_GET_INFO, &fsinfo, sizeof (FishSoundInfo)); fsinfo.format = ed->format; ed->encoder = fish_sound_new (FISH_SOUND_ENCODE, &fsinfo); fish_sound_set_interleave (ed->encoder, ed->interleave); fish_sound_set_encoded_callback (ed->encoder, encoded, ed); ed->channels = fsinfo.channels; if (ed->interleave) { ed->pcm = (float **) malloc (sizeof (float) * ed->channels * ed->blocksize); } else { ed->pcm = (float **) malloc (sizeof (float *) * ed->channels); for (i = 0; i < ed->channels; i++) { ed->pcm[i] = (float *) malloc (sizeof (float) * ed->blocksize); } } ed->begun = 1; } fish_sound_encode (ed->encoder, pcm, frames); return 0; }
int acceptFrames(float **frames, long n) { if (m_rs->getChannelCount() == 0) { FishSoundInfo fsinfo; fish_sound_command(m_fishSound, FISH_SOUND_GET_INFO, &fsinfo, sizeof(FishSoundInfo)); m_rs->m_channelCount = fsinfo.channels; m_rs->m_sampleRate = fsinfo.samplerate; } sizeBuffer(getAvailableFrameCount() + n); int channels = m_rs->getChannelCount(); #ifdef __GNUC__ float interleaved[n * channels]; #else float *interleaved = (float *)alloca(n * channels * sizeof(float)); #endif for (long i = 0; i < n; ++i) { for (int c = 0; c < channels; ++c) { interleaved[i * channels + c] = frames[c][i]; } } m_buffer->write(interleaved, n * channels); return 0; }
int decoded_float (FishSound * fsound, float ** pcm, long frames, void * user_data) { struct roarfish_play_inst * inst = (struct roarfish_play_inst*) user_data; int16_t * data; int i; double s; if (!inst->begun) { fish_sound_command (fsound, FISH_SOUND_GET_INFO, &(inst->fsinfo), sizeof (FishSoundInfo)); if ( (inst->roarfh = roar_simple_play(inst->fsinfo.samplerate, inst->fsinfo.channels, 16, ROAR_CODEC_NATIVE, NULL, "roarfish")) == -1 ) { return -1; } inst->begun = 1; } if ( (data = malloc(frames*2*inst->fsinfo.channels)) == NULL ) { return -1; } frames *= inst->fsinfo.channels; for (i = 0; i < frames; i++) { s = ((float*)pcm)[i]; s *= 32767; data[i] = s; } write(inst->roarfh, (char*)data, frames * 2); free(data); return 0; }
static int fishsound_decoded_callback (FishSound *ap_fsound, float *app_pcm[], long frames, void *ap_user_data) { int rc = FISH_SOUND_CONTINUE; vorbisd_prc_t *p_prc = ap_user_data; OMX_BUFFERHEADERTYPE *p_out = NULL; (void)ap_fsound; assert (NULL != app_pcm); assert (NULL != ap_user_data); TIZ_TRACE (handleOf (p_prc), "frames [%d] ", frames); /* Possible return values are: */ /* FISH_SOUND_CONTINUE Continue decoding */ /* FISH_SOUND_STOP_OK Stop decoding immediately and return control to the fish_sound_decode() caller */ /* FISH_SOUND_STOP_ERR Stop decoding immediately, purge buffered data, and return control to the fish_sound_decode() caller */ if (!p_prc->started_) { p_prc->started_ = true; fish_sound_command (p_prc->p_fsnd_, FISH_SOUND_GET_INFO, &(p_prc->fsinfo_), sizeof(FishSoundInfo)); if (p_prc->fsinfo_.channels > 2 || p_prc->fsinfo_.format != FISH_SOUND_VORBIS) { TIZ_ERROR (handleOf (p_prc), "Supported Vorbis " "streams up tp 2 channels only."); rc = FISH_SOUND_STOP_ERR; goto end; } TIZ_NOTICE (handleOf (p_prc), "Channels [%d] sampling rate [%d]", p_prc->fsinfo_.channels, p_prc->fsinfo_.samplerate); } p_out = tiz_filter_prc_get_header (p_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX); if (NULL == p_out) { TIZ_TRACE (handleOf (p_prc), "No more output buffers " "available at the moment"); rc = FISH_SOUND_STOP_OK; goto end; } { /* write decoded PCM samples */ size_t i = 0; size_t frame_len = sizeof(float) * p_prc->fsinfo_.channels; size_t frames_alloc = ((p_out->nAllocLen - p_out->nOffset) / frame_len); size_t frames_to_write = (frames > frames_alloc) ? frames_alloc : frames; size_t bytes_to_write = frames_to_write * frame_len; assert (NULL != p_out); for (i = 0; i < frames_to_write; ++i) { size_t frame_offset = i * frame_len; size_t float_offset = i * p_prc->fsinfo_.channels; float *out = (float *)(p_out->pBuffer + p_out->nOffset + frame_offset); write_frame_float_ilv (out, ((float *)app_pcm) + float_offset, p_prc->fsinfo_.channels); } p_out->nFilledLen += bytes_to_write; p_out->nOffset += bytes_to_write; if (frames_to_write < frames) { /* Temporarily store the data until an omx buffer is * available */ OMX_U32 nbytes_remaining = (frames - frames_to_write) * frame_len; TIZ_TRACE (handleOf (p_prc), "Need to store [%d] bytes", nbytes_remaining); nbytes_remaining = store_data ( p_prc, (OMX_U8 *)(app_pcm[frames_to_write * sizeof(float)]), nbytes_remaining); } if (tiz_filter_prc_is_eos (p_prc)) { /* Propagate EOS flag to output */ p_out->nFlags |= OMX_BUFFERFLAG_EOS; tiz_filter_prc_update_eos_flag (p_prc, false); TIZ_TRACE (handleOf (p_prc), "Propagating EOS flag to output"); } /* TODO: Shouldn't ignore this rc */ (void)tiz_filter_prc_release_header (p_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX); /* Let's process one input buffer at a time, for now */ rc = FISH_SOUND_STOP_OK; } end: return rc; }