2021-01-15 16:15:58 -05:00
|
|
|
|
|
|
|
#include "libkmaudio.h"
|
|
|
|
|
|
|
|
void getMax(int id, float fv);
|
|
|
|
|
2021-01-18 09:36:29 -05:00
|
|
|
void close_stream(int id)
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
if (devlist[id].capStream != NULL)
|
|
|
|
close_capture_stream(id);
|
|
|
|
if (devlist[id].pbStream != NULL)
|
|
|
|
close_playback_stream(id);
|
|
|
|
#else
|
|
|
|
if (devlist[id].instream != NULL)
|
|
|
|
close_capture_stream(id);
|
|
|
|
if (devlist[id].outstream != NULL)
|
|
|
|
close_playback_stream(id);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-01-15 16:15:58 -05:00
|
|
|
/*
|
|
|
|
* reads len samples from device id into psamp
|
|
|
|
* returns: number of values written to psamp , -1=error
|
|
|
|
* id ... device id returned by kmaudio_startCapture
|
|
|
|
* psamp ... float array of length len getting the audio data (mono)
|
|
|
|
* len ... number of float values to write into psamp
|
|
|
|
* volume ... 0.0f..2.0f will be multiplied with the input sample
|
|
|
|
* wait ... 1=wait for data, 0=return if not enough data available (in this case psamp will return 0,0,0...)
|
|
|
|
*
|
|
|
|
* if resampling is required the number of returned samples may differ from the number of requested samples
|
|
|
|
* it can be larger, so the buffer psamp should be larger than "len" by factor 1.1
|
|
|
|
*/
|
|
|
|
|
|
|
|
int kmaudio_readsamples(int id, float* psamp, int len, float volume, int wait)
|
|
|
|
{
|
|
|
|
int e = io_fifo_elems_avail(id);
|
|
|
|
if (e < len) return 0;
|
|
|
|
|
|
|
|
if (devlist[id].requested_samprate == devlist[id].real_samprate)
|
|
|
|
{
|
|
|
|
// data rate is ok, take samples as is
|
|
|
|
int nl = io_read_fifo_num(id, psamp, len);
|
|
|
|
for (int i = 0; i < nl; i++)
|
|
|
|
{
|
|
|
|
psamp[i] *= volume;
|
|
|
|
getMax(id, psamp[i]);
|
|
|
|
//kmaudio_detectDropouts(id);
|
|
|
|
}
|
|
|
|
return nl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// resampling is required
|
|
|
|
int num = io_read_fifo_num(id, psamp, len);
|
|
|
|
if (num == 0) return 0;
|
|
|
|
|
|
|
|
int newlen = 0;
|
|
|
|
float *f = resample(id, psamp, len, &newlen);
|
|
|
|
for (int i = 0; i < newlen; i++)
|
|
|
|
{
|
|
|
|
psamp[i] = f[i] * volume;
|
|
|
|
getMax(id, psamp[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return newlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* plays len samples from psamp to device id
|
|
|
|
* returns: 0=ok, -1=error
|
|
|
|
* id ... device id returned by kmaudio_startPlayback
|
|
|
|
* psamp ... float array of length len with the audio data (mono)
|
|
|
|
* len ... number of float values in psamp
|
|
|
|
* volume ... 0.0f..2.0f will be multiplied with the output sample
|
|
|
|
*/
|
|
|
|
|
|
|
|
int kmaudio_playsamples(int id, float* psamp, int len, float volume)
|
|
|
|
{
|
|
|
|
// check if resampling is required
|
|
|
|
//printf("%d %d\n", devlist[id].requested_samprate , devlist[id].real_samprate);
|
|
|
|
if (devlist[id].requested_samprate == devlist[id].real_samprate)
|
|
|
|
{
|
|
|
|
// sampling rate is ok, just play samples
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
io_write_fifo(id, psamp[i] * volume);
|
|
|
|
getMax(id, psamp[i] * volume);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// resampling is required
|
|
|
|
int newlen = 0;
|
|
|
|
float *f = resample(id, psamp, len, &newlen);
|
|
|
|
for (int i = 0; i < newlen; i++)
|
|
|
|
{
|
|
|
|
io_write_fifo(id, f[i] * volume);
|
|
|
|
getMax(id, psamp[i] * volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MCHECK 48000 // abt. 1s of samples
|
|
|
|
float farr[MAXDEVICES][MCHECK];
|
|
|
|
int farridx[MAXDEVICES];
|
|
|
|
|
|
|
|
void init_maxarray()
|
|
|
|
{
|
|
|
|
// initialize arrays
|
|
|
|
for (int md = 0; md < MAXDEVICES; md++)
|
|
|
|
{
|
|
|
|
farridx[md] = 0;
|
|
|
|
for (int i = 0; i < MCHECK; i++)
|
|
|
|
farr[md][i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void getMax(int id, float fv)
|
|
|
|
{
|
|
|
|
// put value into array
|
|
|
|
farr[id][farridx[id]] = fv;
|
|
|
|
if (++farridx[id] == MCHECK)
|
|
|
|
farridx[id] = 0;
|
|
|
|
}
|
|
|
|
|
2021-02-22 09:58:19 -05:00
|
|
|
int isPlaying(int id)
|
|
|
|
{
|
|
|
|
return devlist[id].audio_playing;
|
|
|
|
}
|
|
|
|
|
2021-01-15 16:15:58 -05:00
|
|
|
/*
|
|
|
|
* returns the max level (within 1 second) of this stream in % (0..100)
|
|
|
|
* if the level >= 100 the signal will get clipped and distorted
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint8_t kmaudio_maxlevel(int id)
|
|
|
|
{
|
|
|
|
float max = 0;
|
|
|
|
for (int i = 0; i < MCHECK; i++)
|
|
|
|
if (farr[id][i] > max) max = farr[id][i];
|
|
|
|
|
|
|
|
return (uint8_t)(max * 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
void kmaudio_detectDropouts(int id)
|
|
|
|
{
|
|
|
|
int stat = 0;
|
|
|
|
int drlen = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < MCHECK; i++)
|
|
|
|
{
|
|
|
|
switch (stat)
|
|
|
|
{
|
|
|
|
case 0: // search beginning of dropout
|
|
|
|
if (farr[id][i] == 0.0f)
|
|
|
|
stat = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: // count length of dropout
|
|
|
|
if (farr[id][i] == 0.0f) drlen++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// end of dropout
|
|
|
|
if (drlen > 0)
|
|
|
|
{
|
|
|
|
printf("Dropout len:%d\n", drlen);
|
|
|
|
}
|
|
|
|
drlen = 0;
|
|
|
|
stat = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|