@@ -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 );
@@ -836,6 +837,10 @@ struct stb_vorbis
836
837
#ifdef STB_VORBIS_SDL
837
838
SDL_RWops * rwops ;
838
839
uint32 rwops_start ;
840
+ uint32 rwops_virtual_pos ;
841
+ uint32 rwops_buffer_pos ;
842
+ uint32 rwops_buffer_fill ;
843
+ uint8 rwops_buffer [RWOPS_BUFFER_SIZE ];
839
844
int close_on_free ;
840
845
#endif
841
846
@@ -1400,9 +1405,13 @@ static int STBV_CDECL point_compare(const void *p, const void *q)
1400
1405
static uint8 get8 (vorb * z )
1401
1406
{
1402
1407
#ifdef STB_VORBIS_SDL
1403
- uint8 c ;
1404
- if (SDL_RWread (z -> rwops , & c , 1 , 1 ) != 1 ) { z -> eof = TRUE; return 0 ; }
1405
- return c ;
1408
+ if (z -> rwops_buffer_pos >= z -> rwops_buffer_fill ) {
1409
+ z -> rwops_buffer_fill = SDL_RWread (z -> rwops , z -> rwops_buffer , 1 , RWOPS_BUFFER_SIZE );
1410
+ z -> rwops_buffer_pos = 0 ;
1411
+ if (z -> rwops_buffer_fill == 0 ) { z -> eof = TRUE; return 0 ; }
1412
+ }
1413
+ z -> rwops_virtual_pos ++ ;
1414
+ return z -> rwops_buffer [z -> rwops_buffer_pos ++ ];
1406
1415
1407
1416
#else
1408
1417
if (USE_MEMORY (z )) {
@@ -1433,9 +1442,28 @@ static uint32 get32(vorb *f)
1433
1442
static int getn (vorb * z , uint8 * data , int n )
1434
1443
{
1435
1444
#ifdef STB_VORBIS_SDL
1436
- if (SDL_RWread (z -> rwops , data , n , 1 ) == 1 ) return 1 ;
1437
- z -> eof = 1 ;
1438
- return 0 ;
1445
+ while (n > 0 ) {
1446
+ int chunk ;
1447
+
1448
+ if (z -> rwops_buffer_pos >= z -> rwops_buffer_fill ) {
1449
+ z -> rwops_buffer_fill = SDL_RWread (z -> rwops , z -> rwops_buffer , 1 , RWOPS_BUFFER_SIZE );
1450
+ z -> rwops_buffer_pos = 0 ;
1451
+ if (z -> rwops_buffer_fill == 0 ) {
1452
+ z -> eof = 1 ;
1453
+ return 0 ;
1454
+ }
1455
+ }
1456
+
1457
+ chunk = z -> rwops_buffer_fill - z -> rwops_buffer_pos ;
1458
+ if (chunk > n ) chunk = n ;
1459
+
1460
+ memcpy (data , z -> rwops_buffer + z -> rwops_buffer_pos , chunk );
1461
+ z -> rwops_buffer_pos += chunk ;
1462
+ z -> rwops_virtual_pos += chunk ;
1463
+ data += chunk ;
1464
+ n -= chunk ;
1465
+ }
1466
+ return 1 ;
1439
1467
1440
1468
#else
1441
1469
if (USE_MEMORY (z )) {
@@ -1456,11 +1484,12 @@ static int getn(vorb *z, uint8 *data, int n)
1456
1484
#endif
1457
1485
}
1458
1486
1487
+ static int set_file_offset (stb_vorbis * f , unsigned int loc );
1488
+
1459
1489
static void skip (vorb * z , int n )
1460
1490
{
1461
1491
#ifdef STB_VORBIS_SDL
1462
- SDL_RWseek (z -> rwops , n , RW_SEEK_CUR );
1463
-
1492
+ set_file_offset (z , z -> rwops_virtual_pos + n );
1464
1493
#else
1465
1494
if (USE_MEMORY (z )) {
1466
1495
z -> stream += n ;
@@ -1485,17 +1514,31 @@ static int set_file_offset(stb_vorbis *f, unsigned int loc)
1485
1514
f -> eof = 0 ;
1486
1515
1487
1516
#ifdef STB_VORBIS_SDL
1488
- if (loc + f -> rwops_start < loc || loc >= 0x80000000 ) {
1489
- loc = 0x7fffffff ;
1517
+ { unsigned int rwops_pos ;
1518
+ uint32 buffer_start = f -> rwops_virtual_pos - f -> rwops_buffer_pos ;
1519
+ uint32 buffer_end = buffer_start + f -> rwops_buffer_fill ;
1520
+ f -> rwops_virtual_pos = loc ;
1521
+
1522
+ // Move within buffer if possible
1523
+ if (loc >= buffer_start && loc < buffer_end )
1524
+ {
1525
+ f -> rwops_buffer_pos = loc - buffer_start ;
1526
+ return 1 ;
1527
+ }
1528
+
1529
+ rwops_pos = loc + f -> rwops_start ;
1530
+ if (rwops_pos < loc || loc >= 0x80000000 ) {
1531
+ rwops_pos = 0x7fffffff ;
1490
1532
f -> eof = 1 ;
1491
- } else {
1492
- loc += f -> rwops_start ;
1493
1533
}
1494
- if (SDL_RWseek (f -> rwops , loc , RW_SEEK_SET ) != -1 )
1534
+
1535
+ f -> rwops_buffer_pos = f -> rwops_buffer_fill = 0 ; // Invalidate buffer
1536
+ if (SDL_RWseek (f -> rwops , rwops_pos , RW_SEEK_SET ) != -1 )
1495
1537
return 1 ;
1496
1538
f -> eof = 1 ;
1497
1539
SDL_RWseek (f -> rwops , f -> rwops_start , RW_SEEK_END );
1498
1540
return 0 ;
1541
+ }
1499
1542
1500
1543
#else
1501
1544
if (USE_MEMORY (f )) {
@@ -4440,6 +4483,10 @@ static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z)
4440
4483
#ifdef STB_VORBIS_SDL
4441
4484
p -> close_on_free = FALSE;
4442
4485
p -> rwops = NULL ;
4486
+ p -> rwops_start = 0 ;
4487
+ p -> rwops_virtual_pos = 0 ;
4488
+ p -> rwops_buffer_pos = 0 ;
4489
+ p -> rwops_buffer_fill = 0 ;
4443
4490
#endif
4444
4491
#ifndef STB_VORBIS_NO_STDIO
4445
4492
p -> close_on_free = FALSE;
@@ -4711,7 +4758,7 @@ unsigned int stb_vorbis_get_file_offset(stb_vorbis *f)
4711
4758
if (f -> push_mode ) return 0 ;
4712
4759
#endif
4713
4760
#ifdef STB_VORBIS_SDL
4714
- return ( unsigned int ) ( SDL_RWtell ( f -> rwops ) - f -> rwops_start ) ;
4761
+ return f -> rwops_virtual_pos ;
4715
4762
#else
4716
4763
if (USE_MEMORY (f )) return (unsigned int ) (f -> stream - f -> stream_start );
4717
4764
#endif
0 commit comments