28
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
29
/* *************************************************************************/
30
30
31
+ #define QOA_IMPLEMENTATION
32
+ #define QOA_NO_STDIO
33
+
31
34
#include " audio_stream_wav.h"
32
35
33
36
#include " core/io/file_access.h"
@@ -235,6 +238,7 @@ int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_
235
238
len /= 1 ;
236
239
break ;
237
240
case AudioStreamWAV::FORMAT_16_BITS:
241
+ case AudioStreamWAV::FORMAT_QOA:
238
242
len /= 2 ;
239
243
break ;
240
244
case AudioStreamWAV::FORMAT_IMA_ADPCM:
@@ -373,7 +377,8 @@ int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_
373
377
do_resample<int8_t , false , false >((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
374
378
}
375
379
} break ;
376
- case AudioStreamWAV::FORMAT_16_BITS: {
380
+ case AudioStreamWAV::FORMAT_16_BITS:
381
+ case AudioStreamWAV::FORMAT_QOA: {
377
382
if (is_stereo) {
378
383
do_resample<int16_t , true , false >((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm);
379
384
} else {
@@ -470,6 +475,7 @@ double AudioStreamWAV::get_length() const {
470
475
len /= 1 ;
471
476
break ;
472
477
case AudioStreamWAV::FORMAT_16_BITS:
478
+ case AudioStreamWAV::FORMAT_QOA:
473
479
len /= 2 ;
474
480
break ;
475
481
case AudioStreamWAV::FORMAT_IMA_ADPCM:
@@ -499,12 +505,25 @@ void AudioStreamWAV::set_data(const Vector<uint8_t> &p_data) {
499
505
int datalen = p_data.size ();
500
506
if (datalen) {
501
507
const uint8_t *r = p_data.ptr ();
502
- int alloc_len = datalen + DATA_PAD * 2 ;
503
- data = memalloc (alloc_len); // alloc with some padding for interpolation
504
- memset (data, 0 , alloc_len);
505
- uint8_t *dataptr = (uint8_t *)data;
506
- memcpy (dataptr + DATA_PAD, r, datalen);
507
- data_bytes = datalen;
508
+ qoa_desc qoad;
509
+ int alloc_len = 0 ;
510
+ if (qoa_decode_header (r, datalen, &qoad) == 8 ) { // QOA
511
+ int16_t *sample_data = qoa_decode (r, datalen, &qoad);
512
+ int qoa_datalen = qoad.samples * qoad.channels * sizeof (int16_t );
513
+ alloc_len = qoa_datalen + DATA_PAD * 2 ;
514
+ data = memalloc (alloc_len);
515
+ memset (data, 0 , alloc_len);
516
+ int16_t *dataptr = (int16_t *)data;
517
+ memcpy (dataptr + DATA_PAD, sample_data, qoa_datalen);
518
+ data_bytes = qoa_datalen;
519
+ } else {
520
+ alloc_len = datalen + DATA_PAD * 2 ;
521
+ data = memalloc (alloc_len); // alloc with some padding for interpolation
522
+ memset (data, 0 , alloc_len);
523
+ uint8_t *dataptr = (uint8_t *)data;
524
+ memcpy (dataptr + DATA_PAD, r, datalen);
525
+ data_bytes = datalen;
526
+ }
508
527
}
509
528
510
529
AudioServer::get_singleton ()->unlock ();
@@ -548,6 +567,7 @@ Error AudioStreamWAV::save_to_wav(const String &p_path) {
548
567
byte_pr_sample = 1 ;
549
568
break ;
550
569
case AudioStreamWAV::FORMAT_16_BITS:
570
+ case AudioStreamWAV::FORMAT_QOA:
551
571
byte_pr_sample = 2 ;
552
572
break ;
553
573
case AudioStreamWAV::FORMAT_IMA_ADPCM:
@@ -590,6 +610,7 @@ Error AudioStreamWAV::save_to_wav(const String &p_path) {
590
610
}
591
611
break ;
592
612
case AudioStreamWAV::FORMAT_16_BITS:
613
+ case AudioStreamWAV::FORMAT_QOA:
593
614
for (unsigned int i = 0 ; i < data_bytes / 2 ; i++) {
594
615
uint16_t data_point = decode_uint16 (&read_data[i * 2 ]);
595
616
file->store_16 (data_point);
@@ -639,7 +660,7 @@ void AudioStreamWAV::_bind_methods() {
639
660
ClassDB::bind_method (D_METHOD (" save_to_wav" , " path" ), &AudioStreamWAV::save_to_wav);
640
661
641
662
ADD_PROPERTY (PropertyInfo (Variant::PACKED_BYTE_ARRAY, " data" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), " set_data" , " get_data" );
642
- ADD_PROPERTY (PropertyInfo (Variant::INT, " format" , PROPERTY_HINT_ENUM, " 8-Bit,16-Bit,IMA-ADPCM" ), " set_format" , " get_format" );
663
+ ADD_PROPERTY (PropertyInfo (Variant::INT, " format" , PROPERTY_HINT_ENUM, " 8-Bit,16-Bit,IMA-ADPCM,QOA " ), " set_format" , " get_format" );
643
664
ADD_PROPERTY (PropertyInfo (Variant::INT, " loop_mode" , PROPERTY_HINT_ENUM, " Disabled,Forward,Ping-Pong,Backward" ), " set_loop_mode" , " get_loop_mode" );
644
665
ADD_PROPERTY (PropertyInfo (Variant::INT, " loop_begin" ), " set_loop_begin" , " get_loop_begin" );
645
666
ADD_PROPERTY (PropertyInfo (Variant::INT, " loop_end" ), " set_loop_end" , " get_loop_end" );
@@ -649,6 +670,7 @@ void AudioStreamWAV::_bind_methods() {
649
670
BIND_ENUM_CONSTANT (FORMAT_8_BITS);
650
671
BIND_ENUM_CONSTANT (FORMAT_16_BITS);
651
672
BIND_ENUM_CONSTANT (FORMAT_IMA_ADPCM);
673
+ BIND_ENUM_CONSTANT (FORMAT_QOA);
652
674
653
675
BIND_ENUM_CONSTANT (LOOP_DISABLED);
654
676
BIND_ENUM_CONSTANT (LOOP_FORWARD);
0 commit comments