#include <stdio.h>
 
 
#include <sp/sfconv.h>
 
 
static spResampleConfig resample_config;
 
static double o_samp_freq;
 
static double gain;
static char output_file[SP_MAX_PATHNAME] = "";
static char *plugin_search_path;
static char o_plugin_name[SP_MAX_LINE] = "";
 
static int debug_level = -1;
 
    {"-osf", NULL, "output sampling frequency [Hz]", "o_samp_freq",
         SP_TYPE_DOUBLE, &o_samp_freq, "12000.0"},
    {"-fftl", NULL, "minimum FFT length [points]", "fft_length", 
         SP_TYPE_LONG, &resample_config.
max_input_buf_length, 
"512"},
    {"-co", "-cutoff", "normalized cutoff frequency (nyquist = 1)", "cutoff", 
         SP_TYPE_DOUBLE, &resample_config.
cutoff, 
"0.95"},
    {"-sl", "-sidelobe", "height of sidelobe [dB]", "sidelobe", 
         SP_TYPE_DOUBLE, &resample_config.
sidelobe, 
"60.0"},
    {"-trans", "-transition", "normalized transition width", "transition", 
         SP_TYPE_DOUBLE, &resample_config.
transition, 
"0.05"},
    {"-tol", "-tolerance", "tolerance [%]", "tolerance", 
         SP_TYPE_DOUBLE, &resample_config.
tolerance, 
"2.0"},
    {"-g", "-gain", "gain for output data", "gain",
         SP_TYPE_DOUBLE, &gain, "1.0"},
    {"-O", "-output", "output file (default format: wav)", NULL,
         SP_TYPE_STRING_A, output_file, NULL},
    {"-op", "-oplugin", "plugin name for output", "output_plugin",
         SP_TYPE_STRING_A, o_plugin_name, NULL},
    {"-path", NULL, "plugin search path", "plugin_path",
         SP_TYPE_STRING, &plugin_search_path, NULL},
    {"-debug", NULL, "debug level", NULL,
         SP_TYPE_INT, &debug_level, NULL},
    {"-h", "-help", "display this message", NULL,
};
 
static char *filelabel[] = {
    "<input file>",
};
    
int spMain(int argc, char *argv[])
{
    const char *input_file;
            
    spResampleInitConfig(&resample_config);
    
    
 
    spDebug(1, 
"main", 
"input_file = %s\n", input_file);
 
 
    spInitWaveInfo(&i_wave_info);
 
    if ((i_plugin = spOpenFilePluginArg(NULL, input_file, "r",
                                      &i_wave_info, NULL, 0, NULL, NULL)) != NULL) {
            strcpy(o_plugin_name, "output_audio");
        } else {
            spDebug(1, 
"main", 
"output_file = %s\n", output_file);
 
        }
        spDebug(1, 
"main", 
"o_plugin_name = %s\n", o_plugin_name);
 
 
        spCopyWaveInfo(&o_wave_info, &i_wave_info);
        o_wave_info.samp_rate = o_samp_freq;
            
        if ((o_plugin = spOpenFilePluginArg(o_plugin_name, output_file, "w",
                                            device_type,
                                            &o_wave_info, NULL, 0, NULL, NULL)) != NULL) {
            spResampleRec resample;
            long max_output_buf_length;
            long orig_input_buf_length;
            long read_length;
            long write_length;
            long output_buf_length;
            long delay;
            unsigned long total_read;
            unsigned long total_write;
            double new_samp_freq;
            double *input_buf, *output_buf;
 
            spDebug(1, 
"main", 
"samp_rate = %f\n", o_wave_info.samp_rate);
 
 
            resample_config.
num_channel = i_wave_info.num_channel;
            resample_config.
options |= SP_RESAMPLE_OPTION_INPUT_INTERLEAVED;
            resample_config.options |= SP_RESAMPLE_OPTION_OUTPUT_INTERLEAVED;
            resample_config.options |= SP_RESAMPLE_OPTION_TRUNCATE_EDGE;
            
            if ((resample = spResampleOpen(&resample_config)) != NULL) {
                orig_input_buf_length = resample_config.max_input_buf_length;
                
                if ((new_samp_freq = spResampleSetFrequency(resample, i_wave_info.samp_rate, o_wave_info.samp_rate,
                                                            &max_output_buf_length, &delay)) > 0.0) {
                    spMessage(
"New Sampling Frequency: %f\n", new_samp_freq);
 
                    spDebug(1, 
"main", 
"orig_input_buf_length = %ld, max_output_buf_length = %ld, delay = %ld\n",
 
                            orig_input_buf_length, max_output_buf_length, delay);
 
                    input_buf = 
xspAlloc(orig_input_buf_length, 
double);
                    output_buf = 
xspAlloc(max_output_buf_length, 
double);
 
                    total_read = total_write = 0;
 
                    while (1) {
                        read_length = spReadPluginDouble(i_plugin, input_buf, orig_input_buf_length);
                        spDebug(1, 
"main", 
"read_length = %ld\n", read_length);
 
                        
                        if (read_length <= 0) {
                            output_buf_length = spResampleFlush(resample, output_buf);
                            spDebug(1, 
"main", 
"resample flushed: output_buf_length = %ld\n", output_buf_length);
 
                        } else {
                            total_read += read_length;
                            output_buf_length = spResampleProcess(resample, input_buf, read_length, output_buf, &delay);
                            spDebug(1, 
"main", 
"read_length = %ld, output_buf_length = %ld, delay = %ld\n",
 
                                    read_length, output_buf_length, delay);
                        }
 
                        if (output_buf_length > 0) {
                            write_length = spWritePluginDoubleWeighted(o_plugin, output_buf, output_buf_length, gain);
                            if (write_length > 0) {
                                total_write += write_length;
                            }
                        }
 
                        if (read_length <= 0) {
                            break;
                        }
                    }
 
                    spDebug(1, 
"main", 
"total_read = %ld, total_write = %ld\n", total_read, total_write);
 
                    
                } else {
                    spWarning(
"Cannot set sampling frequency: %f\n", o_wave_info.samp_rate);
 
                }
 
                spResampleClose(resample);
                spDebug(1, 
"main", 
"resample finished\n");
 
            } else {
            }
            
            spCloseFilePlugin(o_plugin);
        } else {
            } else {
                spWarning(
"Cannot open output file: %s\n", output_file);
 
            }
        }
        
        spCloseFilePlugin(i_plugin);
    } else {
        spWarning(
"Cannot open input file: %s\n", input_file);
 
    }
 
    return 0;
}
void spSetDebugLevel(int level)
void spWarning(const char *format,...)
void spMessage(const char *format,...)
void spDebug(int level, const char *func_name, const char *format,...)
#define spStrNone(string)
#define xspAlloc(n, type)
#define spGetOptions(argc, argv, option, file_label)
void spCheckNumFile(spOptions options)
struct _spOptions * spOptions
void spGetOptionsValue(int argc, char **argv, spOptions options)
const char * spGetFile(spOptions options)
void spSetHelpMessage(spBool *flag, const char *format,...)
char file_type[SP_WAVE_FILE_TYPE_SIZE]