void _verify(OggVorbis_File *ov,ogg_int64_t pos, ogg_int64_t val,ogg_int64_t pcmval, ogg_int64_t pcmlength, char *bigassbuffer){ int j; long bread; char buffer[4096]; int dummy; /* verify the raw position, the pcm position and position decode */ if(val!=-1 && ov_raw_tell(ov)<val){ printf("raw position out of tolerance: requested %ld, got %ld\n", (long)val,(long)ov_raw_tell(ov)); exit(1); } if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){ printf("pcm position out of tolerance: requested %ld, got %ld\n", (long)pcmval,(long)ov_pcm_tell(ov)); exit(1); } pos=ov_pcm_tell(ov); if(pos<0 || pos>pcmlength){ printf("pcm position out of bounds: got %ld\n",(long)pos); exit(1); } bread=ov_read(ov,buffer,4096,1,1,1,&dummy); for(j=0;j<bread;j++){ if(buffer[j]!=bigassbuffer[j+pos*2]){ printf("data position after seek doesn't match pcm position\n"); exit(1); } } }
void _verify(OggVorbis_File *ov, ogg_int64_t val,ogg_int64_t pcmval,double timeval, ogg_int64_t pcmlength, char *bigassbuffer){ off_t i; int j; long bread; char buffer[4096]; int dummy; ogg_int64_t pos; int hs = ov_halfrate_p(ov); /* verify the raw position, the pcm position and position decode */ if(val!=-1 && ov_raw_tell(ov)<val){ fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n", (long)val,(long)ov_raw_tell(ov)); exit(1); } if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){ fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n", (long)pcmval,(long)ov_pcm_tell(ov)); exit(1); } if(timeval!=-1 && ov_time_tell(ov)>timeval){ fprintf(stderr,"time position out of tolerance: requested %f, got %f\n", timeval,ov_time_tell(ov)); exit(1); } pos=ov_pcm_tell(ov); if(pos<0 || pos>pcmlength){ fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos); exit(1); } bread=ov_read(ov,buffer,4096,1,1,1,&dummy); for(j=0;j<bread;j++){ if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){ fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos); for(i=0;i<(pcmlength>>hs)*2-bread;i++){ for(j=0;j<bread;j++) if(buffer[j] != bigassbuffer[i+j])break; if(j==bread){ fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<<hs)); } } { FILE *f=fopen("a.m","w"); for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]); fclose(f); f=fopen("b.m","w"); for(j=-4096;j<bread+4096;j++) if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2) fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]); fclose(f); } exit(1); } } }
void alogg_seek_rel_bytes_ogg(ALOGG_OGG *ogg, int bytes) { int current_byte = ov_raw_tell(&(ogg->vf)); int wanted_byte = current_byte + bytes; /* check the byte is valid */ if ((wanted_byte < 0) || (wanted_byte >= ogg->data_len)) return; /* get current byte and add to it */ bytes += ov_raw_tell(&(ogg->vf)); ov_raw_seek(&(ogg->vf), bytes); }
void _verify(OggVorbis_File *ov, ogg_int64_t val, ogg_int64_t pcmval, ogg_int64_t timeval, ogg_int64_t pcmlength, char *bigassbuffer){ int j; long bread; char buffer[4096]; int dummy; ogg_int64_t pos; /* verify the raw position, the pcm position and position decode */ if(val!=-1 && ov_raw_tell(ov)<val){ fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n", (long)val,(long)ov_raw_tell(ov)); exit(1); } if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){ fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n", (long)pcmval,(long)ov_pcm_tell(ov)); exit(1); } if(timeval!=-1 && ov_time_tell(ov)>timeval){ fprintf(stderr,"time position out of tolerance: requested %ld, got %ld\n", (long)timeval,(long)ov_time_tell(ov)); exit(1); } pos=ov_pcm_tell(ov); if(pos<0 || pos>pcmlength){ fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos); exit(1); } bread=ov_read(ov,buffer,4096,&dummy); if(bigassbuffer){ for(j=0;j<bread;j++){ if(buffer[j]!=bigassbuffer[j+pos*4]){ fprintf(stderr,"data position after seek doesn't match pcm position\n"); { FILE *f=fopen("a.m","w"); for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]); fclose(f); f=fopen("b.m","w"); for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]); fclose(f); } exit(1); } } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Manage suspend: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int OGG_suspend(){ OGG_suspendPosition = ov_raw_tell(&OGG_VorbisFile); OGG_suspendIsPlaying = OGG_isPlaying; OGG_Stop(); OGG_FreeTune(); return 0; }
/* ================= S_OpenBackgroundTrack ================= */ static qboolean S_OpenBackgroundTrack (char *name, bgTrack_t *track) { OggVorbis_File *vorbisFile; vorbis_info *vorbisInfo; ov_callbacks vorbisCallbacks = {ovc_read, ovc_seek, ovc_close, ovc_tell}; #ifdef OGG_DIRECT_FILE char filename[1024]; char *path = NULL; #endif // Com_Printf("Opening background track: %s\n", name); #ifdef OGG_DIRECT_FILE do { path = FS_NextPath( path ); Com_sprintf( filename, sizeof(filename), "%s/%s", path, name ); if ( (track->file = fopen(filename, "rb")) != 0) break; } while ( path ); #else FS_FOpenFile(name, &track->file); #endif if (!track->file) { Com_Printf("S_OpenBackgroundTrack: couldn't find %s\n", name); return false; } track->vorbisFile = vorbisFile = Z_Malloc(sizeof(OggVorbis_File)); // Com_Printf("Opening callbacks for background track\n"); // bombs out here- ovc_read, FS_Read 0 bytes error if (ov_open_callbacks(track, vorbisFile, NULL, 0, vorbisCallbacks) < 0) { Com_Printf("S_OpenBackgroundTrack: couldn't open OGG stream (%s)\n", name); return false; } // Com_Printf("Getting info for background track\n"); vorbisInfo = ov_info(vorbisFile, -1); if (vorbisInfo->channels != 1 && vorbisInfo->channels != 2) { Com_Printf("S_OpenBackgroundTrack: only mono and stereo OGG files supported (%s)\n", name); return false; } track->start = ov_raw_tell(vorbisFile); track->rate = vorbisInfo->rate; track->width = 2; track->channels = vorbisInfo->channels; // Knightmare added track->format = (vorbisInfo->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; // Com_Printf("Vorbis info: frequency: %i channels: %i bitrate: %i\n", // vorbisInfo->rate, vorbisInfo->channels, vorbisInfo->bitrate_nominal); return true; }
/** * \brief OGG read Callback. * \param[in] name File name to open. * \param[in/out] Music track data structure. * \return False on error, otherwise true. * \note */ PRIVATE _boolean Sound_OpenBGTrack( const char *name, musicTrack_t *track ) { OggVorbis_File *vorbisFile; vorbis_info *vorbisInfo; ov_callbacks vorbisCallbacks = {ovc_read, ovc_seek, ovc_close, ovc_tell}; int ret; track->hFile = FS_OpenFile( name, 0 ); if( ! track->hFile ) { return false; } track->vorbisFile = vorbisFile = Z_Malloc( sizeof( OggVorbis_File ) ); if( (ret = ov_open_callbacks( track, vorbisFile, NULL, 0, vorbisCallbacks )) < 0 ) { switch( ret ) { case OV_EREAD: Com_DPrintf( "A read from media returned an error.(%s)\n", name ); break; case OV_ENOTVORBIS: Com_DPrintf( "Bitstream is not Vorbis data.(%s)\n", name ); break; case OV_EVERSION: Com_DPrintf( "Vorbis version mismatch.(%s)\n", name ); break; case OV_EBADHEADER: Com_DPrintf( "Invalid Vorbis bitstream header.(%s)\n", name ); break; case OV_EFAULT: Com_DPrintf( "Internal logic fault; indicates a bug or heap/stack corruption.(%s)\n", name ); break; } Com_DPrintf( "Could not open OGG stream (%s)\n", name ); return false; } vorbisInfo = ov_info( vorbisFile, -1 ); if( vorbisInfo->channels != 1 && vorbisInfo->channels != 2 ) { Com_DPrintf( "Only mono and stereo OGG files supported (%s)\n", name ); return false; } track->start = ov_raw_tell( vorbisFile ); track->rate = vorbisInfo->rate; track->format = (vorbisInfo->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; return true; }
/* ================= S_OpenBackgroundTrack ================= */ static qboolean S_OpenBackgroundTrack (char *name, bgTrack_t *track) { OggVorbis_File *vorbisFile; vorbis_info *vorbisInfo; ov_callbacks vorbisCallbacks = {ovc_read, ovc_seek, ovc_close, ovc_tell}; if (!ogg_started) return; track->buffersize = FS_LoadFile(name, (void **)&track->buffer); if (track->buffersize <= 0) { if (track->buffer) { Z_Free(track->buffer); track->buffer = NULL; } track->buffersize = 0; Com_Printf("S_OpenBackgroundTrack: couldn't find %s\n", name); return false; } track->vorbisFile = vorbisFile = Z_Malloc(sizeof(OggVorbis_File)); track->buffer_position = track->buffer; // callbacks for background tracks if (ov_open_callbacks(track, vorbisFile, NULL, 0, vorbisCallbacks) < 0) { Com_Printf("S_OpenBackgroundTrack: couldn't open OGG stream (%s)\n", name); return false; } // getting info for background track vorbisInfo = ov_info(vorbisFile, -1); if (vorbisInfo->channels != 1 && vorbisInfo->channels != 2) { Com_Printf("S_OpenBackgroundTrack: only mono and stereo OGG files supported (%s)\n", name); return false; } track->start = ov_raw_tell(vorbisFile); track->rate = vorbisInfo->rate; track->width = 2; track->channels = vorbisInfo->channels; track->format = (vorbisInfo->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; return true; }
bool libname::COggStreamSample::Stream( ALuint buffer ) { if ( !m_pFile ) return false; bool done = false; int current_section; long readBytes = 0; while( readBytes < BUFFER_SIZE ) { long ret=ov_read(&m_OggFile, m_pBufferData+readBytes, BUFFER_SIZE-readBytes, OGG_LITTLE_ENDIAN, PCM_SAMPLE_16BIT, SIGNED_DATA, ¤t_section); if (ret == 0) done=1; else if (ret < 0) { throw std::string( "error in stream"); } else { readBytes+=ret; } } //cerr << "read from stream :" << readBytes << endl; // if there was no more data to be read, stop. if ( ov_raw_tell(&m_OggFile) >= m_lFileSize-1 ) { m_bHasEnded = true; } if ( readBytes == 0 ) { return false; } // Upload sound data to buffer alBufferData( buffer, GetFormat(), m_pBufferData, readBytes, GetFreq()); ALenum error = alGetError(); if ( error != AL_NO_ERROR ) { cerr << __FUNCTION__ << GetOpenALErrorString(error) << endl; return false; } return true; }
static int ices_vorbis_readpcm (input_stream_t* self, size_t olen, int16_t* left, int16_t* right) { ices_vorbis_in_t* vorbis_data = (ices_vorbis_in_t*) self->data; int pos; int len; int i; /* refill buffer if necessary */ if (! vorbis_data->samples) { vorbis_data->offset = 0; do { if ((len = ov_read (vorbis_data->vf, (char*) vorbis_data->buf, sizeof (vorbis_data->buf), ICES_OV_BE, SAMPLESIZE, 1, &pos)) <= 0) { if (len == OV_HOLE) { ices_log_error ("Skipping bad vorbis data"); } else return len; } } while (len <= 0); vorbis_data->samples = len / SAMPLESIZE; if (vorbis_data->info->channels > 1) vorbis_data->samples /= vorbis_data->info->channels; self->bytes_read = ov_raw_tell (vorbis_data->vf); } len = 0; while (vorbis_data->samples && olen) { if (vorbis_data->info->channels == 1) { *left = *right = vorbis_data->buf[vorbis_data->offset++]; left++; right++; } else { *left++ = vorbis_data->buf[vorbis_data->offset++]; *right++ = vorbis_data->buf[vorbis_data->offset++]; } for (i = 0; i < vorbis_data->info->channels - 2; i++) vorbis_data->offset++; vorbis_data->samples--; olen -= SAMPLESIZE; len++; } return len; }
int alogg_get_pos_bytes_ogg(ALOGG_OGG *ogg) { return ov_raw_tell(&(ogg->vf)); }
int alogg_get_pos_bytes_oggstream(ALOGG_OGGSTREAM *ogg) { return ov_raw_tell(&(ogg->vf)); }
int cOggDecoder::getCurrentCompressedPosition() { return ov_raw_tell(&oggStream); }
///////////////////////////////////////////////////////////////////////////////////////// //Audio callback ///////////////////////////////////////////////////////////////////////////////////////// static void oggDecodeThread(void *_buf2, unsigned int numSamples, void *pdata){ short *_buf = (short *)_buf2; //static short OGG_mixBuffer[PSP_NUM_AUDIO_SAMPLES * 2 * 2]__attribute__ ((aligned(64))); //static unsigned long OGG_tempmixleft = 0; int current_section; if (OGG_isPlaying) { // Playing , so mix up a buffer outputInProgress = 1; while (OGG_tempmixleft < numSamples) { // Not enough in buffer, so we must mix more unsigned long bytesRequired = (numSamples - OGG_tempmixleft) * 4; // 2channels, 16bit = 4 bytes per sample unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, ¤t_section); //libtremor //unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, 0, 2, 1, ¤t_section); //ogg-vorbis if (!ret) { //EOF OGG_isPlaying = 0; OGG_eos = 1; outputInProgress = 0; return; } else if (ret < 0) { if (ret == OV_HOLE) continue; OGG_isPlaying = 0; OGG_eos = 1; outputInProgress = 0; return; } OGG_tempmixleft += ret / 4; // back down to sample num } OGG_info.instantBitrate = ov_bitrate_instant(&OGG_VorbisFile); OGG_milliSeconds = ov_time_tell(&OGG_VorbisFile); //Check for playing speed: if (OGG_playingSpeed){ if (ov_raw_seek(&OGG_VorbisFile, ov_raw_tell(&OGG_VorbisFile) + OGG_playingDelta) != 0) OGG_setPlayingSpeed(0); } if (OGG_tempmixleft >= numSamples) { // Buffer has enough, so copy across int count, count2; short *_buf2; for (count = 0; count < numSamples; count++) { count2 = count + count; _buf2 = _buf + count2; //Volume boost: if (OGG_volume_boost){ *(_buf2) = volume_boost(&OGG_mixBuffer[count2], &OGG_volume_boost); *(_buf2 + 1) = volume_boost(&OGG_mixBuffer[count2 + 1], &OGG_volume_boost); }else{ // Double up for stereo *(_buf2) = OGG_mixBuffer[count2]; *(_buf2 + 1) = OGG_mixBuffer[count2 + 1]; } } // Move the pointers OGG_tempmixleft -= numSamples; // Now shuffle the buffer along for (count = 0; count < OGG_tempmixleft * 2; count++) OGG_mixBuffer[count] = OGG_mixBuffer[numSamples * 2 + count]; } outputInProgress = 0; } else { // Not Playing , so clear buffer int count; for (count = 0; count < numSamples * 2; count++) *(_buf + count) = 0; } }
/* this is the codec entry point */ enum codec_status codec_main(void) { ov_callbacks callbacks; OggVorbis_File vf; ogg_int32_t **pcm; int error; long n; int current_section; int previous_section; int eof; ogg_int64_t vf_offsets[2]; ogg_int64_t vf_dataoffsets; ogg_uint32_t vf_serialnos; ogg_int64_t vf_pcmlengths[2]; ci->configure(DSP_SET_SAMPLE_DEPTH, 24); if (codec_init()) { error = CODEC_ERROR; goto exit; } ogg_malloc_init(); #if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS) if (setjmp(rb_jump_buf) != 0) { /* malloc failed; skip to next track */ error = CODEC_ERROR; goto done; } #endif next_track: while (!*ci->taginfo_ready && !ci->stop_codec) ci->sleep(1); /* Create a decoder instance */ callbacks.read_func = read_handler; callbacks.seek_func = initial_seek_handler; callbacks.tell_func = tell_handler; callbacks.close_func = close_handler; /* Open a non-seekable stream */ error = ov_open_callbacks(ci, &vf, NULL, 0, callbacks); /* If the non-seekable open was successful, we need to supply the missing * data to make it seekable. This is a hack, but it's reasonable since we * don't want to run the whole file through the buffer before we start * playing. Using Tremor's seekable open routine would cause us to do * this, so we pretend not to be seekable at first. Then we fill in the * missing fields of vf with 1) information in ci->id3, and 2) info * obtained by Tremor in the above ov_open call. * * Note that this assumes there is only ONE logical Vorbis bitstream in our * physical Ogg bitstream. This is verified in metadata.c, well before we * get here. */ if (!error) { ogg_free(vf.offsets); ogg_free(vf.dataoffsets); ogg_free(vf.serialnos); vf.offsets = vf_offsets; vf.dataoffsets = &vf_dataoffsets; vf.serialnos = &vf_serialnos; vf.pcmlengths = vf_pcmlengths; vf.offsets[0] = 0; vf.offsets[1] = ci->id3->filesize; vf.dataoffsets[0] = vf.offset; vf.pcmlengths[0] = 0; vf.pcmlengths[1] = ci->id3->samples; vf.serialnos[0] = vf.current_serialno; vf.callbacks.seek_func = seek_handler; vf.seekable = 1; vf.end = ci->id3->filesize; vf.ready_state = OPENED; vf.links = 1; } else { DEBUGF("Vorbis: ov_open failed: %d", error); error = CODEC_ERROR; goto done; } if (ci->id3->offset) { ci->advance_buffer(ci->id3->offset); ov_raw_seek(&vf, ci->id3->offset); ci->set_elapsed(ov_time_tell(&vf)); ci->set_offset(ov_raw_tell(&vf)); } previous_section = -1; eof = 0; while (!eof) { ci->yield(); if (ci->stop_codec || ci->new_track) break; if (ci->seek_time) { if (ov_time_seek(&vf, ci->seek_time - 1)) { //ci->logf("ov_time_seek failed"); } ci->seek_complete(); } /* Read host-endian signed 24-bit PCM samples */ n = ov_read_fixed(&vf, &pcm, 1024, ¤t_section); /* Change DSP and buffer settings for this bitstream */ if (current_section != previous_section) { if (!vorbis_set_codec_parameters(&vf)) { error = CODEC_ERROR; goto done; } else { previous_section = current_section; } } if (n == 0) { eof = 1; } else if (n < 0) { DEBUGF("Vorbis: Error decoding frame\n"); } else { ci->pcmbuf_insert(pcm[0], pcm[1], n); ci->set_offset(ov_raw_tell(&vf)); ci->set_elapsed(ov_time_tell(&vf)); } } error = CODEC_OK; done: #if 0 /* defined(SIMULATOR) */ { size_t bufsize; void* buf = ci->codec_get_buffer(&bufsize); DEBUGF("Vorbis: Memory max: %u\n", get_max_size(buf)); } #endif if (ci->request_next_track()) { /* Clean things up for the next track */ vf.dataoffsets = NULL; vf.offsets = NULL; vf.serialnos = NULL; vf.pcmlengths = NULL; ov_clear(&vf); goto next_track; } exit: ogg_malloc_destroy(); return error; }
size_t OggWrapper::getCurrentStreamPos() const { return static_cast<size_t>(ov_raw_tell(ovFile_)); }