int main(void) { int i, sic, eic; U16BIT I; reset_encoder(); reset_decoder(); sic = __time / 2; for (i = 0; i < sizeof(Input) / sizeof(U16BIT); i++) decoder(encoder(Input[i])); eic = __time / 2; printf("\nInstruction cycles for transcoding a sample: %d\n", (eic - sic) / (sizeof(Input) / sizeof(U16BIT))); return (0); }
FXbool VorbisDecoder::find_stream_position() { const FXuchar * data_ptr = get_packet_offset(); FXint cb,lb=-1,tb=0; while(get_next_packet()) { if (is_vorbis_header()){ reset_decoder(); goto reset; } cb=vorbis_packet_blocksize(&info,&op); if (lb!=-1) tb+=(lb+cb)>>2; lb=cb; if (op.granulepos!=-1) { stream_position=op.granulepos-tb; set_packet_offset(data_ptr); return true; } } reset: set_packet_offset(data_ptr); return false; }
DecoderStatus VorbisDecoder::process(Packet * packet) { FXASSERT(packet); #ifdef HAVE_VORBIS_PLUGIN FXfloat ** pcm=NULL; FXfloat * buf32=NULL; #else // HAVE_TREMOR_PLUGIN FXint ** pcm=NULL; FXshort * buf32=NULL; #endif FXint p,navail=0; FXint ngiven,ntotalsamples,nsamples,sample,c,s; FXbool eos=packet->flags&FLAG_EOS; FXuint id=packet->stream; FXlong len=packet->stream_length; OggDecoder::process(packet); /// Init Decoder if (!has_dsp) { if (!init_decoder()) return DecoderError; if (!has_dsp) return DecoderOk; } /// Find Stream Position if (stream_position==-1 && !find_stream_position()) return DecoderOk; if (out) { navail = out->availableFrames(); } while(get_next_packet()) { if (__unlikely(is_vorbis_header())) { GM_DEBUG_PRINT("[vorbis] unexpected vorbis header found. Resetting decoder\n"); push_back_packet(); reset_decoder(); return DecoderOk; } if (vorbis_synthesis(&block,&op)==0) vorbis_synthesis_blockin(&dsp,&block); while((ngiven=vorbis_synthesis_pcmout(&dsp,&pcm))>0) { if (len>0) FXASSERT(stream_position+ngiven<=len); if (__unlikely(stream_position<stream_decode_offset)) { FXlong offset = FXMIN(ngiven,stream_decode_offset - stream_position); GM_DEBUG_PRINT("[vorbis] stream decode offset %ld. Skipping %ld of %ld \n",stream_decode_offset,offset,stream_decode_offset-stream_position); ngiven-=offset; stream_position+=offset; sample=offset; vorbis_synthesis_read(&dsp,offset); if (ngiven==0) continue; } else { sample=0; } for (ntotalsamples=ngiven;ntotalsamples>0;) { /// Get new buffer if (out==NULL) { out = engine->decoder->get_output_packet(); if (out==NULL) return DecoderInterrupted; out->stream_position=stream_position; out->stream_length=len; out->af=af; navail = out->availableFrames(); } #ifdef HAVE_VORBIS_PLUGIN buf32 = out->flt(); #else // HAVE_TREMOR_PLUGIN buf32 = out->s16(); #endif /// Copy Samples nsamples = FXMIN(ntotalsamples,navail); for (p=0,s=sample;s<(nsamples+sample);s++){ for (c=0;c<info.channels;c++,p++) { #ifdef HAVE_VORBIS_PLUGIN buf32[p]=pcm[c][s]; #else buf32[p]=CLIP_TO_15(pcm[c][s]>>9); #endif } } /// Update sample counts out->wroteFrames(nsamples); sample+=nsamples; navail-=nsamples; ntotalsamples-=nsamples; stream_position+=nsamples; /// Send out packet if full ///FIXME handle EOS. if (navail==0) { engine->output->post(out); out=NULL; } } vorbis_synthesis_read(&dsp,ngiven); } } if (eos) { if (out && out->numFrames()) { engine->output->post(out); out=NULL; } engine->output->post(new ControlEvent(End,id)); } return DecoderOk; }
int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds) { unsigned char data[256] = {}; int res; uint64_t deadline; if(milliseconds < 0) { deadline = (uint64_t)(-1); } else { deadline = mono_timer_nanos() + (milliseconds * 1000000); } uint64_t nanos = mono_timer_nanos(); if (nanos == 0 || deadline == 0) { TM_FATAL("touchmouse_process_events_timeout: timer function returned an error, erroring out since we have no timer\n"); return -1; } do { res = hid_read_timeout(dev->dev, data, 255, (deadline - nanos) / 1000000 ); if (res < 0 ) { TM_ERROR("hid_read() failed: %d - %ls\n", res, hid_error(dev->dev)); return -2; } else if (res > 0) { // Dump contents of transfer TM_SPEW("touchmouse_process_events_timeout: got report: %d bytes:", res); int j; for(j = 0; j < res; j++) { TM_SPEW(" %02X", data[j]); } TM_SPEW("\n"); // Interpret contents. report* r = (report*)data; // We only care about report ID 39 (0x27), which should be 32 bytes long if (res == 32 && r->report_id == 0x27) { TM_FLOOD("Timestamp: %02X\t%02X bytes:", r->timestamp, r->length - 1); int t; for(t = 0; t < r->length - 1; t++) { TM_FLOOD(" %02X", r->data[t]); } TM_FLOOD("\n"); // Reset the decoder if we've seen one timestamp already from earlier // transfers, and this one doesn't match. if (dev->buf_index != 0 && r->timestamp != dev->timestamp_in_progress) { TM_FLOOD("touchmouse_process_events_timeout: timestamps don't match: got %d, expected %d\n", r->timestamp, dev->timestamp_in_progress); reset_decoder(dev); // Reset decoder for next transfer } dev->timestamp_in_progress = r->timestamp; for(t = 0; t < r->length - 1; t++) { // We subtract one byte because the length includes the timestamp byte. int res; // Yes, we process the low nybble first. Embedded systems are funny like that. res = process_nybble(dev, r->data[t] & 0xf); if (res == DECODER_COMPLETE) { TM_SPEW("Frame completed, triggering callback\n"); dev->timestamp_last_completed = r->timestamp; touchmouse_callback_info cbinfo; cbinfo.userdata = dev->userdata; cbinfo.image = dev->image; cbinfo.timestamp = dev->timestamp_last_completed; dev->cb(&cbinfo); reset_decoder(dev); // Reset decoder for next transfer return 0; } if (res == DECODER_ERROR) { TM_ERROR("Caught error in decoder, aborting decode!\n"); reset_decoder(dev); return -1; } res = process_nybble(dev, (r->data[t] & 0xf0) >> 4); if (res == DECODER_COMPLETE) { TM_SPEW("Frame completed, triggering callback\n"); dev->timestamp_last_completed = r->timestamp; touchmouse_callback_info cbinfo; cbinfo.userdata = dev->userdata; cbinfo.image = dev->image; cbinfo.timestamp = dev->timestamp_last_completed; dev->cb(&cbinfo); reset_decoder(dev); // Reset decoder for next transfer return 0; } if (res == DECODER_ERROR) { TM_ERROR("Caught error in decoder, aborting decode!\n"); reset_decoder(dev); return -1; } } } }