void Buffer::loadFromArray(int sr, int channels, int frames, float* inputData) { int simulationSr= (int)simulation->getSr(); staticResamplerKernel(sr, simulationSr, channels, frames, inputData, &(this->frames), &data); if(data==nullptr) ERROR(Lav_ERROR_MEMORY); this->channels = channels; if(this->channels == 1) return; //It's already uninterleaved. //Uninterleave the data and delete the old one. float* newData = new float[this->channels*this->frames]; for(int ch = 0; ch < this->channels; ch++) { for(int i = 0; i < this->frames; i++) { newData[ch*this->frames+i] = data[this->channels*i+ch]; } } delete[] data; data = newData; }
void HrtfData::loadFromBuffer(unsigned int length, char* buffer, unsigned int forSr) { //we now handle endianness. int32_t endianness_marker =convi(buffer); if(endianness_marker != 1) reverse_endianness(buffer, length, 4); //read it again; if it is still not 1, something has gone badly wrong. endianness_marker = convi(buffer); if(endianness_marker != 1) ERROR(Lav_ERROR_HRTF_INVALID, "Could not correct endianness for this architecture."); char* iterator = buffer; const unsigned int window_size = 4; //read the header information. iterator += window_size;//skip the endianness marker, which is handled above. samplerate = convi(iterator); iterator += window_size; hrir_count = convi(iterator); iterator += window_size; elev_count = convi(iterator); iterator += window_size; min_elevation = convi(iterator); iterator += window_size; max_elevation = convi(iterator); iterator += window_size; //this is the first "dynamic" piece of information. azimuth_counts = new int[elev_count]; for(int i = 0; i < elev_count; i++) { azimuth_counts[i] = convi(iterator); iterator += window_size; } //sanity check: we must have as many hrirs as the sum of the above array. int32_t sum_sanity_check = 0; for(int i = 0; i < elev_count; i++) sum_sanity_check +=azimuth_counts[i]; if(sum_sanity_check != hrir_count) ERROR(Lav_ERROR_HRTF_INVALID, "Not enough or too many responses."); int before_hrir_length = convi(iterator); iterator += window_size; unsigned int length_so_far = iterator-buffer; size_t size_remaining = length-length_so_far; //we must have enough remaining to be all hrir hrirs. size_t hrir_size = before_hrir_length*hrir_count*sizeof(float); if(hrir_size != size_remaining) ERROR(Lav_ERROR_HRTF_INVALID, "Not enough HRIR data."); //last step. Initialize the HRIR array. hrirs = new float**[elev_count]; //do the azimuth dimension. for(int i = 0; i < elev_count; i++) { hrirs[i] = new float*[azimuth_counts[i]]; } //the above gives us what amounts to a 2d array. The first dimension represents elevation. The second dimension represents azimuth going clockwise. //fill it. float* tempBuffer = allocArray<float>(before_hrir_length); int final_hrir_length = 0; for(int elev = 0; elev < elev_count; elev++) { for(int azimuth = 0; azimuth < azimuth_counts[elev]; azimuth++) { memcpy(tempBuffer, iterator, sizeof(float)*before_hrir_length); staticResamplerKernel(samplerate, forSr, 1, before_hrir_length, tempBuffer, &final_hrir_length, &hrirs[elev][azimuth]); iterator+=before_hrir_length*sizeof(float); } } hrir_length = final_hrir_length; samplerate = forSr; freeArray(tempBuffer); if(temporary_buffer1) freeArray(temporary_buffer1); if(temporary_buffer2) freeArray(temporary_buffer2); temporary_buffer1 = allocArray<float>(hrir_length); temporary_buffer2 = allocArray<float>(hrir_length); //stuff for linear phase filters. fft_time_data = allocArray<float>(hrir_length*2); fft_data = allocArray<kiss_fft_cpx>(hrir_length+1); //half the bins, plus dc. fft = kiss_fftr_alloc(hrir_length*2, 0, nullptr, nullptr); ifft = kiss_fftr_alloc(hrir_length*2, 1, nullptr, nullptr); }