| | 68 | |
| | 69 | static FILE* _bgStream = 0; |
| | 70 | static OggVorbis_File _vf; |
| | 71 | static vorbis_info* _vinfo; |
| | 72 | |
| | 73 | #if BYTE_ORDER == LITTLE_ENDIAN |
| | 74 | #define OGG_BIG_ENDIAN 0 |
| | 75 | #else |
| | 76 | #define OGG_BIG_ENDIAN 1 |
| | 77 | #endif |
| | 78 | #define OGG_BUFFER_SIZE (4096 * 4) |
| | 79 | static char _oggPCM[ OGG_BUFFER_SIZE ]; |
| | 80 | |
| | 81 | /* |
| | 82 | Returns false if all data has been read or an error occurs. |
| | 83 | */ |
| | 84 | static int _readOgg( ALuint buffer, OggVorbis_File* vf, vorbis_info* vinfo ) |
| | 85 | { |
| | 86 | int stream; |
| | 87 | unsigned int count = 0; |
| | 88 | |
| | 89 | while( count < OGG_BUFFER_SIZE ) |
| | 90 | { |
| | 91 | int amt = ov_read( vf, _oggPCM + count, OGG_BUFFER_SIZE - count, |
| | 92 | OGG_BIG_ENDIAN, 2, 1, &stream ); |
| | 93 | if( amt <= 0 ) |
| | 94 | { |
| | 95 | if( amt < 0 ) |
| | 96 | fprintf( stderr, "ov_read" ); |
| | 97 | break; |
| | 98 | } |
| | 99 | count += amt; |
| | 100 | } |
| | 101 | |
| | 102 | if( ! count ) |
| | 103 | return 0; |
| | 104 | |
| | 105 | ALint format = (vinfo->channels == 1) ? AL_FORMAT_MONO16 : |
| | 106 | AL_FORMAT_STEREO16; |
| | 107 | |
| | 108 | //printf( "KR ogg count %d\n", count ); |
| | 109 | alBufferData( buffer, format, _oggPCM, count, vinfo->rate ); |
| | 110 | |
| | 111 | return 1; |
| | 112 | } |
| | 113 | |
| | 114 | |
| | 115 | static void _startMusic() |
| | 116 | { |
| | 117 | int i; |
| | 118 | for( i = 0; i < MUSIC_BUFFERS; ++i ) |
| | 119 | { |
| | 120 | if( ! _readOgg( _musicBuffers[i], &_vf, _vinfo ) ) |
| | 121 | { |
| | 122 | ov_clear( &_vf ); // Closes _bgStream for us. |
| | 123 | _bgStream = 0; |
| | 124 | break; |
| | 125 | } |
| | 126 | } |
| | 127 | |
| | 128 | if( i > 0 ) |
| | 129 | { |
| | 130 | alSourceQueueBuffers( _musicSource, i, _musicBuffers ); |
| | 131 | alSourcePlay( _musicSource ); |
| | 132 | //printf( "KR _startMusic %d\n", i ); |
| | 133 | } |
| | 134 | } |
| 132 | | } |
| 133 | | |
| 134 | | |
| | 193 | #if 0 |
| | 194 | static Millisec prev = 0; |
| | 195 | Millisec now, diff; |
| | 196 | now = osNow(); |
| | 197 | diff = now - prev; |
| | 198 | prev = now; |
| | 199 | if( diff > (16 * 5) ) |
| | 200 | printf( "%ld\n", diff ); |
| | 201 | #endif |
| | 202 | |
| | 203 | if( _musicSource ) |
| | 204 | { |
| | 205 | #if 0 |
| | 206 | ALint sourcestate; |
| | 207 | alGetSourcei( _musicSource, AL_SOURCE_STATE, &sourcestate ); |
| | 208 | if( sourcestate != AL_PLAYING ) |
| | 209 | { |
| | 210 | if( _bgStream ) |
| | 211 | { |
| | 212 | // The music source will stop playing when the buffers |
| | 213 | // have been emptied. This can easily occur if the X11 window |
| | 214 | // is moved vigorously around or a long load happens between |
| | 215 | // audioUpdate() calls. |
| | 216 | |
| | 217 | printf( "KR audioUpdate - _musicSource not playing!\n" ); |
| | 218 | |
| | 219 | // For some reason this solution causes the stream quality |
| | 220 | // to degrade (noise and echos occur). |
| | 221 | _startMusic(); |
| | 222 | } |
| | 223 | else |
| | 224 | { |
| | 225 | aud_stopMusic(); |
| | 226 | } |
| | 227 | return; |
| | 228 | } |
| | 229 | #endif |
| | 230 | |
| | 231 | if( _bgStream ) |
| | 232 | { |
| | 233 | ALint processed; |
| | 234 | ALuint freeBuf; |
| | 235 | |
| | 236 | alGetSourcei( _musicSource, AL_BUFFERS_PROCESSED, &processed ); |
| | 237 | |
| | 238 | //if( processed ) printf( "KR proc %d\n", processed ); |
| | 239 | |
| | 240 | while( processed ) |
| | 241 | { |
| | 242 | alSourceUnqueueBuffers( _musicSource, 1, &freeBuf ); |
| | 243 | //printf( " buf %d\n", freeBuf ); |
| | 244 | |
| | 245 | if( _readOgg( freeBuf, &_vf, _vinfo ) ) |
| | 246 | { |
| | 247 | alSourceQueueBuffers( _musicSource, 1, &freeBuf ); |
| | 248 | } |
| | 249 | else |
| | 250 | { |
| | 251 | printf( "KR audioUpdate - end of stream\n" ); |
| | 252 | ov_clear( &_vf ); // Closes _bgStream for us. |
| | 253 | _bgStream = 0; |
| | 254 | break; |
| | 255 | } |
| | 256 | |
| | 257 | --processed; |
| | 258 | } |
| | 259 | } |
| | 260 | } |
| | 261 | } |
| | 262 | |
| | 263 | |
| | 264 | #if 0 |
| 297 | | size = ur_fileSize( file ); |
| 298 | | if( size > 0 ) |
| 299 | | { |
| 300 | | fileBuf = memAlloc( size ); |
| 301 | | if( fileBuf ) |
| 302 | | { |
| 303 | | FileHandle fp = fileOpen( file, FILE_READ_BINARY ); |
| 304 | | if( fp ) |
| 305 | | { |
| 306 | | if( fileRead( fp, fileBuf, size ) == (size_t) size ) |
| 307 | | ok = 1; |
| 308 | | fileClose( fp ); |
| 309 | | } |
| 310 | | } |
| 311 | | } |
| 312 | | |
| 313 | | if( ok ) |
| 314 | | { |
| | 422 | _bgStream = fopen( file, "rb" ); |
| | 423 | if( ! _bgStream ) |
| | 424 | return; |
| | 425 | |
| | 426 | if( ov_open( _bgStream, &_vf, NULL, 0 ) < 0 ) |
| | 427 | { |
| | 428 | fclose( _bgStream ); |
| | 429 | _bgStream = 0; |
| | 430 | |
| | 431 | fprintf( stderr, "aud_playMusic - %s is not a valid Ogg file\n", |
| | 432 | file ); |
| | 433 | } |
| | 434 | else |
| | 435 | { |
| | 436 | _vinfo = ov_info( &_vf, -1 ); |
| | 437 | |