#include "rec-sock-alsa.h"

/* ***************************************************************** */

int open_sound(snd_pcm_t ** handle /* ptr auf ptr */)
{
int retval;
snd_pcm_channel_params_t params;

if ((retval = snd_pcm_open(handle, 0 /* card */, 0 /* device */, 
                           SND_PCM_OPEN_CAPTURE)))
   { fprintf(stderr,"Error with snd_pcm_open: %s\n",snd_strerror(retval));
     return 1; };
   // auch mgl.: snd_pcm_open_subdevice(h,c,d, s ,m) ...
   // mode: | SND_PCM_OPEN_NONBLOCK ist mgl.

params.channel=0; 
params.format.format=SND_PCM_SFMT_S32_LE;
   // Ice1712pro/Linux does only this, and without the use of plugins,
   // ALSA offers no conversion.
   // btw. the hardware only uses the 24 MSBs.
params.format.interleave = 1;
   // interleaved vs. blocked data format
   // for vector based i/o, interleave sucks.
params.format.rate = snd_HZ;
params.format.voices = nCHN;
   // Ice1712pro/Linux driver supports only opening all voices at once!
   // for capture, voices *must* be 12, for playback, it *must* be 10.
params.channel = SND_PCM_CHANNEL_CAPTURE; // or ... CAPTURE
params.mode = SND_PCM_MODE_STREAM; // or ... BLOCK
  // not set: params.digital.*, params.format.reserved, 
  // params.reserved, params.format.special
params.start_mode = SND_PCM_START_DATA; // or ... FULL or ... GO
params.stop_mode = SND_PCM_STOP_ROLLOVER; 
  // ... STOP or ... ERASE or ... ROLLOVER
  // STOP klappt, aber ROLLOVER muss nach einem Buffer
  // overrun/underrun nicht neu angeworfen werden.
params.time = 0; // set to get gettimeofday time of beginning of transfer
                 // -> sys/time.h ... struct timeval -> tv_sec ...
params.ust_time = 0; // set to get time in UST format
  
   params.buf.stream.queue_size = (snd_HZ >> 1) * 4 * nCHN;
                 // muss ein Vielfaches von 4*nCHN sein, min 1/2k...
                 // 1/16 Sekunde mit (snd_HZ >> 4) * 40 funktioniert z.B. ok.
                 // Groessere Queue -> mehr Latency aber weniger kritisches
                 // Timing bei Multitasking. Also sinnvoll einstellen!
   params.buf.stream.fill = SND_PCM_FILL_SILENCE_WHOLE; 
                 // or ... NONE or ... SILENCE
   params.buf.stream.max_fill = 480;
                 // not really used if fill!=...SILENCE
/* 
 * params.buf.block.frag_size=40960;
 * params.buf.block.frags_min=1;
 * params.buf.block.frags_max=10;
 */
if ((retval = snd_pcm_channel_params(*handle,&params)))
   { fprintf(stderr,"Format not supported by soundcard: "); 
     fprintf(stderr,"%s\n",snd_strerror(retval)); return 1; };

if ((retval = snd_pcm_capture_prepare(*handle)))
   { fprintf(stderr,"Error preparing capture: "); 
     fprintf(stderr,"%s\n",snd_strerror(retval)); return 1; };

// je nach START setting fehlt nun noch snd_pcm_capture_go(),
// ansonsten passiert der START automatisch.
return 0;
};

/* ***************************************************************** */

int close_sound(snd_pcm_t * handle)
{
int retval;
if ((retval = snd_pcm_close(handle)))
   {  fprintf(stderr,"Error closing sound: %s\n",snd_strerror(retval)); };
return retval;
};

/* ***************************************************************** */

