/*
    Tucnak - VHF contest log
    Copyright (C) 2011-2016 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __DSP_H
#define __DSP_H

#include "header.h"

#ifdef HAVE_PORTAUDIO
#include <portaudio.h>
#endif

#ifdef HAVE_SLES_OPENSLES_H
#include <SLES/OpenSLES.h>
#endif

#ifdef HAVE_SWRADIO
#include <linux/videodev2.h>
#endif

#ifdef HAVE_LIBRTLSDR
#include <rtl-sdr.h>
#endif

#define MAX_CHANNELS 4

enum dsp_type { DSPT_OSS, DSPT_ALSA, DSPT_SSBDx, DSPT_PORTAUDIO, 
    DSPT_SNDFILE, DSPT_SNDPIPE, DSPT_SDRC, DSPT_SWRADIO,
    DSPT_RTLSDR, DSPT_HAMLIB };

enum dsp_cfg_group { DCG_SSBD, DCG_SDR };

struct dsp{
    enum dsp_type type;

/* OSS only */    
#ifdef HAVE_SYS_SOUNDCARD_H
    char *oss_filename, *oss_mixer;
    int fmt_mask;
    int oss_format,fragment,blksize;
#endif

#if defined(HAVE_SYS_SOUNDCARD_H) || defined(HAVE_SWRADIO)
    int fd;
#endif

/* Alsa only */    
#ifdef HAVE_ALSA    
    snd_pcm_t *pcm;
    snd_pcm_format_t pcm_format;
    int pcm_opened;
    int pcm_recover;
	char *pcm_play, *pcm_rec;
	char *alsa_mixer;
	char *alsa_src;
#endif   

/* Portaudio only */
#ifdef HAVE_PORTAUDIO
    PaStream *pa;
    PaStreamParameters pa_params;
    int pa_play, pa_rec;
    int pa_play_hi, pa_rec_hi;
    gchar *pa_play_s, *pa_rec_s;

#endif 

/* OpenSL ES only */
#ifdef HAVE_SLES_OPENSLES_H
    SLObjectItf engineObject;
    SLEngineItf engineEngine;
    SLObjectItf outputMixObject;
    SLObjectItf bqPlayerObject;
    SLObjectItf bqPlayerBufferQueue;
#endif	

#ifdef HAVE_SWRADIO
	char *swradio_filename;
    uint32_t swradio_format;
#endif

#ifdef HAVE_LIBRTLSDR
	char *rtlsdr_device;
	rtlsdr_dev_t *rtlsdr_dev;
	uint32_t rtlsdr_frequency;
	unsigned char *rtlsdr_buf;
	//int rtlsdr_bufsize, rtlsdr_buflen, rtlsdr_bufhead; // all in bytes
#endif

#ifdef HAVE_SNDFILE
	SNDFILE *sndfile;
	SF_INFO *sfinfo;
	char *play_filename, *rec_filename;
#endif
   
    int pipe[2]; 
	int pipe_opened;
	int pipe_opened_for_play;

	int sock;
	struct zbinbuf *rdbuf;

/* common */
    gchar *name; /* human readable string (/dev/dsp, hw:0,0) */
    int channels, speed, period_time, plev, rlev;
    char *source;
	int frames;      // buffer size in frames
    int samples;	 // buffer size in samples = frames * channels
	int bytes;       // buffer size in bytes = samples * 2

    int (*open)(struct dsp *dsp, int rec);
	int (*close2)(struct dsp *dsp);
    int (*write)(struct dsp *dsp, void *data, int frames);
    int (*read)(struct dsp *dsp, void *data, int frames);
    int (*reset)(struct dsp *dsp);
    int (*sync)(struct dsp *dsp);
#ifdef HAVE_SNDFILE
    int (*set_format)(struct dsp *dsp, SF_INFO *sfinfo, int rec);
#endif
	int (*set_source)(struct dsp *dsp);
	int (*set_plevel)(struct dsp *dsp);
    int (*set_sdr_format)(struct dsp *dsp, int blocksize, int speed, int rec);
};

/* format:
    0x10005     8 bit PCM
    0x10002     16 bit PCM    
    0x10010     u-law
    0x10011     a-law
    0x10012     IMA ADPCM
    0x10013     MS ADPCM
    0x10020     GSM 6.1  */

struct dsp *init_dsp (enum dsp_type, enum dsp_cfg_group);
void free_dsp(struct dsp *dsp);

#ifdef HAVE_SNDFILE
int dummy_dsp_set_format(struct dsp *dsp, SF_INFO *sfinfo, int rec);
#endif
int dummy_dsp_open(struct dsp *dsp, int rec);
int dummy_dsp_close(struct dsp *dsp);
int dummy_dsp_write(struct dsp *dsp, void *data, int len);
int dummy_dsp_read(struct dsp *dsp, void *data, int len);
int dummy_dsp_reset(struct dsp *dsp);
int dummy_dsp_sync(struct dsp *dsp);
int dummy_dsp_set_source(struct dsp *dsp);
int dummy_dsp_set_plevel(struct dsp *dsp);
int dummy_dsp_set_sdr_format(struct dsp *dsp, int blocksize, int speed, int rec);
int dsp_write_empty(struct dsp *dsp);
#endif


