Implemented distance matrix and used openmp to scale accross cores

This commit is contained in:
2026-02-10 03:18:14 -06:00
parent 2f86f5fd99
commit 39f3513241
2 changed files with 97 additions and 19 deletions

View File

@@ -6,7 +6,9 @@ Spectogramspectrogram
`for %f in (*.wav) do ffmpeg -y -i "%f" -ar 44100 -lavfi "showspectrumpic=s=256x256:scale=log:legend=0" "img\%~nf.png"` `for %f in (*.wav) do ffmpeg -y -i "%f" -ar 44100 -lavfi "showspectrumpic=s=256x256:scale=log:legend=0" "img\%~nf.png"`
With loudnorm to try to improve performance With loudnorm to try to improve performance by normalizing loudness
<sup> Seems to work much better
`for %f in (*.wav) do ffmpeg -y -i "%f" -ar 44100 -lavfi "loudnorm,showspectrumpic=s=256x256:scale=log:legend=0" "img\%~nf.png"` `for %f in (*.wav) do ffmpeg -y -i "%f" -ar 44100 -lavfi "loudnorm,showspectrumpic=s=256x256:scale=log:legend=0" "img\%~nf.png"`
@@ -14,7 +16,7 @@ With loudnorm to try to improve performance
Used for gathering the image data Used for gathering the image data
## Building ## Building
`clang src/main.c -Iexternal -O2 -o soundknn.exe` `clang src/main.c -Iexternal -O3 -fopenmp -march=native -o soundknn.exe`
### Todo ### Todo
- [x] Load all images from directory - [x] Load all images from directory

View File

@@ -2,6 +2,8 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <windows.h> #include <windows.h>
#include <time.h>
#include <omp.h>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
@@ -25,8 +27,69 @@ float EuclideanDistance(AudioData *im1,AudioData *im2){
distance += d * d; distance += d * d;
} }
// Leaving out sqrt to save compute as it doesn't change distance rankings
// distance=sqrtf(distance);
return distance;
}
return sqrtf(distance); void computeDistanceMatrix(AudioData *audioData, float **distanceArrays,int nfiles, int counter){
// Computes distance matrix for all images
int matrixSize=nfiles*nfiles;
unsigned int computeCounter=0;
for(int i = 0; i < counter; i++){
for(int j = 0; j < counter; j++){
float d = EuclideanDistance(&audioData[i], &audioData[j]);
distanceArrays[i][j] = d;
computeCounter++;
}
// printf("Way through matrix compute: %d\n",(computeCounter/matrixSize)*100);
printf("\rWay through matrix compute: %.2f%%",(computeCounter/(float)matrixSize)*100);
fflush(stdout);
}
printf("\n");
}
void computeDistanceMatrixOMP(AudioData *audioData, float **distanceArrays,int nfiles, int counter){
// Computes distance matrix for all images
int matrixSize=2000*2000;
unsigned int computeCounter=0;
// Uses openmp to use all threads for this
#pragma omp parallel for schedule(static)
for(int i = 0; i < counter; i++){
for(int j = 0; j < counter; j++){
float d = EuclideanDistance(&audioData[i], &audioData[j]);
distanceArrays[i][j] = d;
#pragma omp atomic
computeCounter++;
}
#pragma omp critical
{
printf("\rWay through matrix compute: %.2f%%",(computeCounter/(float)matrixSize)*100);
fflush(stdout);
}
}
printf("\n");
}
int getAmountOfFiles(){
HANDLE myHandle;
WIN32_FIND_DATA FindFileData;
const char* directory="esc-50-audio/img/*.png";
int x,y;
int counter=0;
// Getting first file out of the loop
myHandle=FindFirstFileA(directory,&FindFileData);
counter++;
while(FindNextFileA(myHandle,&FindFileData)){
counter++;
}
// Closing windows handler
FindClose(myHandle);
return counter;
} }
int main(){ int main(){
@@ -36,7 +99,9 @@ int main(){
const char* directory="esc-50-audio/img/*.png"; const char* directory="esc-50-audio/img/*.png";
int x,y; int x,y;
struct AudioData audioData[2000]; int nfiles=getAmountOfFiles();
// Allocating on the heap to account for unknown number of images
struct AudioData *audioData = malloc(sizeof(struct AudioData) * nfiles);
// Getting first file out of the loop // Getting first file out of the loop
myHandle=FindFirstFileA(directory,&FindFileData); myHandle=FindFirstFileA(directory,&FindFileData);
@@ -48,7 +113,7 @@ int main(){
int counter=1; int counter=1;
// Gets all other files // Gets all other files
while(FindNextFileA(myHandle,&FindFileData)&& counter<2000){ while(FindNextFileA(myHandle,&FindFileData)&& counter<nfiles){
// printf("%s\n",FindFileData.cFileName); // printf("%s\n",FindFileData.cFileName);
snprintf(path, MAX_PATH, "esc-50-audio/img/%s", FindFileData.cFileName); snprintf(path, MAX_PATH, "esc-50-audio/img/%s", FindFileData.cFileName);
audioData[counter].data = stbi_load(path, &x, &y, NULL, 1); audioData[counter].data = stbi_load(path, &x, &y, NULL, 1);
@@ -58,13 +123,18 @@ int main(){
// Closing windows handler // Closing windows handler
FindClose(myHandle); FindClose(myHandle);
float *distanceArrays[2000]; float **distanceArrays = malloc(nfiles * sizeof(float*));
for(int i=0;i<2000;i++){
distanceArrays[i]=calloc(2000,sizeof(float)); for(int i=0;i<nfiles;i++){
distanceArrays[i]=calloc(nfiles,sizeof(float));
} }
time_t now = time(NULL);
computeDistanceMatrixOMP(audioData, distanceArrays,nfiles, counter);
printf("Time it took to compute matrix: %lld\n seconds",time(NULL)-now);
// Searches for index of specific image // Searches for index of specific image
char img[]="esc-50-audio/img/1-32318-A-0.png"; char img[]="esc-50-audio/img/4-189838-A-22.png";
int fileindex; int fileindex;
for(int i=0;i<counter;i++){ for(int i=0;i<counter;i++){
if(strcmp(img,audioData[i].fileName)==0){ if(strcmp(img,audioData[i].fileName)==0){
@@ -72,19 +142,22 @@ int main(){
break; break;
} }
} }
float distance=EuclideanDistance(&audioData[fileindex],&audioData[0]);
int closest=fileindex; int closest = -1;
float best = INFINITY;
for (int i = 0; i < counter; i++) { for (int i = 0; i < counter; i++) {
if(strcmp(img,audioData[i].fileName)!=0){ if (i != fileindex){
float newdistance=EuclideanDistance(&audioData[fileindex],&audioData[i]); // use matrix to find value
if(newdistance<distance){ float d = distanceArrays[fileindex][i];
if (d < best) {
best = d;
closest = i; closest = i;
distance=newdistance; }
} }
} }
} printf("Original: %s\n",img);
printf("Closest: %s",audioData[closest].fileName); printf("Closest: %s",audioData[closest].fileName);
// Freeing the memory of images // Freeing the memory of images
@@ -97,5 +170,8 @@ int main(){
for(int i=0;i<2000;i++){ for(int i=0;i<2000;i++){
free(distanceArrays[i]); free(distanceArrays[i]);
} }
free(distanceArrays);
free(audioData);
return 0; return 0;
} }