mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
160 lines
5.3 KiB
C
160 lines
5.3 KiB
C
/*---------------------------------------------------------------------------*\
|
|
|
|
FILE........: resample.c
|
|
AUTHOR......: David Rowe
|
|
DATE CREATED: 5/3/2016
|
|
|
|
Resamples a stream of 16 bit shorts.
|
|
|
|
$ gcc resample.c -o resample -lm -lsamplerate -Wall
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*
|
|
Copyright (C) 2016 David Rowe
|
|
|
|
All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License version 2.1, as
|
|
published by the Free Software Foundation. This program is
|
|
distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#define BUF_PERIOD 0.02 /* length of processingbuffer in seconds */
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <samplerate.h>
|
|
|
|
/* returns number of output samples generated by resampling */
|
|
|
|
int resample(SRC_STATE *src,
|
|
short output_short[],
|
|
short input_short[],
|
|
int output_sample_rate,
|
|
int input_sample_rate,
|
|
int length_output_short, /* maximum output array length in samples */
|
|
int length_input_short,
|
|
int *input_samples_used,
|
|
int last
|
|
)
|
|
{
|
|
SRC_DATA src_data;
|
|
float input[length_input_short];
|
|
float output[length_output_short];
|
|
int ret;
|
|
|
|
assert(src != NULL);
|
|
|
|
src_short_to_float_array(input_short, input, length_input_short);
|
|
|
|
src_data.data_in = input;
|
|
src_data.data_out = output;
|
|
src_data.input_frames = length_input_short;
|
|
src_data.output_frames = length_output_short;
|
|
src_data.end_of_input = last;
|
|
src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
|
|
//printf("ratio: %f\n", src_data.src_ratio);
|
|
|
|
ret = src_process(src, &src_data);
|
|
assert(ret == 0);
|
|
|
|
assert(src_data.output_frames_gen <= length_output_short);
|
|
src_float_to_short_array(output, output_short, src_data.output_frames_gen);
|
|
|
|
*input_samples_used = src_data.input_frames_used;
|
|
return src_data.output_frames_gen;
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
FILE *fin, *fout;
|
|
SRC_STATE *src;
|
|
int FsIn, FsOut;
|
|
int length_input_short, length_output_short;
|
|
int src_error, nin, left_over, nread;
|
|
|
|
if (argc < 5) {
|
|
printf("usage: resample FsIn FsOut InputFileOfShorts OutputFileOfShortsn");
|
|
printf("e.g resample 1E6 1E5 Fs1E6HzInputShortFile.raw Fs1E5HzOutputShortFile.raw\n");
|
|
printf("e.g SampleGenerator | resample 1E6 1E5 | SampleConsumer\n");
|
|
exit(1);
|
|
}
|
|
|
|
FsIn = (int)atof(argv[1]);
|
|
FsOut = (int)atof(argv[2]);
|
|
|
|
length_input_short = BUF_PERIOD*FsIn;
|
|
length_output_short = BUF_PERIOD*FsOut;
|
|
//printf("FsIn: %d FsOut: %d length_input_short: %d length_output_short: %d\n",
|
|
// FsIn, FsOut, length_input_short, length_output_short);
|
|
|
|
short input_short[length_input_short];
|
|
short output_short[length_output_short];
|
|
|
|
if (strcmp(argv[3], "-") == 0) fin = stdin;
|
|
else if ( (fin = fopen(argv[3],"rb")) == NULL ) {
|
|
fprintf(stderr, "Error opening input speech file: %s: %s.\n",
|
|
argv[2], strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
if (strcmp(argv[4], "-") == 0) fout = stdout;
|
|
else if ( (fout = fopen(argv[4],"wb")) == NULL ) {
|
|
fprintf(stderr, "Error opening output speech file: %s: %s.\n",
|
|
argv[3], strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
src = src_new(SRC_SINC_FASTEST, 1, &src_error);
|
|
assert(src != NULL);
|
|
|
|
nin = length_input_short;
|
|
left_over = 0;
|
|
while((nread = fread(&input_short[left_over], sizeof(short), nin, fin)) == nin) {
|
|
length_output_short = resample(src,
|
|
output_short,
|
|
input_short,
|
|
FsOut,
|
|
FsIn,
|
|
length_output_short,
|
|
length_input_short,
|
|
&nin,
|
|
0);
|
|
left_over = length_input_short - nin;
|
|
memcpy(input_short, &input_short[nin], left_over);
|
|
//printf("length_output_short: %d length_input_short: %d nin: %d left_over: %d\n",
|
|
// length_output_short, length_input_short, nin, left_over);
|
|
fwrite(output_short, sizeof(short), length_output_short, fout);
|
|
}
|
|
|
|
length_output_short = resample(src,
|
|
output_short,
|
|
input_short,
|
|
FsOut,
|
|
FsIn,
|
|
length_output_short,
|
|
length_input_short,
|
|
&nin,
|
|
1);
|
|
fwrite(output_short, sizeof(short), length_output_short, fout);
|
|
|
|
fclose(fin);
|
|
fclose(fout);
|
|
|
|
src_delete(src);
|
|
|
|
return 0;
|
|
}
|