pub.mod/oggvorbis.mod: faulty loop?
Archives Forums/BlitzMax Bug Reports/pub.mod/oggvorbis.mod: faulty loop?
| ||
the following code is currently used in pub.mod/oggvorbis.mod:int Read_Ogg(oggio *ogg,char *buf,int bytes) // null buffer to close { int res,bs; if (buf==0) return ov_clear(&ogg->vf); while (bytes>0) { res=ov_read(&ogg->vf,buf,bytes,endian,bits/8,sign,&bs); if (res<0) { if (bs) return -1; // Only one logical bitstream currently supported return -2; // Warning: hole in data } buf+=res; bytes-=res; } return 0; } There are two issues: - Read_Ogg() does return "0" instead of the amount of read bytes (which might differ from the param "bytes") - what happens, if you read up to the last byte of the ogg file - so "ov_read" returns 0 ... I assume you are then trapped in the while-loop, as "bytes" will never reach "0" I am not sure whether I have done it right, but I think this would solve both issues: int Read_Ogg(oggio *ogg,char *buf,int bytes) // null buffer to close { int res,bs,read; if (buf==0) return ov_clear(&ogg->vf); read = 0; while (bytes>0) { res=ov_read(&ogg->vf,buf,bytes,endian,bits/8,sign,&bs); if (res<0) { if (bs) return -1; // Only one logical bitstream currently supported return -2; // Warning: hole in data } else if (res == 0) // reached eof { return read; } read+=res; buf+=res; bytes-=res; } return read; } The returned value "read" contains the bytes loaded by the multiple calls of ov_read(). bye Ron |
| ||
. |
| ||
ov_read(): It returns up to the specified number of bytes of decoded PCM audio in the requested endianness, signedness, and word size. [...] Return Values OV_HOLE indicates there was an interruption in the data. (one of: garbage between pages, loss of sync followed by recapture, or a corrupt page) OV_EBADLINK indicates that an invalid stream section was supplied to libvorbisfile, or the requested link is corrupt. OV_EINVAL indicates the initial file headers couldn't be read or are corrupt, or that the initial open call for vf failed. 0 indicates EOF n indicates actual number of bytes read. ov_read() will decode at most one vorbis packet per invocation, so the value returned will generally be less than length. https://www.xiph.org/vorbis/doc/vorbisfile/ov_read.html In oggvorbis.mod/libvorbis-1.3.4/include/vorbis/codec.h the following consts are defined: #define OV_EOF -2 #define OV_HOLE -3 [...] #define OV_EBADLINK -137 So there is an error code for reaching EOF, while the documentation mentions a returned "0" is also EOF ? bye Ron |
| ||
Perhaps the error code is only returned when continuing to read passed the EOF. So when an EOF is reached initially the return value will be 0, then upon trying again the error value is returned? |
| ||
Something to try out (you need to supply your own "sound3.ogg" - and take a small one, so it has less than 1mio samples): With the default implementation, it will get trapped in the second Read_Ogg(stream2...) call (application has to get force killed). The first call to Read_ogg() returns 0 as it did not see another error, so we cannot know if we reached EOF yet. With the adjusted Read_ogg the first call returns the "max bytes" while the second one returns 0 (the EOF-result). Don't know which one is better ;-) |
| ||
ith the default implementation, it will get trapped in the second Read_Ogg(stream2...) call (application has to get force killed). Oh, thats not good! Well spotted!! Don't know which one is better ;-) I'd say if one your algos can reflect a change of 'state' in the return value then that is the better way to go. |