1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-07-08 04:25:14 +00:00

Cosmetic changes to audio source files

This commit is contained in:
Luke Ceddia 2017-08-06 13:37:54 +10:00
parent b17655fbb7
commit 79ffcc50b3
2 changed files with 1639 additions and 1639 deletions

View file

@ -8,25 +8,25 @@
#define DEPENDENCY_AUDIO_DECODE_WAV #define DEPENDENCY_AUDIO_DECODE_WAV
#ifdef QB64_BACKSLASH_FILESYSTEM #ifdef QB64_BACKSLASH_FILESYSTEM
#ifdef DEPENDENCY_AUDIO_DECODE_MP3 #ifdef DEPENDENCY_AUDIO_DECODE_MP3
#include "mp3_mini\\src.c" #include "mp3_mini\\src.c"
#endif #endif
#ifdef DEPENDENCY_AUDIO_DECODE_WAV #ifdef DEPENDENCY_AUDIO_DECODE_WAV
#include "wav\\src.c" #include "wav\\src.c"
#endif #endif
#ifdef DEPENDENCY_AUDIO_DECODE_OGG #ifdef DEPENDENCY_AUDIO_DECODE_OGG
#include "ogg\\src.c" #include "ogg\\src.c"
#endif #endif
#else #else
#ifdef DEPENDENCY_AUDIO_DECODE_MP3 #ifdef DEPENDENCY_AUDIO_DECODE_MP3
#include "mp3_mini/src.c" #include "mp3_mini/src.c"
#endif #endif
#ifdef DEPENDENCY_AUDIO_DECODE_WAV #ifdef DEPENDENCY_AUDIO_DECODE_WAV
#include "wav/src.c" #include "wav/src.c"
#endif #endif
#ifdef DEPENDENCY_AUDIO_DECODE_OGG #ifdef DEPENDENCY_AUDIO_DECODE_OGG
#include "ogg/src.c" #include "ogg/src.c"
#endif #endif
#endif #endif
//forward refs: //forward refs:
@ -34,248 +34,248 @@ void sub__sndvol(int32 handle,float volume);
void sub__sndclose(int32 handle); void sub__sndclose(int32 handle);
int32 func__sndopen(qbs* filename,qbs* requirements,int32 passed){ int32 func__sndopen(qbs* filename,qbs* requirements,int32 passed){
sndsetup(); sndsetup();
if (new_error) return 0; if (new_error) return 0;
static qbs *s1=NULL; static qbs *s1=NULL;
if (!s1) s1=qbs_new(0,0); if (!s1) s1=qbs_new(0,0);
static qbs *req=NULL; static qbs *req=NULL;
if (!req) req=qbs_new(0,0); if (!req) req=qbs_new(0,0);
static qbs *s3=NULL; static qbs *s3=NULL;
if (!s3) s3=qbs_new(0,0); if (!s3) s3=qbs_new(0,0);
static uint8 r[32]; static uint8 r[32];
static int32 i,i2,i3; static int32 i,i2,i3;
//check requirements //check requirements
memset(r,0,32); memset(r,0,32);
if (passed){ if (passed){
if (requirements->len){ if (requirements->len){
i=1; i=1;
qbs_set(req,qbs_ucase(requirements));//convert tmp str to perm str qbs_set(req,qbs_ucase(requirements));//convert tmp str to perm str
nextrequirement: nextrequirement:
i2=func_instr(i,req,qbs_new_txt(","),1); i2=func_instr(i,req,qbs_new_txt(","),1);
if (i2){ if (i2){
qbs_set(s1,func_mid(req,i,i2-i,1)); qbs_set(s1,func_mid(req,i,i2-i,1));
}else{ }else{
qbs_set(s1,func_mid(req,i,req->len-i+1,1)); qbs_set(s1,func_mid(req,i,req->len-i+1,1));
} }
qbs_set(s1,qbs_rtrim(qbs_ltrim(s1))); qbs_set(s1,qbs_rtrim(qbs_ltrim(s1)));
if (qbs_equal(s1,qbs_new_txt("SYNC"))){r[0]++; goto valid;} if (qbs_equal(s1,qbs_new_txt("SYNC"))){r[0]++; goto valid;}
if (qbs_equal(s1,qbs_new_txt("VOL"))){r[1]++; goto valid;} if (qbs_equal(s1,qbs_new_txt("VOL"))){r[1]++; goto valid;}
if (qbs_equal(s1,qbs_new_txt("PAUSE"))){r[2]++; goto valid;} if (qbs_equal(s1,qbs_new_txt("PAUSE"))){r[2]++; goto valid;}
if (qbs_equal(s1,qbs_new_txt("LEN"))){r[3]++; goto valid;} if (qbs_equal(s1,qbs_new_txt("LEN"))){r[3]++; goto valid;}
if (qbs_equal(s1,qbs_new_txt("SETPOS"))){r[4]++; goto valid;} if (qbs_equal(s1,qbs_new_txt("SETPOS"))){r[4]++; goto valid;}
error(5); return 0;//invalid requirements error(5); return 0;//invalid requirements
valid: valid:
if (i2){i=i2+1; goto nextrequirement;} if (i2){i=i2+1; goto nextrequirement;}
for (i=0;i<32;i++) if (r[i]>1){error(5); return 0;}//cannot define requirements twice for (i=0;i<32;i++) if (r[i]>1){error(5); return 0;}//cannot define requirements twice
}//->len }//->len
}//passed }//passed
qbs_set(s1,qbs_add(filename,qbs_new_txt_len("\0",1)));//s1=filename+CHR$(0) qbs_set(s1,qbs_add(filename,qbs_new_txt_len("\0",1)));//s1=filename+CHR$(0)
if (!r[0]){//NOT SYNC if (!r[0]){//NOT SYNC
if (snd_stream_handle){error(5); return 0;}//stream in use if (snd_stream_handle){error(5); return 0;}//stream in use
} }
//load file //load file
if (s1->len==1) return 0;//return invalid handle if null length string if (s1->len==1) return 0;//return invalid handle if null length string
static int32 fh,result; static int32 fh,result;
static int64 lof; static int64 lof;
fh=gfs_open(s1,1,0,0); fh=gfs_open(s1,1,0,0);
if (fh<0) return 0; if (fh<0) return 0;
lof=gfs_lof(fh); lof=gfs_lof(fh);
static uint8* content; static uint8* content;
content=(uint8*)malloc(lof); if (!content){gfs_close(fh); return 0;} content=(uint8*)malloc(lof); if (!content){gfs_close(fh); return 0;}
result=gfs_read(fh,-1,content,lof); result=gfs_read(fh,-1,content,lof);
gfs_close(fh); gfs_close(fh);
if (result<0){free(content); return 0;} if (result<0){free(content); return 0;}
//identify file format //identify file format
static snd_sequence_struct *seq; static snd_sequence_struct *seq;
//OGG? //OGG?
#ifdef DEPENDENCY_AUDIO_DECODE_OGG #ifdef DEPENDENCY_AUDIO_DECODE_OGG
if (lof>=3){ if (lof>=3){
if (content[0]==79){ if (content[1]==103){ if (content[2]==103){//"Ogg" if (content[0]==79){ if (content[1]==103){ if (content[2]==103){//"Ogg"
seq=snd_decode_ogg(content,lof); seq=snd_decode_ogg(content,lof);
goto got_seq; goto got_seq;
}}} }}}
}//3 }//3
#endif #endif
//WAV? //WAV?
#ifdef DEPENDENCY_AUDIO_DECODE_WAV #ifdef DEPENDENCY_AUDIO_DECODE_WAV
if (lof>=12){ if (lof>=12){
if ((*(uint32*)&content[8])==0x45564157){//WAVE if ((*(uint32*)&content[8])==0x45564157){//WAVE
seq=snd_decode_wav(content,lof); seq=snd_decode_wav(content,lof);
goto got_seq; goto got_seq;
}//WAVE }//WAVE
} }
#endif #endif
//assume mp3! //assume mp3!
//MP3? //MP3?
#ifdef DEPENDENCY_AUDIO_DECODE_MP3 #ifdef DEPENDENCY_AUDIO_DECODE_MP3
seq=snd_decode_mp3(content,lof); seq=snd_decode_mp3(content,lof);
#endif #endif
got_seq: got_seq:
free(content); free(content);
if (seq==NULL) return 0; if (seq==NULL) return 0;
//convert sequence (includes sample rate conversion etc etc) //convert sequence (includes sample rate conversion etc etc)
//just perform sample_rate fix for now... //just perform sample_rate fix for now...
//1. 8->16bit conversion and/or edian conversion //1. 8->16bit conversion and/or edian conversion
static int32 incorrect_format; static int32 incorrect_format;
incorrect_format=0; incorrect_format=0;
if (seq->bits_per_sample!=16) incorrect_format=1; if (seq->bits_per_sample!=16) incorrect_format=1;
if (seq->is_unsigned) incorrect_format=1; if (seq->is_unsigned) incorrect_format=1;
//todo... if (seq->endian==???) //todo... if (seq->endian==???)
//this section does not fix the frequency, only the bits per sample //this section does not fix the frequency, only the bits per sample
//and signed-ness of the data //and signed-ness of the data
if (incorrect_format){ if (incorrect_format){
static int32 bps; bps=seq->bits_per_sample/8; static int32 bps; bps=seq->bits_per_sample/8;
static int32 samples; samples=seq->data_size/bps; static int32 samples; samples=seq->data_size/bps;
static uint8 *new_data; static uint8 *new_data;
if (bps!=2){ if (bps!=2){
new_data=(uint8*)malloc(samples*2); new_data=(uint8*)malloc(samples*2);
}else{ }else{
new_data=seq->data; new_data=seq->data;
} }
static int32 i,v; static int32 i,v;
for (i=0;i<samples;i++){ for (i=0;i<samples;i++){
//read original value //read original value
v=0; v=0;
if (bps==1){ if (bps==1){
if (seq->is_unsigned){ if (seq->is_unsigned){
v=*(uint8*)(seq->data+i*1); v=*(uint8*)(seq->data+i*1);
v=(v-128)*256; v=(v-128)*256;
}else{ }else{
v=*(int8*)(seq->data+i*1); v=*(int8*)(seq->data+i*1);
v=v*128; v=v*128;
} }
} }
if (bps==2){ if (bps==2){
if (seq->is_unsigned){ if (seq->is_unsigned){
v=*(uint16*)(seq->data+i*2); v=*(uint16*)(seq->data+i*2);
v=v-32768; v=v-32768;
}else{ }else{
v=*(int16*)(seq->data+i*2); v=*(int16*)(seq->data+i*2);
} }
} }
//place new value into array //place new value into array
((int16*)new_data)[i]=v; ((int16*)new_data)[i]=v;
}//i }//i
if (bps!=2){free(seq->data); seq->data=new_data; seq->data_size=samples*2;} if (bps!=2){free(seq->data); seq->data=new_data; seq->data_size=samples*2;}
//update seq info //update seq info
seq->bits_per_sample=16; seq->bits_per_sample=16;
seq->is_unsigned=0; seq->is_unsigned=0;
}//incorrect format }//incorrect format
//2. samplerate conversion //2. samplerate conversion
if (seq->sample_rate != snd_frequency) { //need to resample seq->data if (seq->sample_rate != snd_frequency) { //need to resample seq->data
//create new resampler //create new resampler
SpeexResamplerState *state; SpeexResamplerState *state;
state = speex_resampler_init(seq->channels, seq->sample_rate, snd_frequency, SPEEX_RESAMPLER_QUALITY_MIN, NULL); state = speex_resampler_init(seq->channels, seq->sample_rate, snd_frequency, SPEEX_RESAMPLER_QUALITY_MIN, NULL);
if (!state) { //NULL means failure if (!state) { //NULL means failure
free(seq->data); free(seq->data);
return 0; return 0;
} }
//allocate new memory for output
int32 out_samples_max = ((double)seq->data_size / seq->channels / 2) * ((((double)snd_frequency) / ((double)seq->sample_rate)) + 0.1) + 100;//10%+100 extra samples as a buffer-zone
int16 *resampled = (int16 *)malloc(out_samples_max * seq->channels * sizeof(int16));
if (!resampled) {
free(seq->data);
return 0;
}
//establish data sizes
//in_len will be set by the resampler to number of samples processed
spx_uint32_t in_len = seq->data_size / seq->channels / 2; // divide by 2 because 2byte samples, divive by #channels because function wants it per-channel
//out_len will be set to the number of samples written
spx_uint32_t out_len;
//resample!
if (speex_resampler_process_interleaved_int(state, (spx_int16_t *)seq->data, &in_len, (spx_int16_t *)resampled, &out_len) != RESAMPLER_ERR_SUCCESS) {
//Error
free(resampled);
free(seq->data);
speex_resampler_destroy(state);
return 0;
}
//destroy the resampler anyway
speex_resampler_destroy(state);
//establish real size of new data and update seq
free(seq->data); //That was the old data
seq->data_size = out_len * seq->channels * 2; //remember out_len is perchannel, and each sample is 2 bytes
seq->data = (uint8_t *)realloc(resampled, seq->data_size); //we overestimated the array size before, so make it the correct size now
if (!seq->data) { //realloc could fail
free(resampled);
return 0;
}
seq->sample_rate = snd_frequency;
}
if (seq->channels==1){ //allocate new memory for output
seq->data_mono=seq->data; int32 out_samples_max = ((double)seq->data_size / seq->channels / 2) * ((((double)snd_frequency) / ((double)seq->sample_rate)) + 0.1) + 100;//10%+100 extra samples as a buffer-zone
seq->data_mono_size=seq->data_size; int16 *resampled = (int16 *)malloc(out_samples_max * seq->channels * sizeof(int16));
} if (!resampled) {
if (seq->channels==2){ free(seq->data);
seq->data_stereo=seq->data; return 0;
seq->data_stereo_size=seq->data_size; }
}
if (seq->channels>2) return 0;
//attach sequence to handle (& inc. refs) //establish data sizes
//create snd handle //in_len will be set by the resampler to number of samples processed
static int32 handle; handle=list_add(snd_handles); spx_uint32_t in_len = seq->data_size / seq->channels / 2; // divide by 2 because 2byte samples, divive by #channels because function wants it per-channel
static snd_struct *snd; snd=(snd_struct*)list_get(snd_handles,handle); //out_len will be set to the number of samples written
spx_uint32_t out_len;
snd->internal=0; //resample!
snd->type=2; if (speex_resampler_process_interleaved_int(state, (spx_int16_t *)seq->data, &in_len, (spx_int16_t *)resampled, &out_len) != RESAMPLER_ERR_SUCCESS) {
snd->seq=seq; //Error
snd->volume=1.0; free(resampled);
snd->capability=r[0]*SND_CAPABILITY_SYNC+r[1]*SND_CAPABILITY_VOL+r[2]*SND_CAPABILITY_PAUSE+r[3]*SND_CAPABILITY_LEN+r[4]*SND_CAPABILITY_SETPOS; free(seq->data);
if (!r[0]){ speex_resampler_destroy(state);
snd->streamed=1;//NOT SYNC return 0;
snd_stream_handle=handle; }
}
return handle; //destroy the resampler anyway
speex_resampler_destroy(state);
//establish real size of new data and update seq
free(seq->data); //That was the old data
seq->data_size = out_len * seq->channels * 2; //remember out_len is perchannel, and each sample is 2 bytes
seq->data = (uint8_t *)realloc(resampled, seq->data_size); //we overestimated the array size before, so make it the correct size now
if (!seq->data) { //realloc could fail
free(resampled);
return 0;
}
seq->sample_rate = snd_frequency;
}
if (seq->channels==1){
seq->data_mono=seq->data;
seq->data_mono_size=seq->data_size;
}
if (seq->channels==2){
seq->data_stereo=seq->data;
seq->data_stereo_size=seq->data_size;
}
if (seq->channels>2) return 0;
//attach sequence to handle (& inc. refs)
//create snd handle
static int32 handle; handle=list_add(snd_handles);
static snd_struct *snd; snd=(snd_struct*)list_get(snd_handles,handle);
snd->internal=0;
snd->type=2;
snd->seq=seq;
snd->volume=1.0;
snd->capability=r[0]*SND_CAPABILITY_SYNC+r[1]*SND_CAPABILITY_VOL+r[2]*SND_CAPABILITY_PAUSE+r[3]*SND_CAPABILITY_LEN+r[4]*SND_CAPABILITY_SETPOS;
if (!r[0]){
snd->streamed=1;//NOT SYNC
snd_stream_handle=handle;
}
return handle;
} }
void sub__sndplayfile(qbs *filename,int32 sync,double volume,int32 passed){ void sub__sndplayfile(qbs *filename,int32 sync,double volume,int32 passed){
if (new_error) return; if (new_error) return;
sndsetup(); sndsetup();
static int32 handle; static int32 handle;
static int32 setvolume; static int32 setvolume;
static qbs *syncstr=NULL; if (!syncstr) syncstr=qbs_new(0,0); static qbs *syncstr=NULL; if (!syncstr) syncstr=qbs_new(0,0);
setvolume=0; setvolume=0;
if (passed&2){ if (passed&2){
if ((volume<0)||(volume>1)){error(5); return;} if ((volume<0)||(volume>1)){error(5); return;}
if (volume!=1) setvolume=1; if (volume!=1) setvolume=1;
} }
if ((!setvolume)&&(!sync)) syncstr->len=0; if ((!setvolume)&&(!sync)) syncstr->len=0;
if ((setvolume)&&(!sync)) qbs_set(syncstr,qbs_new_txt("VOL")); if ((setvolume)&&(!sync)) qbs_set(syncstr,qbs_new_txt("VOL"));
if ((!setvolume)&&(sync)) qbs_set(syncstr,qbs_new_txt("SYNC")); if ((!setvolume)&&(sync)) qbs_set(syncstr,qbs_new_txt("SYNC"));
if ((setvolume)&&(sync)) qbs_set(syncstr,qbs_new_txt("SYNC,VOL")); if ((setvolume)&&(sync)) qbs_set(syncstr,qbs_new_txt("SYNC,VOL"));
if (syncstr->len){ if (syncstr->len){
handle=func__sndopen(filename,syncstr,1); handle=func__sndopen(filename,syncstr,1);
}else{ }else{
handle=func__sndopen(filename,NULL,0); handle=func__sndopen(filename,NULL,0);
} }
if (handle==0) return; if (handle==0) return;
if (setvolume) sub__sndvol(handle,volume); if (setvolume) sub__sndvol(handle,volume);
sub__sndplay(handle); sub__sndplay(handle);
sub__sndclose(handle); sub__sndclose(handle);
} }

File diff suppressed because it is too large Load diff