Add a simple test application for running the filtering stages on a PC.
This commit is contained in:
parent
e6ece89049
commit
aad64a9b7d
|
@ -0,0 +1,25 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(ploopy_headphones_project C CXX ASM)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_executable(filter_test
|
||||
filter_test.c
|
||||
../code/fix16.c
|
||||
../code/bqf.c
|
||||
../code/user.c
|
||||
)
|
||||
|
||||
target_include_directories(filter_test PRIVATE ${CMAKE_SOURCE_DIR}/../code)
|
||||
|
||||
# TODO: user.c includes run.h to get the definition for SAMPLING_FREQ, but this
|
||||
# pulls in the whole pico sdk as a dependency. A little refactoring would fix it all.
|
||||
target_compile_definitions(filter_test PRIVATE
|
||||
SAMPLING_FREQ=48000
|
||||
RUN_H
|
||||
)
|
||||
|
||||
target_link_libraries(filter_test
|
||||
m
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
## filter_test
|
||||
This is a basic utility for testing the Ploopy headphones filtering routines on a PC.
|
||||
|
||||
### Usage
|
||||
Find a source file and use ffmpeg to convert it to PCM data:
|
||||
|
||||
```
|
||||
ffmpeg -i <input file< -map 0:6 -vn -f s16le -acodec pcm_s16le input.pcm
|
||||
```
|
||||
|
||||
Run `filter_test` to process the PCM data. The `filter_test` program takes two arguments an input file and an output file:
|
||||
|
||||
```
|
||||
./filter_test input.pcm output.pcm
|
||||
```
|
||||
|
||||
You can listen to the output audio using ffplay (which is usually included with ffmpeg:
|
||||
|
||||
```
|
||||
./ffplay -f s16le -ar 48000 -ac 2 output.pcm
|
||||
```
|
||||
|
||||
If there are no obvious problems, go ahead and flash your firmware.
|
|
@ -0,0 +1,91 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bqf.h"
|
||||
#include "fix16.h"
|
||||
#include "user.h"
|
||||
|
||||
bqf_coeff_t bqf_filters_left[FILTER_STAGES];
|
||||
bqf_coeff_t bqf_filters_right[FILTER_STAGES];
|
||||
bqf_mem_t bqf_filters_mem_left[FILTER_STAGES];
|
||||
bqf_mem_t bqf_filters_mem_right[FILTER_STAGES];
|
||||
|
||||
const char* usage = "Usage: %s INFILE OUTFILE\n\n"
|
||||
"Reads 16bit stereo PCM data from INFILE, runs it through the Ploopy headphones\n"
|
||||
"filters then writes it out to OUTFILE.\n";
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stdout, usage, argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Load the input data into a buffer
|
||||
FILE* input = fopen(argv[1], "rb");
|
||||
if (!input) {
|
||||
fprintf(stderr, "Cannot open input file '%s'\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
fseek(input , 0L , SEEK_END);
|
||||
size_t input_size = ftell(input);
|
||||
rewind(input);
|
||||
|
||||
// Allocate our input and output buffers. This could be optimized
|
||||
// we dont need to store the whole input and output files in memory.
|
||||
int samples = input_size / 2;
|
||||
int16_t *in = (int16_t *) calloc(samples, sizeof(int16_t));
|
||||
int16_t *out = (int16_t *) calloc(samples, sizeof(int16_t));
|
||||
|
||||
fread(in, samples, sizeof(int16_t), input);
|
||||
fclose(input);
|
||||
|
||||
// Open the output file.
|
||||
FILE* output = fopen(argv[2], "wb");
|
||||
if (!output)
|
||||
{
|
||||
fprintf(stderr, "Cannot open output file '%s'\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// The smaple proccesing code, essentially the same as the
|
||||
// code in the firmware's run.c file.
|
||||
define_filters();
|
||||
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
out[i] = in[i];
|
||||
}
|
||||
|
||||
for (int j = 0; j < FILTER_STAGES; j++)
|
||||
{
|
||||
for (int i = 0; i < samples; i ++)
|
||||
{
|
||||
// Left channel filter
|
||||
fix16_t x_f16 = fix16_from_int((int16_t) out[i]);
|
||||
|
||||
x_f16 = bqf_transform(x_f16, &bqf_filters_left[j],
|
||||
&bqf_filters_mem_left[j]);
|
||||
|
||||
out[i] = (int32_t) fix16_to_int(x_f16);
|
||||
|
||||
// Right channel filter
|
||||
i++;
|
||||
x_f16 = fix16_from_int((int16_t) out[i]);
|
||||
|
||||
x_f16 = bqf_transform(x_f16, &bqf_filters_right[j],
|
||||
&bqf_filters_mem_right[j]);
|
||||
|
||||
out[i] = (int16_t) fix16_to_int(x_f16);
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the processed audio.
|
||||
fwrite(out, samples, sizeof(int16_t), output);
|
||||
fclose(output);
|
||||
|
||||
free(in);
|
||||
free(out);
|
||||
}
|
Loading…
Reference in New Issue