diff --git a/source/dsp/SofaReader.h b/source/dsp/SofaReader.h index c590ff4..6165f69 100644 --- a/source/dsp/SofaReader.h +++ b/source/dsp/SofaReader.h @@ -23,19 +23,91 @@ class SofaReader { break; case SAF_SOFA_ERROR_INVALID_FILE_OR_FILE_PATH: std::cout << "Not a SOFA file, or no such file was found in the specified location" << std::endl; - break; + return; case SAF_SOFA_ERROR_DIMENSIONS_UNEXPECTED: std::cout << "Dimensions of the SOFA data were not as expected" << std::endl; - break; + return; case SAF_SOFA_ERROR_FORMAT_UNEXPECTED: std::cout << "The data-type of the SOFA data was not as expected" << std::endl; - break; + return; case SAF_SOFA_ERROR_NETCDF_IN_USE: std::cout << "NetCDF is not thread safe!" << std::endl; - break; + return; + } + + // + int azimuthStep = 30; + int elevationStep = 30; + int minElevation = -30; + int numElevationSteps = 5; + + int azimuth1 = 90, elevation1 = 45; + + // Calculate source indices + int indexTest = calculateSourceIndex(azimuth1, elevation1, azimuthStep, elevationStep, minElevation, numElevationSteps); + + // Print results + printf("Source index for azimuth %d, elevation %d: %d\n", azimuth1, elevation1, indexTest); + + int leftEarIndex = 0; + int rightEarIndex = 1; + + auto hrtfLeft = accessHRTF(&sofa, indexTest, leftEarIndex); + auto hrtfRight = accessHRTF(&sofa, indexTest, rightEarIndex); + + std::cout << "Successfully loaded HRTF" << std::endl; + + writeHRTFToWav(hrtfLeft, hrtfRight, "HRTF_Output.wav"); + } + + // Function to calculate the source index for a given azimuth and elevation + int calculateSourceIndex(int azimuth, int elevation, int azimuthStep, int elevationStep, int minElevation, int numElevationSteps) { + int azimuthIndex = azimuth / azimuthStep; + int elevationIndex = (elevation - minElevation) / elevationStep; + return azimuthIndex * numElevationSteps + elevationIndex; + } + + int getSourceReceiverIndex(int sourceIndex, int receiverIndex, saf_sofa_container *sofaToUse) { + return (sourceIndex * sofaToUse->nReceivers + receiverIndex) * sofaToUse->DataLengthIR; + } + + // not real-time safe!! + std::vector accessHRTF(saf_sofa_container *sofaToUse, int sourceIndex, int receiverIndex) { + int index = getSourceReceiverIndex(sourceIndex, receiverIndex, sofaToUse); + std::vector hrtf(sofaToUse->DataLengthIR); + memcpy(hrtf.data(), &sofaToUse->DataIR[index], sizeof(float) * sofaToUse->DataLengthIR); + return hrtf; + } + + void writeHRTFToWav(const std::vector& hrtfLeft, const std::vector& hrtfRight, const String& fileName) { + File file(File::getCurrentWorkingDirectory().getChildFile(fileName)); + file.deleteFile(); + + std::unique_ptr fileStream(file.createOutputStream()); + if (!fileStream) { + std::cout << "Failed to create file stream!" << std::endl; + return; + } + + WavAudioFormat wavFormat; + std::unique_ptr writer; + writer.reset(wavFormat.createWriterFor(fileStream.get(), sofa.DataSamplingRate, + 2, 16, {}, 0)); + if (writer == nullptr) { + std::cout << "Failed to create audio writer!" << std::endl; + return; } + juce::AudioBuffer buffer(2, (int) hrtfLeft.size()); + buffer.copyFrom(0, 0, hrtfLeft.data(), (int) hrtfLeft.size()); + buffer.copyFrom(1, 0, hrtfRight.data(), (int) hrtfRight.size()); + + writer->writeFromAudioSampleBuffer(buffer, 0, buffer.getNumSamples()); + fileStream->flush(); + + std::cout << "HRTF data written to " << file.getFullPathName() << std::endl; + fileStream.release(); } private: