123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #include <stdio.h>
- #include <string.h>
- #include <sndfile.h>
- #include <speex/speex_echo.h>
- #include <speex/speex_preprocess.h>
- #include <speex/speex_resampler.h>
- #include "wavtool.h"
- #define AGC_DEFAULT_TARGET 8000
- #define AGC_DEFAULT_MAX_GAIN 12
- #define AGC_DEFAULT_DECREMENT -60
- WavTool::WavTool(){}
- SpeexPreprocessState* preproc_create(int samplerate)
- {
- SpeexPreprocessState* preproc = speex_preprocess_state_init(128, samplerate);
- // Enable AGC
- int val = 1;
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_AGC, &val);
- // Disable other
- val = 0;
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_DENOISE, &val);
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_DEREVERB, &val);
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_VAD, &val);
- val = AGC_DEFAULT_TARGET; // 8000 ~24% -- Default: 8000 ~24%
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_AGC_TARGET, &val);
- val = AGC_DEFAULT_MAX_GAIN; // +12dB -- Default 30dB
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &val);
- val = AGC_DEFAULT_DECREMENT; // -60dB per second -- Default -40dB
- speex_preprocess_ctl(preproc, SPEEX_PREPROCESS_SET_AGC_DECREMENT, &val);
- return preproc;
- }
- void WavTool::addNote(const char* infilename, float start,float length)
- {
- SF_INFO info;
- memset(&info,0,sizeof(info));
- SNDFILE* infile = sf_open(infilename,SFM_READ,&info);
- SpeexPreprocessState* preproc = preproc_create(info.samplerate);
- SpeexResamplerState *resampler = nullptr;
- wavdata* ret=new wavdata;
- ret->start=start;
- ret->length=length;
- int err=0;
- if(info.samplerate != _outputRate)
- resampler = speex_resampler_init(1, info.samplerate, _outputRate, 10, &err);
- //info.samplerate = output_rate;
- //SNDFILE* outfile = sf_open(outfilename,SFM_WRITE,&info);
- short data[128];
- short data2[1024];
- //store wav data
- while(1)
- {
- int count = sf_read_short(infile,data,128);
- speex_preprocess_run(preproc, data);
- for(int i=0;i<128;i++) data[i]*=0.9;
- int data2_length = 1024;
- if(resampler) {
- speex_resampler_process_int(resampler,0,data,(spx_uint32_t*)&count,data2,(spx_uint32_t*)&data2_length);
- for(int i=0;i<data2_length;i++) ret->data.push_back(data2[i]*1.0/32768);
- }
- if(count<128) break;
- }
- speex_preprocess_state_destroy(preproc);
- sf_close(infile);
- if(resampler) speex_resampler_destroy(resampler);
- _notes.push_back(ret);
- }
- void WavTool::mix()
- {
- float songLength = _notes[_notes.size()-1]->start + _notes[_notes.size()-1]->length;
- _outdataLength = _outputRate*songLength;
- _outdata = new float[_outdataLength];
- for(int i=0;i<(int)_notes.size();i++)
- {
- float start = _notes[i]->start;
- float end = start+_notes[i]->length;
- int startix = _outputRate*start;
- int endix = _outputRate*end;
- int count = endix-startix;
- //fprintf(stderr,"%i %i\n",startix,endix);
- for(int j=0;j<count;j++)
- {
- int index = j+startix;
- if(index>0 && index<_outdataLength && j<_notes[i]->data.size()) _outdata[index]+=_notes[i]->data[j];
- }
- }
- SF_INFO info;
- memset(&info,0,sizeof(info));
- info.channels=1;
- info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
- info.samplerate = _outputRate;
- SNDFILE* sf= sf_open("/tmp/wavtool.wav",SFM_WRITE,&info);
- sf_write_float(sf,_outdata,_outdataLength);
- sf_close(sf);
- //fprintf(stderr,"songLength %f\n",songLength);
- }
- void WavTool::clear()
- {
- _notes.clear();
- //TODO: delete memory
- }
|