Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}