@@ -308,6 +308,7 @@ extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_cl
308
308
#ifdef STB_VORBIS_SDL
309
309
extern stb_vorbis * stb_vorbis_open_rwops_section (SDL_RWops * rwops , int close_on_free , int * error , const stb_vorbis_alloc * alloc , unsigned int length );
310
310
extern stb_vorbis * stb_vorbis_open_rwops (SDL_RWops * rwops , int close_on_free , int * error , const stb_vorbis_alloc * alloc );
311
+ #define RWOPS_BUFFER_SIZE 2048
311
312
#endif
312
313
313
314
extern int stb_vorbis_seek_frame (stb_vorbis * f , unsigned int sample_number );
@@ -834,6 +835,10 @@ struct stb_vorbis
834
835
#ifdef STB_VORBIS_SDL
835
836
SDL_RWops * rwops ;
836
837
uint32 rwops_start ;
838
+ uint32 rwops_virtual_pos ;
839
+ uint32 rwops_buffer_pos ;
840
+ uint32 rwops_buffer_fill ;
841
+ uint8 rwops_buffer [RWOPS_BUFFER_SIZE ];
837
842
int close_on_free ;
838
843
#endif
839
844
@@ -1398,9 +1403,13 @@ static int STBV_CDECL point_compare(const void *p, const void *q)
1398
1403
static uint8 get8 (vorb * z )
1399
1404
{
1400
1405
#ifdef STB_VORBIS_SDL
1401
- uint8 c ;
1402
- if (SDL_RWread (z -> rwops , & c , 1 , 1 ) != 1 ) { z -> eof = TRUE; return 0 ; }
1403
- return c ;
1406
+ if (z -> rwops_buffer_pos >= z -> rwops_buffer_fill ) {
1407
+ z -> rwops_buffer_fill = SDL_RWread (z -> rwops , z -> rwops_buffer , 1 , RWOPS_BUFFER_SIZE );
1408
+ z -> rwops_buffer_pos = 0 ;
1409
+ if (z -> rwops_buffer_fill == 0 ) { z -> eof = TRUE; return 0 ; }
1410
+ }
1411
+ z -> rwops_virtual_pos ++ ;
1412
+ return z -> rwops_buffer [z -> rwops_buffer_pos ++ ];
1404
1413
1405
1414
#else
1406
1415
if (USE_MEMORY (z )) {
@@ -1431,9 +1440,28 @@ static uint32 get32(vorb *f)
1431
1440
static int getn (vorb * z , uint8 * data , int n )
1432
1441
{
1433
1442
#ifdef STB_VORBIS_SDL
1434
- if (SDL_RWread (z -> rwops , data , n , 1 ) == 1 ) return 1 ;
1435
- z -> eof = 1 ;
1436
- return 0 ;
1443
+ while (n > 0 ) {
1444
+ int chunk ;
1445
+
1446
+ if (z -> rwops_buffer_pos >= z -> rwops_buffer_fill ) {
1447
+ z -> rwops_buffer_fill = SDL_RWread (z -> rwops , z -> rwops_buffer , 1 , RWOPS_BUFFER_SIZE );
1448
+ z -> rwops_buffer_pos = 0 ;
1449
+ if (z -> rwops_buffer_fill == 0 ) {
1450
+ z -> eof = 1 ;
1451
+ return 0 ;
1452
+ }
1453
+ }
1454
+
1455
+ chunk = z -> rwops_buffer_fill - z -> rwops_buffer_pos ;
1456
+ if (chunk > n ) chunk = n ;
1457
+
1458
+ memcpy (data , z -> rwops_buffer + z -> rwops_buffer_pos , chunk );
1459
+ z -> rwops_buffer_pos += chunk ;
1460
+ z -> rwops_virtual_pos += chunk ;
1461
+ data += chunk ;
1462
+ n -= chunk ;
1463
+ }
1464
+ return 1 ;
1437
1465
1438
1466
#else
1439
1467
if (USE_MEMORY (z )) {
@@ -1454,11 +1482,12 @@ static int getn(vorb *z, uint8 *data, int n)
1454
1482
#endif
1455
1483
}
1456
1484
1485
+ static int set_file_offset (stb_vorbis * f , unsigned int loc );
1486
+
1457
1487
static void skip (vorb * z , int n )
1458
1488
{
1459
1489
#ifdef STB_VORBIS_SDL
1460
- SDL_RWseek (z -> rwops , n , RW_SEEK_CUR );
1461
-
1490
+ set_file_offset (z , z -> rwops_virtual_pos + n );
1462
1491
#else
1463
1492
if (USE_MEMORY (z )) {
1464
1493
z -> stream += n ;
@@ -1483,17 +1512,31 @@ static int set_file_offset(stb_vorbis *f, unsigned int loc)
1483
1512
f -> eof = 0 ;
1484
1513
1485
1514
#ifdef STB_VORBIS_SDL
1486
- if (loc + f -> rwops_start < loc || loc >= 0x80000000 ) {
1487
- loc = 0x7fffffff ;
1515
+ { unsigned int rwops_pos ;
1516
+ uint32 buffer_start = f -> rwops_virtual_pos - f -> rwops_buffer_pos ;
1517
+ uint32 buffer_end = buffer_start + f -> rwops_buffer_fill ;
1518
+ f -> rwops_virtual_pos = loc ;
1519
+
1520
+ // Move within buffer if possible
1521
+ if (loc >= buffer_start && loc < buffer_end )
1522
+ {
1523
+ f -> rwops_buffer_pos = loc - buffer_start ;
1524
+ return 1 ;
1525
+ }
1526
+
1527
+ rwops_pos = loc + f -> rwops_start ;
1528
+ if (rwops_pos < loc || loc >= 0x80000000 ) {
1529
+ rwops_pos = 0x7fffffff ;
1488
1530
f -> eof = 1 ;
1489
- } else {
1490
- loc += f -> rwops_start ;
1491
1531
}
1492
- if (SDL_RWseek (f -> rwops , loc , RW_SEEK_SET ) != -1 )
1532
+
1533
+ f -> rwops_buffer_pos = f -> rwops_buffer_fill = 0 ; // Invalidate buffer
1534
+ if (SDL_RWseek (f -> rwops , rwops_pos , RW_SEEK_SET ) != -1 )
1493
1535
return 1 ;
1494
1536
f -> eof = 1 ;
1495
1537
SDL_RWseek (f -> rwops , f -> rwops_start , RW_SEEK_END );
1496
1538
return 0 ;
1539
+ }
1497
1540
1498
1541
#else
1499
1542
if (USE_MEMORY (f )) {
@@ -4438,6 +4481,10 @@ static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z)
4438
4481
#ifdef STB_VORBIS_SDL
4439
4482
p -> close_on_free = FALSE;
4440
4483
p -> rwops = NULL ;
4484
+ p -> rwops_start = 0 ;
4485
+ p -> rwops_virtual_pos = 0 ;
4486
+ p -> rwops_buffer_pos = 0 ;
4487
+ p -> rwops_buffer_fill = 0 ;
4441
4488
#endif
4442
4489
#ifndef STB_VORBIS_NO_STDIO
4443
4490
p -> close_on_free = FALSE;
@@ -4709,7 +4756,7 @@ unsigned int stb_vorbis_get_file_offset(stb_vorbis *f)
4709
4756
if (f -> push_mode ) return 0 ;
4710
4757
#endif
4711
4758
#ifdef STB_VORBIS_SDL
4712
- return ( unsigned int ) ( SDL_RWtell ( f -> rwops ) - f -> rwops_start ) ;
4759
+ return f -> rwops_virtual_pos ;
4713
4760
#else
4714
4761
if (USE_MEMORY (f )) return (unsigned int ) (f -> stream - f -> stream_start );
4715
4762
#endif
0 commit comments