aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2021-04-18 16:09:30 +0200
committercbdev <cb@cbcdn.com>2021-04-18 16:09:30 +0200
commit9a82789007d626b830f528e476c556e80ff59dcb (patch)
tree99eaa83bdc2bfa14b3fc2ef0b51b15e4ca6a996a
parente4d256218844f21942a4805b100b1bc2b372a1ab (diff)
downloadcswave-9a82789007d626b830f528e476c556e80ff59dcb.tar.gz
cswave-9a82789007d626b830f528e476c556e80ff59dcb.tar.bz2
cswave-9a82789007d626b830f528e476c556e80ff59dcb.zip
Normalize floating point samples
-rw-r--r--Makefile2
-rw-r--r--cswave.c101
2 files changed, 100 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index ed5b4e5..d97a541 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,8 @@ all: cswave cswave.exe
cswave: cswave.c
cswave.exe: export CC = x86_64-w64-mingw32-gcc
+cswave.exe: cswave.c
+ $(CC) $(CFLAGS) $(LDFLAGS) $< $(OBJS) $(LDLIBS) -o $@
clean:
$(RM) *.o
diff --git a/cswave.c b/cswave.c
index 39b9481..c6534e9 100644
--- a/cswave.c
+++ b/cswave.c
@@ -8,8 +8,72 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <math.h>
+
+#ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ #include <winsock2.h>
+ #define PRIsize_t "Iu"
+ #define htole16(x) (x)
+ #define htole32(x) (x)
+#define GETLINE_BUFFER 4096
+
+//getline implementation from midimonster / https://github.com/cbdevnet/midimonster
+static ssize_t getline(char** line, size_t* alloc, FILE* stream){
+ size_t bytes_read = 0;
+ char c;
+ //sanity checks
+ if(!line || !alloc || !stream){
+ return -1;
+ }
+
+ //allocate buffer if none provided
+ if(!*line || !*alloc){
+ *alloc = GETLINE_BUFFER;
+ *line = calloc(GETLINE_BUFFER, sizeof(char));
+ if(!*line){
+ fprintf(stderr, "Failed to allocate memory\n");
+ return -1;
+ }
+ }
+
+ if(feof(stream)){
+ return -1;
+ }
+
+ for(c = fgetc(stream); 1; c = fgetc(stream)){
+ //end of buffer, resize
+ if(bytes_read == (*alloc) - 1){
+ *alloc += GETLINE_BUFFER;
+ *line = realloc(*line, (*alloc) * sizeof(char));
+ if(!*line){
+ fprintf(stderr, "Failed to allocate memory\n");
+ return -1;
+ }
+ }
-#define PRIsize_t "lu"
+ //store character
+ (*line)[bytes_read] = c;
+
+ //end of line
+ if(feof(stream) || c == '\n'){
+ //terminate string
+ (*line)[bytes_read + 1] = 0;
+ return bytes_read;
+ }
+
+ //input broken
+ if(ferror(stream)){
+ return -1;
+ }
+
+ bytes_read++;
+ }
+}
+#else
+ #define PRIsize_t "lu"
+#endif
typedef enum {
fmt_i8,
@@ -152,6 +216,25 @@ static size_t process(FILE* src, size_t column, sample_format fmt, int dst){
return samples;
}
+static float* float_reference(int fd, size_t samples){
+ float* data = calloc(samples, sizeof(float)), max = 0;
+ size_t n = 0;
+
+ for(n = 0; n < samples; n++){
+ read(fd, data + n, 4);
+ if(fabsf(data[n]) > fabsf(max)){
+ max = data[n];
+ }
+ }
+
+ fprintf(stdout, "Determined maximum sample value as %f\n", max);
+
+ for(n = 0; n < samples; n++){
+ data[n] /= fabsf(max);
+ }
+ return data;
+}
+
static void write_headers(int fd, sample_format fmt, size_t samples, size_t samplerate){
hdr_riff_t riff_hdr = {
.magic_riff = "RIFF",
@@ -208,7 +291,7 @@ int main(int argc, char** argv){
return EXIT_FAILURE;
}
- int output_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ int output_fd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if(output_fd < 0){
fprintf(stderr, "Failed to open output file %s\n", argv[2]);
close(output_fd);
@@ -223,7 +306,19 @@ int main(int argc, char** argv){
lseek(output_fd, 0, SEEK_SET);
write_headers(output_fd, fmt, samples, strtoul(argv[4], NULL, 10));
- //TODO normalize floats
+
+ //floating point pcm needs to be normalized...
+ if(fmt == fmt_f32){
+ float* normalized = float_reference(output_fd, samples);
+ lseek(output_fd, 0, SEEK_SET);
+ write_headers(output_fd, fmt, samples, strtoul(argv[4], NULL, 10));
+ for(size_t n = 0; n < samples; n++){
+ write(output_fd, normalized + n, 4);
+ //fprintf(stdout, "Normalized sample %f\n", normalized[n]);
+ }
+ free(normalized);
+ }
+
close(output_fd);
return EXIT_SUCCESS;
}