mirror of
https://github.com/dj0abr/SSB_HighSpeed_Modem.git
synced 2026-06-01 21:44:51 -04:00
update
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
# makefile for dv_serial
|
||||
|
||||
CXXFLAGS = -Wall -O3 -std=c++0x -Wno-write-strings -Wno-narrowing
|
||||
LDFLAGS = -lpthread -lrt -lsndfile -lasound -lm -lbass -lfftw3 -lfftw3_threads -lliquid
|
||||
LDFLAGS = -lpthread -lrt -lsndfile -lasound -lm -lbass -lbassflac -lfftw3 -lfftw3_threads -lliquid
|
||||
OBJ = hsmodem.o constellation.o crc16.o frame_packer.o main_helper.o scrambler.o speed.o fec.o audio.o udp.o fft.o liquid_if.o
|
||||
|
||||
default: $(OBJ)
|
||||
|
||||
+152
-28
@@ -50,8 +50,9 @@ HSTREAM stream = 0;
|
||||
int openpbdev = -1;
|
||||
int opencapdev = -1;
|
||||
|
||||
/*void showDeviceInfo(BASS_DEVICEINFO info)
|
||||
void showDeviceInfo(BASS_DEVICEINFO info)
|
||||
{
|
||||
printf("Name:%s driver:%s flags:%d:", info.name, info.driver,info.flags);
|
||||
if (info.flags & BASS_DEVICE_ENABLED) printf("%s\n","BASS_DEVICE_ENABLED ");
|
||||
if (info.flags & BASS_DEVICE_DEFAULT) printf("%s\n","BASS_DEVICE_DEFAULT ");
|
||||
if (info.flags & BASS_DEVICE_INIT) printf("%s\n","BASS_DEVICE_INIT ");
|
||||
@@ -68,7 +69,28 @@ int opencapdev = -1;
|
||||
if (info.flags & BASS_DEVICE_TYPE_SPDIF) printf("%s\n","BASS_DEVICE_TYPE_SPDIF ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_SPEAKERS) printf("%s\n","BASS_DEVICE_TYPE_SPEAKERS ");
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
void showDeviceInfoWasabi(BASS_WASAPI_DEVICEINFO info, int devnum)
|
||||
{
|
||||
printf("%d: Name:%s defperiod:%f flags:%d minperiod:%f mixchans:%d mixfreq:%d type:%d ", devnum, info.name, info.defperiod, info.flags, info.minperiod,info.mixchans, info.mixfreq,info.type);
|
||||
if (info.flags & BASS_DEVICE_ENABLED) printf("%s\n", "BASS_DEVICE_ENABLED ");
|
||||
if (info.flags & BASS_DEVICE_DEFAULT) printf("%s\n", "BASS_DEVICE_DEFAULT ");
|
||||
if (info.flags & BASS_DEVICE_INIT) printf("%s\n", "BASS_DEVICE_INIT ");
|
||||
if (info.flags & BASS_DEVICE_LOOPBACK) printf("%s\n", "BASS_DEVICE_LOOPBACK ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_DIGITAL) printf("%s\n", "BASS_DEVICE_TYPE_DIGITAL ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_DISPLAYPORT) printf("%s\n", "BASS_DEVICE_TYPE_DISPLAYPORT ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_HANDSET) printf("%s\n", "BASS_DEVICE_TYPE_HANDSET ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_HDMI) printf("%s\n", "BASS_DEVICE_TYPE_HDMI ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_HEADPHONES) printf("%s\n", "BASS_DEVICE_TYPE_HEADPHONES ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_HEADSET) printf("%s\n", "BASS_DEVICE_TYPE_HEADSET ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_LINE) printf("%s\n", "BASS_DEVICE_TYPE_LINE ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_MICROPHONE) printf("%s\n", "BASS_DEVICE_TYPE_MICROPHONE ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_NETWORK) printf("%s\n", "BASS_DEVICE_TYPE_NETWORK ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_SPDIF) printf("%s\n", "BASS_DEVICE_TYPE_SPDIF ");
|
||||
if (info.flags & BASS_DEVICE_TYPE_SPEAKERS) printf("%s\n", "BASS_DEVICE_TYPE_SPEAKERS ");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
uint8_t devstring[MAXDEVSTRLEN +100];
|
||||
char PBdevs[100][256]; // stores the device names, just for diagnosis, has no real fuction
|
||||
@@ -103,9 +125,10 @@ void readAudioDevs()
|
||||
BASS_DEVICEINFO info;
|
||||
for (a = 1; BASS_GetDeviceInfo(a, &info); a++)
|
||||
{
|
||||
if (info.flags & BASS_DEVICE_ENABLED)
|
||||
showDeviceInfo(info);
|
||||
if (info.flags & BASS_DEVICE_ENABLED && !(info.flags & BASS_DEVICE_LOOPBACK))
|
||||
{
|
||||
if (!strstr(info.name, "HDMI") && !strstr(info.name, "hdmi") && !strstr(info.name, "efault"))
|
||||
if (!strstr(info.name, "efault"))
|
||||
{
|
||||
audioPBdevs[pbanz].bassdev = a;
|
||||
strncpy(audioPBdevs[pbanz].name, info.name, 255);
|
||||
@@ -117,9 +140,10 @@ void readAudioDevs()
|
||||
|
||||
for (a = 1; BASS_RecordGetDeviceInfo(a, &info); a++)
|
||||
{
|
||||
if (info.flags & BASS_DEVICE_ENABLED)
|
||||
//showDeviceInfo(info);
|
||||
if (info.flags & BASS_DEVICE_ENABLED && !(info.flags & BASS_DEVICE_LOOPBACK))
|
||||
{
|
||||
if (!strstr(info.name, "HDMI") && !strstr(info.name, "hdmi") && !strstr(info.name, "efault"))
|
||||
if (!strstr(info.name, "efault"))
|
||||
{
|
||||
audioCAPdevs[capanz].bassdev = a;
|
||||
strncpy(audioCAPdevs[capanz].name, info.name, 255);
|
||||
@@ -134,9 +158,10 @@ void readAudioDevs()
|
||||
BASS_WASAPI_DEVICEINFO info;
|
||||
for (a = 0; BASS_WASAPI_GetDeviceInfo(a, &info); a++)
|
||||
{
|
||||
if (!(info.flags & BASS_DEVICE_INPUT) && (info.flags & BASS_DEVICE_ENABLED))
|
||||
//showDeviceInfoWasabi(info,a);
|
||||
if (!(info.flags & BASS_DEVICE_INPUT) && (info.flags & BASS_DEVICE_ENABLED) && !(info.flags & BASS_DEVICE_LOOPBACK))
|
||||
{
|
||||
if (!strstr(info.name, "HDMI") && !strstr(info.name, "hdmi") && !strstr(info.name, "efault"))
|
||||
if (!strstr(info.name, "efault"))
|
||||
{
|
||||
audioPBdevs[pbanz].bassdev = a;
|
||||
strncpy(audioPBdevs[pbanz].name, info.name, 255);
|
||||
@@ -145,9 +170,9 @@ void readAudioDevs()
|
||||
}
|
||||
}
|
||||
|
||||
if ((info.flags & BASS_DEVICE_INPUT) && (info.flags & BASS_DEVICE_ENABLED))
|
||||
if ((info.flags & BASS_DEVICE_INPUT) && (info.flags & BASS_DEVICE_ENABLED) && !(info.flags & BASS_DEVICE_LOOPBACK))
|
||||
{
|
||||
if (!strstr(info.name, "HDMI") && !strstr(info.name, "hdmi") && !strstr(info.name, "efault"))
|
||||
if (!strstr(info.name, "efault"))
|
||||
{
|
||||
audioCAPdevs[capanz].bassdev = a;
|
||||
strncpy(audioCAPdevs[capanz].name, info.name, 255);
|
||||
@@ -181,6 +206,7 @@ void buildUdpAudioList()
|
||||
// playback devices
|
||||
for (int i = 0; i < pbanz; i++)
|
||||
{
|
||||
sprintf((char*)devstring + strlen((char*)devstring), "%d: ", i);
|
||||
strcat((char*)devstring, audioPBdevs[i].name);
|
||||
strcat((char*)devstring, "~"); // audio device separator
|
||||
}
|
||||
@@ -190,6 +216,7 @@ void buildUdpAudioList()
|
||||
// capture devices
|
||||
for (int i = 0; i < capanz; i++)
|
||||
{
|
||||
sprintf((char*)devstring + strlen((char*)devstring), "%d: ", i);
|
||||
strcat((char*)devstring, audioCAPdevs[i].name);
|
||||
strcat((char*)devstring, "~"); // audio device separator
|
||||
}
|
||||
@@ -224,7 +251,7 @@ static int f = 1;
|
||||
|
||||
int pbdev = -1;
|
||||
if (setpbdev >=0 && setpbdev < pbanz) pbdev = audioPBdevs[setpbdev].bassdev;
|
||||
int capdev = -1;
|
||||
int capdev = -2;
|
||||
if (setcapdev >= 0 && setcapdev < capanz) capdev = audioCAPdevs[setcapdev].bassdev;
|
||||
|
||||
printf("init audio, caprate:%d\n",caprate);
|
||||
@@ -251,7 +278,7 @@ static int f = 1;
|
||||
// initialize default output device
|
||||
if (!BASS_Init(pbdev, caprate, 0, NULL, NULL))
|
||||
{
|
||||
printf("Can't initialize output device\n");
|
||||
printf("Can't initialize output device: %d err:%d\n", pbdev, BASS_ErrorGetCode());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -263,6 +290,8 @@ static int f = 1;
|
||||
return -1;
|
||||
}
|
||||
pbdev = ret;
|
||||
openpbdev = pbdev;
|
||||
printf("real BASS PB Device No: %d\n", pbdev);
|
||||
|
||||
// set play callback
|
||||
BASS_GetInfo(&info);
|
||||
@@ -275,7 +304,7 @@ static int f = 1;
|
||||
// initalize default recording device
|
||||
if (!BASS_RecordInit(capdev))
|
||||
{
|
||||
printf("Can't initialize recording device: %d\n", BASS_ErrorGetCode());
|
||||
printf("Can't initialize recording device: %d err:%d\n", capdev, BASS_ErrorGetCode());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -287,6 +316,7 @@ static int f = 1;
|
||||
return -1;
|
||||
}
|
||||
capdev = ret;
|
||||
printf("real BASS CAP Device No: %d\n", capdev);
|
||||
|
||||
// set capture callback
|
||||
rchan = BASS_RecordStart(caprate, CHANNELS, BASS_SAMPLE_FLOAT, RecordingCallback, 0);
|
||||
@@ -297,7 +327,6 @@ static int f = 1;
|
||||
|
||||
printf("audio initialized\n");
|
||||
|
||||
openpbdev = pbdev;
|
||||
opencapdev = capdev;
|
||||
|
||||
return 0;
|
||||
@@ -305,7 +334,6 @@ static int f = 1;
|
||||
}
|
||||
|
||||
#ifdef _LINUX_
|
||||
|
||||
void close_audio()
|
||||
{
|
||||
if(stream != 0)
|
||||
@@ -394,7 +422,7 @@ DWORD CALLBACK WriteStream(HSTREAM handle, float *buffer, DWORD length, void *us
|
||||
return length;
|
||||
}
|
||||
|
||||
#endif // _LINUX_
|
||||
#endif
|
||||
|
||||
// set volume
|
||||
void setVolume(int pbcap, int v)
|
||||
@@ -403,6 +431,7 @@ void setVolume(int pbcap, int v)
|
||||
else setCAPvolume(v);
|
||||
}
|
||||
|
||||
|
||||
// ================ thread safe fifo for audio callback routines ===============
|
||||
|
||||
#ifdef _WIN32_
|
||||
@@ -507,21 +536,9 @@ void pb_write_fifo_clear()
|
||||
|
||||
int pb_fifo_usedBlocks()
|
||||
{
|
||||
static int old_fill = 0;
|
||||
int fill = 0;
|
||||
|
||||
int fs = pb_fifo_freespace(0);
|
||||
int used = AUDIO_PLAYBACK_BUFLEN - fs;
|
||||
used /= (txinterpolfactor * UDPBLOCKLEN * 8 / bitsPerSymbol);
|
||||
|
||||
if (used > 0) fill = 1; else fill = 0;
|
||||
if (fill == 1 && old_fill == 0)
|
||||
printf("fifo has data to send\n");
|
||||
if (fill == 0 && old_fill == 1)
|
||||
printf("fifo now empty\n");
|
||||
old_fill = fill;
|
||||
|
||||
//printf("free:%d used blocks:%d\n", fs, used);
|
||||
return used;
|
||||
}
|
||||
|
||||
@@ -541,6 +558,12 @@ int freebuf = 0;
|
||||
return freebuf;
|
||||
}
|
||||
|
||||
int pb_fifo_usedspace()
|
||||
{
|
||||
int anz = pb_fifo_freespace(0);
|
||||
return AUDIO_PLAYBACK_BUFLEN - anz;
|
||||
}
|
||||
|
||||
// read elements floats from fifo or return 0 if not enough floats are available
|
||||
int pb_read_fifo(float *data, int elements)
|
||||
{
|
||||
@@ -567,3 +590,104 @@ int pb_read_fifo(float *data, int elements)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================ Play FLAC Audio File ===========================
|
||||
|
||||
typedef struct _AUDIOFILES_ {
|
||||
char fn[256];
|
||||
int duration;
|
||||
} AUDIOFILES;
|
||||
|
||||
AUDIOFILES audiofiles[12] =
|
||||
{
|
||||
{"amsat", 1100},
|
||||
{"qpsk", 1100},
|
||||
{"psk8", 1100},
|
||||
{"3000", 600},
|
||||
{"4000", 600},
|
||||
{"4410", 900},
|
||||
{"4800", 900},
|
||||
{"5500", 900},
|
||||
{"6000", 600},
|
||||
{"6600", 900},
|
||||
{"7200", 900},
|
||||
{"kbps", 1000},
|
||||
};
|
||||
|
||||
char* getAudiofn(int aidx, char *ext)
|
||||
{
|
||||
static char filename[300];
|
||||
strcpy(filename, "audio/");
|
||||
strcat(filename, audiofiles[aidx].fn);
|
||||
strcat(filename, ext);
|
||||
return filename;
|
||||
}
|
||||
|
||||
void playAudioFLAC(int aidx)
|
||||
{
|
||||
int resamp = 0;
|
||||
int len;
|
||||
int16_t d[100];
|
||||
printf("play:%s\n", getAudiofn(aidx, ".pcm"));
|
||||
FILE *fp = fopen(getAudiofn(aidx,".pcm"), "rb");
|
||||
if (fp)
|
||||
{
|
||||
while ((len = fread(d, sizeof(int16_t), 100, fp)))
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
float f = (float)d[i];
|
||||
f /= 32768;
|
||||
pb_write_fifo(f);
|
||||
|
||||
if (caprate == 48000)
|
||||
{
|
||||
if (++resamp >= 9)
|
||||
{
|
||||
resamp = 0;
|
||||
pb_write_fifo(f);
|
||||
}
|
||||
}
|
||||
|
||||
// sync with soundcard
|
||||
while (pb_fifo_usedspace() > 10000) sleep_ms(1);
|
||||
}
|
||||
if (len != 100) break;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
printf("audio file not found\n");
|
||||
}
|
||||
|
||||
int ann_running = 0;
|
||||
int transmissions = 10000;
|
||||
|
||||
void sendAnnouncement()
|
||||
{
|
||||
if (announcement == 0) return;
|
||||
|
||||
if (++transmissions >= announcement)
|
||||
{
|
||||
ann_running = 1;
|
||||
transmissions = 0;
|
||||
|
||||
playAudioFLAC(0);
|
||||
if(bitsPerSymbol == 2) playAudioFLAC(1);
|
||||
else playAudioFLAC(2);
|
||||
switch (linespeed)
|
||||
{
|
||||
case 3000: playAudioFLAC(3); break;
|
||||
case 4000: playAudioFLAC(4); break;
|
||||
case 4410: playAudioFLAC(5); break;
|
||||
case 4800: playAudioFLAC(6); break;
|
||||
case 5500: playAudioFLAC(7); break;
|
||||
case 6000: playAudioFLAC(8); break;
|
||||
case 6600: playAudioFLAC(9); break;
|
||||
case 7200: playAudioFLAC(10); break;
|
||||
}
|
||||
playAudioFLAC(11);
|
||||
|
||||
ann_running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-12
@@ -35,8 +35,8 @@ void init_pipes();
|
||||
void cap_write_fifo(float sample);
|
||||
int pb_read_fifo(float* data, int elements);
|
||||
void close_wasapi();
|
||||
DWORD CALLBACK PBcallback(void* buffer, DWORD length, void* user);
|
||||
DWORD CALLBACK CAPcallback(void* buffer, DWORD length, void* user);
|
||||
DWORD CALLBACK PBcallback_wasapi(void* buffer, DWORD length, void* user);
|
||||
DWORD CALLBACK CAPcallback_wasapi(void* buffer, DWORD length, void* user);
|
||||
|
||||
float minPBvol = 0;
|
||||
float maxPBvol = 99;
|
||||
@@ -48,14 +48,18 @@ extern int opencapdev;
|
||||
|
||||
float softwareCAPvolume = 0.5;
|
||||
|
||||
int use_wasapi = -1;
|
||||
|
||||
int init_wasapi(int pbdev, int capdev)
|
||||
{
|
||||
close_wasapi();
|
||||
|
||||
use_wasapi = -1;
|
||||
|
||||
// ======= init PLAYBACK device ========
|
||||
|
||||
// initialize default output device
|
||||
if (!BASS_WASAPI_Init(pbdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f/*buffer in seconds*/, 0, PBcallback, NULL))
|
||||
if (!BASS_WASAPI_Init(pbdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f/*buffer in seconds*/, 0, PBcallback_wasapi, NULL))
|
||||
{
|
||||
printf("Can't initialize output device: %d err:%d\n", pbdev, BASS_ErrorGetCode());
|
||||
return -1;
|
||||
@@ -91,9 +95,9 @@ int init_wasapi(int pbdev, int capdev)
|
||||
|
||||
// initalize default recording device
|
||||
if (capdev == -1) capdev = -2; // cap: -2 is the default device for input
|
||||
if (!BASS_WASAPI_Init(capdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f/*buffer in seconds*/, 0, CAPcallback, NULL))
|
||||
if (!BASS_WASAPI_Init(capdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f/*buffer in seconds*/, 0, CAPcallback_wasapi, NULL))
|
||||
{
|
||||
printf("Can't initialize recording device: %d\n", BASS_ErrorGetCode());
|
||||
printf("Can't initialize recording device: %d err:%d\n", capdev, BASS_ErrorGetCode());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -127,16 +131,18 @@ int init_wasapi(int pbdev, int capdev)
|
||||
openpbdev = pbdev;
|
||||
opencapdev = capdev;
|
||||
|
||||
use_wasapi = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void selectPBdevice()
|
||||
void selectPBdevice_wasapi()
|
||||
{
|
||||
if (!BASS_WASAPI_SetDevice(openpbdev))
|
||||
printf("BASS_WASAPI_SetDevice: %d err:%d\n", openpbdev, BASS_ErrorGetCode());
|
||||
}
|
||||
|
||||
void selectCAPdevice()
|
||||
void selectCAPdevice_wasapi()
|
||||
{
|
||||
if (!BASS_WASAPI_SetDevice(opencapdev))
|
||||
printf("BASS_WASAPI_SetDevice: %d err:%d\n", opencapdev, BASS_ErrorGetCode());
|
||||
@@ -153,7 +159,7 @@ void setPBvolume(int v)
|
||||
|
||||
printf("set PB volume to:%d / %f [%f..%f]\n", v, vf, minPBvol, maxPBvol);
|
||||
|
||||
selectPBdevice();
|
||||
selectPBdevice_wasapi();
|
||||
if (!BASS_WASAPI_SetVolume(BASS_WASAPI_CURVE_DB, vf))
|
||||
printf("setPBvolume: %d err:%d\n", openpbdev, BASS_ErrorGetCode());
|
||||
}
|
||||
@@ -172,18 +178,18 @@ void close_wasapi()
|
||||
|
||||
if (openpbdev != -1)
|
||||
{
|
||||
selectPBdevice();
|
||||
selectPBdevice_wasapi();
|
||||
if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", openpbdev, BASS_ErrorGetCode());
|
||||
}
|
||||
|
||||
if (opencapdev != -1)
|
||||
{
|
||||
selectCAPdevice();
|
||||
selectCAPdevice_wasapi();
|
||||
if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", opencapdev, BASS_ErrorGetCode());
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CALLBACK PBcallback(void* buffer, DWORD length, void* user)
|
||||
DWORD CALLBACK PBcallback_wasapi(void* buffer, DWORD length, void* user)
|
||||
{
|
||||
float* fbuffer = (float*)buffer;
|
||||
|
||||
@@ -211,7 +217,7 @@ DWORD CALLBACK PBcallback(void* buffer, DWORD length, void* user)
|
||||
return length;
|
||||
}
|
||||
|
||||
DWORD CALLBACK CAPcallback(void* buffer, DWORD length, void* user)
|
||||
DWORD CALLBACK CAPcallback_wasapi(void* buffer, DWORD length, void* user)
|
||||
{
|
||||
//printf("CAP callback, len:%d\n",length);
|
||||
//measure_speed_bps(length/sizeof(float)/ WASAPI_CHANNELS);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
BASSFLAC 2.4 C/C++ header file
|
||||
Copyright (c) 2004-2017 Un4seen Developments Ltd.
|
||||
|
||||
See the BASSFLAC.CHM file for more detailed documentation
|
||||
*/
|
||||
|
||||
#ifndef BASSFLAC_H
|
||||
#define BASSFLAC_H
|
||||
|
||||
#include "bass.h"
|
||||
|
||||
#if BASSVERSION!=0x204
|
||||
#error conflicting BASS and BASSFLAC versions
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BASSFLACDEF
|
||||
#define BASSFLACDEF(f) WINAPI f
|
||||
#endif
|
||||
|
||||
// BASS_CHANNELINFO type
|
||||
#define BASS_CTYPE_STREAM_FLAC 0x10900
|
||||
#define BASS_CTYPE_STREAM_FLAC_OGG 0x10901
|
||||
|
||||
// Additional tag types
|
||||
#define BASS_TAG_FLAC_CUE 12 // cuesheet : TAG_FLAC_CUE structure
|
||||
#define BASS_TAG_FLAC_PICTURE 0x12000 // + index #, picture : TAG_FLAC_PICTURE structure
|
||||
#define BASS_TAG_FLAC_METADATA 0x12400 // + index #, application metadata : TAG_FLAC_METADATA structure
|
||||
|
||||
typedef struct {
|
||||
DWORD apic; // ID3v2 "APIC" picture type
|
||||
const char *mime; // mime type
|
||||
const char *desc; // description
|
||||
DWORD width;
|
||||
DWORD height;
|
||||
DWORD depth;
|
||||
DWORD colors;
|
||||
DWORD length; // data length
|
||||
const void *data;
|
||||
} TAG_FLAC_PICTURE;
|
||||
|
||||
typedef struct {
|
||||
QWORD offset; // index offset relative to track offset (samples)
|
||||
DWORD number; // index number
|
||||
} TAG_FLAC_CUE_TRACK_INDEX;
|
||||
|
||||
typedef struct {
|
||||
QWORD offset; // track offset (samples)
|
||||
DWORD number; // track number
|
||||
const char *isrc; // ISRC
|
||||
DWORD flags;
|
||||
DWORD nindexes; // number of indexes
|
||||
const TAG_FLAC_CUE_TRACK_INDEX *indexes; // the indexes
|
||||
} TAG_FLAC_CUE_TRACK;
|
||||
|
||||
typedef struct {
|
||||
const char *catalog; // media catalog number
|
||||
DWORD leadin; // lead-in (samples)
|
||||
BOOL iscd; // a CD?
|
||||
DWORD ntracks; // number of tracks
|
||||
const TAG_FLAC_CUE_TRACK *tracks; // the tracks
|
||||
} TAG_FLAC_CUE;
|
||||
|
||||
// TAG_FLAC_CUE_TRACK flags
|
||||
#define TAG_FLAC_CUE_TRACK_DATA 1 // data track
|
||||
#define TAG_FLAC_CUE_TRACK_PRE 2 // pre-emphasis
|
||||
|
||||
typedef struct {
|
||||
char id[4];
|
||||
DWORD length; // data length
|
||||
const void *data;
|
||||
} TAG_FLAC_METADATA;
|
||||
|
||||
HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
|
||||
HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
|
||||
HSTREAM BASSFLACDEF(BASS_FLAC_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static inline HSTREAM BASS_FLAC_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags)
|
||||
{
|
||||
return BASS_FLAC_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE);
|
||||
}
|
||||
|
||||
static inline HSTREAM BASS_FLAC_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user)
|
||||
{
|
||||
return BASS_FLAC_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
+22
-17
@@ -88,7 +88,7 @@ int UdpDataPort_fromGR_I_Q = 40137;
|
||||
|
||||
// op mode depending values
|
||||
// default mode if not set by the app
|
||||
int speedmode = 7;
|
||||
int speedmode = 2;
|
||||
int bitsPerSymbol = 2; // QPSK=2, 8PSK=3
|
||||
int constellationSize = 4; // QPSK=4, 8PSK=8
|
||||
|
||||
@@ -101,11 +101,13 @@ int restart_modems = 0;
|
||||
int caprate = 44100;
|
||||
int txinterpolfactor = 20;
|
||||
int rxPreInterpolfactor = 5;
|
||||
int linespeed = 4410;
|
||||
|
||||
int captureDeviceNo = -1;
|
||||
int playbackDeviceNo = -1;
|
||||
int initialPBvol = -1;
|
||||
int initialCAPvol = -1;
|
||||
int announcement = 0;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
@@ -221,22 +223,21 @@ typedef struct {
|
||||
int tx;
|
||||
int rx;
|
||||
int bpsym;
|
||||
int linespeed;
|
||||
} SPEEDRATE;
|
||||
|
||||
SPEEDRATE sr[10] = {
|
||||
SPEEDRATE sr[8] = {
|
||||
// QPSK modes
|
||||
{48000, 32, 8, 2}, // AudioRate, TX-Resampler, RX-Resampler/4, bit/symbol
|
||||
{44100, 28, 7, 2}, // see samprate.ods
|
||||
{44100, 24, 6, 2},
|
||||
{48000, 24, 6, 2},
|
||||
{44100, 20, 5, 2},
|
||||
{48000, 20, 5, 2},
|
||||
{48000, 32, 8, 2, 3000}, // AudioRate, TX-Resampler, RX-Resampler/4, bit/symbol, see samprate.ods
|
||||
{48000, 24, 6, 2, 4000},
|
||||
{44100, 20, 5, 2, 4410},
|
||||
{48000, 20, 5, 2, 4800},
|
||||
|
||||
// 8PSK modes
|
||||
{44100, 24, 6, 3},
|
||||
{48000, 24, 6, 3},
|
||||
{44100, 20, 5, 3},
|
||||
{48000, 20, 5, 3}
|
||||
{44100, 24, 6, 3, 5500},
|
||||
{48000, 24, 6, 3, 6000},
|
||||
{44100, 20, 5, 3, 6600},
|
||||
{48000, 20, 5, 3, 7200}
|
||||
};
|
||||
|
||||
void startModem()
|
||||
@@ -247,6 +248,7 @@ void startModem()
|
||||
caprate = sr[speedmode].audio;
|
||||
txinterpolfactor = sr[speedmode].tx;
|
||||
rxPreInterpolfactor = sr[speedmode].rx;
|
||||
linespeed = sr[speedmode].linespeed;
|
||||
|
||||
// int TX audio and modulator
|
||||
close_dsp();
|
||||
@@ -256,7 +258,7 @@ void startModem()
|
||||
init_dsp();
|
||||
}
|
||||
|
||||
void setAudioDevices(int pb, int cap, int pbvol, int capvol)
|
||||
void setAudioDevices(int pb, int cap, int pbvol, int capvol, int announce)
|
||||
{
|
||||
//printf("%d %d\n", pb, cap);
|
||||
|
||||
@@ -268,6 +270,8 @@ void setAudioDevices(int pb, int cap, int pbvol, int capvol)
|
||||
initialPBvol = pbvol;
|
||||
initialCAPvol = capvol;
|
||||
}
|
||||
|
||||
announcement = announce;
|
||||
}
|
||||
|
||||
// called from UDP RX thread for Broadcast-search from App
|
||||
@@ -275,7 +279,7 @@ void bc_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
|
||||
{
|
||||
if (len > 0 && pdata[0] == 0x3c)
|
||||
{
|
||||
setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4]);
|
||||
setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4], pdata[5]);
|
||||
|
||||
char rxip[20];
|
||||
strcpy(rxip, inet_ntoa(rxsock->sin_addr));
|
||||
@@ -325,6 +329,7 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
|
||||
speedmode = pdata[1];
|
||||
printf("set speedmode to %d\n", speedmode);
|
||||
restart_modems = 1;
|
||||
transmissions = 1000; // announcement at next TX
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -392,9 +397,9 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
|
||||
if (minfo == 0)
|
||||
{
|
||||
// this is the first frame of a larger file
|
||||
sendAnnouncement();
|
||||
// send it multiple times, like a preamble, to give the
|
||||
// receiver some time for synchronisation
|
||||
// duration: 3 seconds
|
||||
// caprate: samples/s. This are symbols: caprate/txinterpolfactor
|
||||
// and bits: symbols * bitsPerSymbol
|
||||
// and bytes/second: bits/8 = (caprate/txinterpolfactor) * bitsPerSymbol / 8
|
||||
@@ -405,7 +410,7 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
|
||||
}
|
||||
else if ((len - 2) < PAYLOADLEN)
|
||||
{
|
||||
// if not enough data for a full payload add Zeros
|
||||
// if not enough data for a full payload add Zeros
|
||||
uint8_t payload[PAYLOADLEN];
|
||||
memset(payload, 0, PAYLOADLEN);
|
||||
memcpy(payload, pdata + 2, len - 2);
|
||||
@@ -428,7 +433,7 @@ void toGR_sendData(uint8_t* data, int type, int status)
|
||||
sendToModulator(txdata, len);
|
||||
}
|
||||
|
||||
// called by UDP RX thread or liquid demodulator for received data
|
||||
// called by liquid demodulator for received data
|
||||
void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
|
||||
{
|
||||
static int fnd = 0;
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#include "bass.h"
|
||||
#include "basswasapi.h"
|
||||
#include "bassflac.h"
|
||||
#include "liquid.h"
|
||||
#include "frameformat.h"
|
||||
#include "fec.h"
|
||||
@@ -111,6 +112,7 @@ void setPBvolume(int v);
|
||||
void setCAPvolume(int v);
|
||||
void setVolume(int pbcap, int v);
|
||||
int init_wasapi(int pbdev, int capdev);
|
||||
void sendAnnouncement();
|
||||
|
||||
void sleep_ms(int ms);
|
||||
void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock);
|
||||
@@ -140,6 +142,10 @@ extern int txinterpolfactor;
|
||||
extern int rxPreInterpolfactor;
|
||||
extern char appIP[20];
|
||||
extern float softwareCAPvolume;
|
||||
extern int announcement;
|
||||
extern int ann_running;
|
||||
extern int transmissions;
|
||||
extern int linespeed;
|
||||
|
||||
#ifdef _LINUX_
|
||||
int isRunning(char* prgname);
|
||||
|
||||
@@ -220,6 +220,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="bass.h" />
|
||||
<ClInclude Include="bassflac.h" />
|
||||
<ClInclude Include="basswasapi.h" />
|
||||
<ClInclude Include="fec.h" />
|
||||
<ClInclude Include="fftw3.h" />
|
||||
|
||||
@@ -83,5 +83,8 @@
|
||||
<ClInclude Include="fec.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bassflac.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -289,7 +289,7 @@ void make_FFTdata(float f)
|
||||
int bidx = 0;
|
||||
txpl[bidx++] = 4; // type 4: FFT data follows
|
||||
int us = pb_fifo_usedBlocks();
|
||||
if (us > 255) us = 255;
|
||||
if (us > 255 || ann_running == 1) us = 255;
|
||||
txpl[bidx++] = us; // usage of TX fifo
|
||||
|
||||
for (int i = 0; i < fftlen; i++)
|
||||
@@ -353,7 +353,7 @@ static int ccol_idx = 0;
|
||||
unsigned int sym_out; // output symbol
|
||||
modem_demodulate(demod, syms, &sym_out);
|
||||
|
||||
//measure_speed_syms(1);
|
||||
measure_speed_syms(1);
|
||||
|
||||
// try to extract a complete frame
|
||||
uint8_t symb = sym_out;
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ void measure_speed_syms(int len)
|
||||
speed = meanval((int)dspd) * bitsPerSymbol;
|
||||
|
||||
// here we have number of elements after 1s
|
||||
printf("%d sym/s\n",speed);
|
||||
//printf("%d sym/s\n",speed);
|
||||
|
||||
elems=0;
|
||||
lasttim = tim;
|
||||
|
||||
@@ -140,7 +140,6 @@ void sendUDP(char *destIP, int destPort, uint8_t *pdata, int len)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in servaddr;
|
||||
//printf("%d %d %02X\n",destPort,len,pdata[0]);
|
||||
|
||||
// Creating socket file descriptor
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
|
||||
Reference in New Issue
Block a user