diff --git a/LinuxRelease/hsmodem b/LinuxRelease/hsmodem index c0d86ca..d2ec1c8 100755 Binary files a/LinuxRelease/hsmodem and b/LinuxRelease/hsmodem differ diff --git a/README.md b/README.md index 38b03a0..ea7c174 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The purpose of this project is to transfer data (pictures...) via a 2,7kHz SSB channel on the narrow band transponder as fast as possible. # this is work in progress -Version 0.2 is working on: +Version 0.4 is working on: Windows 10 (should work on Win7, not tested) linux Desktop PC, Odroid SBC @@ -27,6 +27,7 @@ this software uses these programs: * liquid-SDR: https://github.com/jgaeddert/liquid-dsp (MIT License) * BASS Audio: https://www.un4seen.com/ (free for non-commercial use) * fftw3: http://www.fftw.org (GPL V.2 or later) +* libcodec2 (Linux: standard lib, Windows: from freeDV) # building the software * Linux @@ -42,12 +43,18 @@ this software uses these programs: you need to run 2 programs, the first one is "hsmodem" which runs in a termimal without GUI. This is the modem doing all modulation and demodulation staff. The second program is the user interface "oscardata.exe". -1. go into the folder "WinRelease" or "LinuxRelease" +* Windows +copy all files from "WinRelease" into any folder of your choice. Start oscardata.exe by double-clicking. +The application oscardata.exe can also run on a different PC in your home network, see Linux version. +Even a mix between Linux and Windows is possible, so running oscardata.exe on a Windows PC and +running the hsmodem on another computer in the shack. + +* Linux +1. go into the folder "LinuxRelease" 2. run the software: ./hs100modem.exe or ./hsmodem optional command line parameter: no parameter ... normal usage -m IP ... specify the V4 IP adress of the device where the application software is running. This is useful if you have more than one qo100modem running simultaneously. Without this parameter the app will search the modem automatically. - 3. start the user application on any PC in your home network. It will find the modem automatically The file is located in oscardata/oscardata/bin/Release On windows just start oscardata.exe @@ -58,8 +65,6 @@ On Linux start it with: mono oscardata.exe * QO-100 via IC-9700, IC-7300 or IC-7100 ... working * Short Wave 6m band via IC-7300, IC-7100 ... working. In case of significant noise, use the lowest bit rate (3000 bit/s) -# TODOs -the current version V0.2 runs very fine on Linux but shows a higher bit error rate on Windows. This has to do with the initialisation of the sound card. The default sound bitrate setting in the Windows-Sound-Settings implement some kind of "filtering". This is currently under evaluation. # usage diff --git a/WinRelease/hsmodem.exe b/WinRelease/hsmodem.exe index a9b46e5..d61bc7c 100755 Binary files a/WinRelease/hsmodem.exe and b/WinRelease/hsmodem.exe differ diff --git a/WinRelease/libcodec2.dll b/WinRelease/libcodec2.dll new file mode 100755 index 0000000..d05498e Binary files /dev/null and b/WinRelease/libcodec2.dll differ diff --git a/WinRelease/libgcc_s_sjlj-1.dll b/WinRelease/libgcc_s_sjlj-1.dll new file mode 100755 index 0000000..24fa2dc Binary files /dev/null and b/WinRelease/libgcc_s_sjlj-1.dll differ diff --git a/WinRelease/liblpcnetfreedv.dll b/WinRelease/liblpcnetfreedv.dll new file mode 100755 index 0000000..0a452c3 Binary files /dev/null and b/WinRelease/liblpcnetfreedv.dll differ diff --git a/WinRelease/libwinpthread-1.dll b/WinRelease/libwinpthread-1.dll new file mode 100755 index 0000000..357a244 Binary files /dev/null and b/WinRelease/libwinpthread-1.dll differ diff --git a/WinRelease/oscardata.exe b/WinRelease/oscardata.exe index b43db5d..572a092 100755 Binary files a/WinRelease/oscardata.exe and b/WinRelease/oscardata.exe differ diff --git a/hsmodem/Makefile b/hsmodem/Makefile index 9e850a2..4b7effb 100755 --- a/hsmodem/Makefile +++ b/hsmodem/Makefile @@ -1,8 +1,8 @@ -# makefile for dv_serial +# makefile for hsmodem CXXFLAGS = -Wall -O3 -std=c++0x -Wno-write-strings -Wno-narrowing -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 symboltracker.o +LDFLAGS = -lpthread -lrt -lsndfile -lasound -lm -lopus -lbassopus -lbass -lbassenc_opus -lbassenc -lfftw3 -lfftw3_threads -lliquid -lcodec2 +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 symboltracker.o audio_voice.o voiceprocessor.o codec2.o default: $(OBJ) g++ $(CXXFLAGS) -o ../LinuxRelease/hsmodem $(OBJ) $(LDFLAGS) diff --git a/hsmodem/audio.cpp b/hsmodem/audio.cpp index 80e3930..67c68b9 100755 --- a/hsmodem/audio.cpp +++ b/hsmodem/audio.cpp @@ -38,7 +38,6 @@ BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user); DWORD CALLBACK WriteStream(HSTREAM handle, float *buffer, DWORD length, void *user); int pb_read_fifo(float *data, int elements); -void close_audio(); void cap_write_fifo(float sample); int pb_fifo_freespace(int nolock); void init_pipes(); @@ -96,12 +95,6 @@ uint8_t devstring[MAXDEVSTRLEN +100]; char PBdevs[100][256]; // stores the device names, just for diagnosis, has no real fuction char CAPdevs[100][256]; -// audio device description table -typedef struct { - int bassdev; // bass (basswasapi) dev no - char name[256]; // DEV name -} AUDIODEVS; - // index is enumerated number, 0=default AUDIODEVS audioPBdevs[100]; AUDIODEVS audioCAPdevs[100]; @@ -111,6 +104,8 @@ int pbanz = 0, capanz = 0; void readAudioDevs() { int a; + pbanz = 0; + capanz = 0; // enter default device manually audioPBdevs[pbanz].bassdev = -1; @@ -125,7 +120,7 @@ void readAudioDevs() BASS_DEVICEINFO info; for (a = 1; BASS_GetDeviceInfo(a, &info); a++) { - showDeviceInfo(info); + //showDeviceInfo(info); if (info.flags & BASS_DEVICE_ENABLED && !(info.flags & BASS_DEVICE_LOOPBACK)) { if (!strstr(info.name, "efault")) @@ -133,6 +128,7 @@ void readAudioDevs() audioPBdevs[pbanz].bassdev = a; strncpy(audioPBdevs[pbanz].name, info.name, 255); audioPBdevs[pbanz].name[255] = 0; + strncpy(audioPBdevs[pbanz].id, info.driver, 255); pbanz++; } } @@ -148,6 +144,7 @@ void readAudioDevs() audioCAPdevs[capanz].bassdev = a; strncpy(audioCAPdevs[capanz].name, info.name, 255); audioCAPdevs[capanz].name[255] = 0; + strncpy(audioCAPdevs[capanz].id, info.driver, 255); capanz++; } } @@ -166,6 +163,7 @@ void readAudioDevs() audioPBdevs[pbanz].bassdev = a; strncpy(audioPBdevs[pbanz].name, info.name, 255); audioPBdevs[pbanz].name[255] = 0; + strncpy(audioPBdevs[pbanz].id, info.id, 255); pbanz++; } } @@ -177,6 +175,7 @@ void readAudioDevs() audioCAPdevs[capanz].bassdev = a; strncpy(audioCAPdevs[capanz].name, info.name, 255); audioCAPdevs[capanz].name[255] = 0; + strncpy(audioCAPdevs[capanz].id, info.id, 255); capanz++; } } @@ -188,11 +187,11 @@ void printAudioDevs() { printf("PB devices:\n"); for (int i = 0; i < pbanz; i++) - printf("idx:%d bass:%d name:%s\n", i, audioPBdevs[i].bassdev, audioPBdevs[i].name); + printf("idx:%d ID:%s bass:%d name:%s\n", i, audioPBdevs[i].id, audioPBdevs[i].bassdev, audioPBdevs[i].name); printf("CAP devices:\n"); for (int i = 0; i < capanz; i++) - printf("idx:%d bass:%d name:%s\n", i, audioCAPdevs[i].bassdev, audioCAPdevs[i].name); + printf("idx:%d ID:%s bass:%d name:%s\n", i, audioCAPdevs[i].id, audioCAPdevs[i].bassdev, audioCAPdevs[i].name); } // build string of audio device name, to be sent to application as response to Broadcast search @@ -202,6 +201,11 @@ void buildUdpAudioList() { memset(devstring, 0, sizeof(devstring)); devstring[0] = ' '; // placeholder for ID for this UDP message + devstring[1] = '0' + init_audio_result; + devstring[2] = '0' + init_voice_result; + + //printf("init_voice_result:%d\n", devstring[2]); + // playback devices for (int i = 0; i < pbanz; i++) @@ -226,22 +230,34 @@ void buildUdpAudioList() uint8_t* getAudioDevicelist(int *len) { + // update Status + devstring[1] = '0' + init_audio_result; + devstring[2] = '0' + init_voice_result; + *len = strlen((char*)(devstring+1))+1; return devstring; } -// pbdev, capdev: -1=default device +// read audio device list at program start, or if something went wrong +void readAudioDevices() +{ + readAudioDevs(); + //printAudioDevs(); + buildUdpAudioList(); + return; +} + +// ret: 0=ok, -1=system error, 1=pb error 2=cap error 3=pb+cap error int init_audio(int setpbdev, int setcapdev) { static int f = 1; +int ret = 0; if (f == 1) { // do only once after program start f = 0; - readAudioDevs(); - printAudioDevs(); - buildUdpAudioList(); + readAudioDevices(); init_pipes(); } @@ -262,7 +278,7 @@ static int f = 1; if (HIWORD(BASS_GetVersion()) != BASSVERSION) { printf("An incorrect version of BASS was loaded\n"); - return -1; + return 3; } #ifdef _WIN32_ @@ -279,25 +295,31 @@ static int f = 1; if (!BASS_Init(pbdev, caprate, 0, NULL, NULL)) { printf("Can't initialize output device: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; + ret = 1; } - - // read real device number - int ret = BASS_GetDevice(); - if (ret == -1) + else { - printf("BASS_GetDevice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; - } - pbdev = ret; - openpbdev = pbdev; - printf("real BASS PB Device No: %d\n", pbdev); - // set play callback - BASS_GetInfo(&info); - stream = BASS_StreamCreate(info.freq, CHANNELS, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream, 0); // sample: 32 bit float - BASS_ChannelSetAttribute(stream, BASS_ATTRIB_BUFFER, 0); // no buffering for minimum latency - BASS_ChannelPlay(stream, FALSE); // start it + // read real device number + int device = BASS_GetDevice(); + if (device == -1) + { + printf("BASS_GetDevice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + pbdev = device; + openpbdev = pbdev; + printf("real BASS PB Device No: %d\n", pbdev); + + // set play callback + BASS_GetInfo(&info); + stream = BASS_StreamCreate(info.freq, CHANNELS, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream, 0); // sample: 32 bit float + BASS_ChannelSetAttribute(stream, BASS_ATTRIB_BUFFER, 0); // no buffering for minimum latency + BASS_ChannelPlay(stream, FALSE); // start it + } + } // ===== CAPTURE ==== @@ -305,51 +327,56 @@ static int f = 1; if (!BASS_RecordInit(capdev)) { printf("Can't initialize recording device: %d err:%d\n", capdev, BASS_ErrorGetCode()); - return -1; + ret |= 2; } - - // read real device number - ret = BASS_GetDevice(); - if (ret == -1) + else { - printf("BASS_GetDevice: %d err:%d\n", capdev, BASS_ErrorGetCode()); - 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); - if (!rchan) { - printf("Can't start capturing: %d\n", BASS_ErrorGetCode()); - return -1; + // read real device number + int device = BASS_RecordGetDevice(); + if (device == -1) + { + printf("BASS_GetDevice: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + capdev = device; + printf("real BASS CAP Device No: %d\n", capdev); + + // set capture callback + if (rchan) BASS_ChannelStop(rchan); + rchan = BASS_RecordStart(caprate, CHANNELS, BASS_SAMPLE_FLOAT, RecordingCallback, 0); + if (!rchan) + { + printf("Can't start capturing: %d\n", BASS_ErrorGetCode()); + ret |= 2; + } + else + opencapdev = capdev; + } } - printf("audio initialized\n"); + if(ret == 0) + printf("audio started successfully for PBdev:%d and CAPdev:%d\n", openpbdev, opencapdev); + else + { + opencapdev = -1; + openpbdev = -1; + readAudioDevices(); + } + if (ret == 1) + printf("audio initialized: PBerror CapOK\n"); + if (ret == 2) + printf("audio initialized: PBOK CapERROR\n"); + if (ret == 3) + printf("audio initialized: PBerror CapERROR\n"); - opencapdev = capdev; - - return 0; + return ret; #endif } #ifdef _LINUX_ -void close_audio() -{ - if(stream != 0) - { - printf("close Audio Devices\n"); - BASS_ChannelStop(rchan); - int rr = BASS_RecordFree(); - if (!rr) printf("Bass_RecordFree error: %d\n", BASS_ErrorGetCode()); - - BASS_StreamFree(stream); - int r = BASS_Free(); - if(!r) printf("Bass_Free error: %d\n", BASS_ErrorGetCode()); - stream = 0; - } -} - void selectPBdevice() { if (!BASS_SetDevice(openpbdev)) @@ -362,6 +389,24 @@ void selectCAPdevice() printf("BASS_SetDevice: %d err:%d\n", opencapdev, BASS_ErrorGetCode()); } +void close_audio() +{ + if(stream != 0) + { + printf("close Audio Devices\n"); + selectCAPdevice(); + BASS_ChannelStop(rchan); + int rr = BASS_RecordFree(); + if (!rr) printf("Bass_RecordFree error: %d\n", BASS_ErrorGetCode()); + + selectPBdevice(); + BASS_StreamFree(stream); + int r = BASS_Free(); + if(!r) printf("Bass_Free error: %d\n", BASS_ErrorGetCode()); + stream = 0; + } +} + void setPBvolume(int v) { // the volume comes in % 0..99 @@ -429,7 +474,7 @@ void setVolume(int pbcap, int v) { if (pbcap == 0) setPBvolume(v); else setCAPvolume(v); - } +} // ================ thread safe fifo for audio callback routines =============== @@ -460,9 +505,8 @@ void CAP_UNLOCK() { pthread_mutex_unlock(&cap_crit_sec); } void PB_UNLOCK() { pthread_mutex_unlock(&pb_crit_sec); } #endif -#define AUDIO_BUFFERMAXTIME 2 // fifo can buffer this time in [s] #define AUDIO_PLAYBACK_BUFLEN (48000 * 10) // space for 10 seconds of samples -#define AUDIO_CAPTURE_BUFLEN (48000) // space for 1s +#define AUDIO_CAPTURE_BUFLEN 24000 // space for 0.5s int cap_wridx=0; int cap_rdidx=0; @@ -496,6 +540,10 @@ void cap_write_fifo(float sample) cap_buffer[cap_wridx] = sample; if(++cap_wridx >= AUDIO_CAPTURE_BUFLEN) cap_wridx = 0; CAP_UNLOCK(); + + // if monitoring is activated then write it also to the voice fifo + if (VoiceAudioMode == VOICEMODE_LISTENAUDIOIN) + toVoice(sample); } int cap_read_fifo(float *data) @@ -516,6 +564,35 @@ int cap_read_fifo(float *data) return 1; } +void cap_write_fifo_clear() +{ + cap_wridx = cap_rdidx = 0; +} + +int cap_fifo_freespace() +{ + int freebuf = 0; + + CAP_LOCK; + + int elemInFifo = (cap_wridx + AUDIO_CAPTURE_BUFLEN - cap_rdidx) % AUDIO_CAPTURE_BUFLEN; + freebuf = AUDIO_CAPTURE_BUFLEN - elemInFifo; + + CAP_UNLOCK(); + + return freebuf; +} + +int cap_fifo_usedPercent() +{ + int fs = cap_fifo_freespace(); + int used = AUDIO_CAPTURE_BUFLEN - fs; + used = (used * 100) / AUDIO_CAPTURE_BUFLEN; + if (used < 5) printf("used:%d\n", used); + return used; +} + + void pb_write_fifo(float sample) { PB_LOCK; @@ -580,6 +657,7 @@ int pb_read_fifo(float *data, int elements) { // Fifo empty, no data available PB_UNLOCK(); + //printf("pb fifo empty: TX underrun\n"); //printf("pb fifo empty, need:%d have:%d size:%d\n",elements,e,AUDIO_PLAYBACK_BUFLEN); return 0; } @@ -595,7 +673,13 @@ int pb_read_fifo(float *data, int elements) return 1; } -// ================ Play FLAC Audio File =========================== +void clear_audio_fifos() +{ + pb_write_fifo_clear(); + cap_write_fifo_clear(); +} + +// ================ Play PCM Audio File =========================== typedef struct _AUDIOFILES_ { char fn[256]; diff --git a/hsmodem/audio/amsat.flac b/hsmodem/audio/amsat.flac deleted file mode 100644 index 6f5f0f0..0000000 Binary files a/hsmodem/audio/amsat.flac and /dev/null differ diff --git a/hsmodem/audio_voice.cpp b/hsmodem/audio_voice.cpp new file mode 100755 index 0000000..d291e15 --- /dev/null +++ b/hsmodem/audio_voice.cpp @@ -0,0 +1,500 @@ +/* +* High Speed modem to transfer data in a 2,7kHz SSB channel +* ========================================================= +* Author: DJ0ABR +* +* (c) DJ0ABR +* www.dj0abr.de +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* audio.c ... very similar to audio.c but is used for Microphone / Loudspeaker +* +*/ + +#include "hsmodem.h" + +void init_pipes_voice(); +BOOL CALLBACK RecordingCallback_voice(HRECORD handle, const void* buffer, DWORD length, void* user); +DWORD CALLBACK WriteStream_voice(HSTREAM handle, float* buffer, DWORD length, void* user); +//void CALLBACK EncodeProc(HENCODE handle, DWORD channel, const void* buffer, DWORD length, void* user); +void cap_write_fifo_voice(float sample); +int pb_read_fifo_voice(float* data, int elements); +void setLSvolume(int v); +void setMICvolume(int v); + +extern AUDIODEVS audioPBdevs[100]; +extern AUDIODEVS audioCAPdevs[100]; +extern int pbanz; +extern int capanz; + + +HRECORD rchan_voice = 0; // recording channel +BASS_INFO info_voice; +HSTREAM stream_voice = 0; + +int openpbdev_voice = -1; +int opencapdev_voice = -1; +int caprate_voice = VOICE_SAMPRATE; + +int initialLSvol = -1; +int initialMICvol = -1; + +float softwareCAPvolume_voice = 1; + +// pbdev, capdev: -1=default device +int init_audio_voice(int setpbdev, int setcapdev) +{ + static int f = 1; + int ret = 0; + + if (f == 1) + { + // do only once after program start + f = 0; + init_pipes_voice(); + } + + // translate requested device numbers to bass device numbers + if (setpbdev < 0 || setpbdev >= pbanz) setpbdev = 0; + if (setcapdev < 0 || setcapdev >= capanz) setcapdev = 0; + + int pbdev = -1; + if (setpbdev >= 0 && setpbdev < pbanz) pbdev = audioPBdevs[setpbdev].bassdev; + int capdev = -2; + if (setcapdev >= 0 && setcapdev < capanz) capdev = audioCAPdevs[setcapdev].bassdev; + + printf("voice: init audio_voice, caprate:%d\n", caprate_voice); + printf("voice: requested LS device: %d bassno:%d name:%s\n", setpbdev, pbdev, audioPBdevs[setpbdev].name); + printf("voice: requested MIC device: %d bassno:%d name:%s\n", setcapdev, capdev, audioCAPdevs[setcapdev].name); + +#ifdef _WIN32_ + // use WASAPI for Windows to get exclusive access to sound card + return init_wasapi_voice(pbdev, capdev); +#endif + +#ifdef _LINUX_ + close_audio_voice(); + + if (VoiceAudioMode == 0) return 0; // Voice off + + // ===== PLAYBACK ====== + + // initialize default output device + if (!BASS_Init(pbdev, caprate_voice, 0, NULL, NULL)) + { + printf("voice: Can't initialize output device: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + close_audio_voice(); + ret = 1; + } + else + { + + // read real device number + int device = BASS_GetDevice(); + if (device == -1) + { + printf("voice: BASS_GetDevice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + close_audio_voice(); + ret = 1; + } + else + { + pbdev = device; + openpbdev_voice = pbdev; + printf("voice: real BASS PB Device No: %d\n", pbdev); + + // set play callback + BASS_GetInfo(&info_voice); + stream_voice = BASS_StreamCreate(info_voice.freq, 2, BASS_SAMPLE_FLOAT, (STREAMPROC*)WriteStream_voice, 0); // sample: 32 bit float + BASS_ChannelSetAttribute(stream_voice, BASS_ATTRIB_BUFFER, 0); // no buffering for minimum latency + BASS_ChannelPlay(stream_voice, FALSE); // start it + + setLSvolume(initialLSvol); + } + } + + // ===== CAPTURE ==== + + // initalize default recording device + if (!BASS_RecordInit(capdev)) + { + printf("voice: Can't initialize recording device: %d err:%d\n", capdev, BASS_ErrorGetCode()); + close_audio_voice(); + ret |= 2; + } + else + { + + // read real device number + int device = BASS_RecordGetDevice(); + if (device == -1) + { + printf("voice: BASS_GetDevice: %d err:%d\n", capdev, BASS_ErrorGetCode()); + close_audio_voice(); + ret |= 2; + } + else + { + capdev = device; + printf("voice: real BASS CAP Device No: %d\n", capdev); + + // set capture callback + rchan_voice = BASS_RecordStart(caprate_voice, 2, BASS_SAMPLE_FLOAT, RecordingCallback_voice, 0); + if (!rchan_voice) { + printf("voice: Can't start capturing: %d\n", BASS_ErrorGetCode()); + close_audio_voice(); + ret |= 2; + } + else + { + opencapdev_voice = capdev; + setMICvolume(initialMICvol); + } + } + } + + if (ret == 0) + printf("voice started successfully for PBdev:%d and CAPdev:%d\n", openpbdev_voice, opencapdev_voice); + else + { + opencapdev_voice = -1; + openpbdev_voice = -1; + readAudioDevices(); + } + if (ret == 1) + printf("voice initialized: PBerror CapOK\n"); + if (ret == 2) + printf("voice initialized: PBOK CapERROR\n"); + if (ret == 3) + printf("voice initialized: PBerror CapERROR\n"); + +#endif + + return ret; +} + +#ifdef _LINUX_ +void selectPBdevice_voice() +{ + if (!BASS_SetDevice(openpbdev_voice)) + printf("BASS_SetDevice: %d err:%d\n", openpbdev_voice, BASS_ErrorGetCode()); +} + +void selectCAPdevice_voice() +{ + if (!BASS_SetDevice(opencapdev_voice)) + printf("BASS_SetDevice: %d err:%d\n", opencapdev_voice, BASS_ErrorGetCode()); +} + +void close_audio_voice() +{ + printf("voice: close Audio Devices\n"); + if (stream_voice > 0) + BASS_StreamFree(stream_voice); + + if (openpbdev_voice != -1) + { + selectPBdevice_voice(); + int r = BASS_Free(); + if (!r) printf("voice: Bass_Free error: %d\n", BASS_ErrorGetCode()); + } + + if (rchan_voice > 0) + BASS_ChannelStop(rchan_voice); + + if (opencapdev_voice != -1) + { + selectCAPdevice_voice(); + int rr = BASS_RecordFree(); + if (!rr) printf("voice: Bass_RecordFree error: %d\n", BASS_ErrorGetCode()); + } + + openpbdev_voice = -1; + opencapdev_voice = -1; + rchan_voice = 0; + stream_voice = 0; +} + +void setLSvolume(int v) +{ + if (v < 0 || v>100) return; + + // the volume comes in % 0..99 + // map to 0..1 + float vf = v; + vf /= 100; + + //printf("set PB volume to:%d / %f [0..1]\n", v, vf ); + + selectPBdevice_voice(); + if (!BASS_SetVolume(vf)) + printf("setPBvolume: %d err:%d\n", openpbdev_voice, BASS_ErrorGetCode()); +} + +void setMICvolume(int v) +{ + if (v < 0 || v>100) return; + + // the volume comes in % 0..99 + // map to min/maxPBvol + float vf = v; + vf /= 100; + + //printf("set CAP volume to:%d / %f [0..1]\n", v, vf); + + selectCAPdevice_voice(); + if (!BASS_RecordSetInput(-1, BASS_INPUT_ON, vf)) + { + printf("setCAPvolume: %d err:%d, using software level\n", opencapdev_voice, BASS_ErrorGetCode()); + softwareCAPvolume_voice = ((float)v / 100); + } +} + + +// capture callback +BOOL CALLBACK RecordingCallback_voice(HRECORD handle, const void* buffer, DWORD length, void* user) +{ + //printf("captured %ld samples, channels:%d\n",length/sizeof(float),2); + //measure_speed(length/sizeof(float)); + + float* fbuffer = (float*)buffer; + //showbytestringf((char*)"cap:", fbuffer, 10); + //printf("w:%ld ",length/sizeof(float)); + for (unsigned int i = 0; i < (length / sizeof(float)); i += 2) + { + //printf("%f\n",fbuffer[i]); + cap_write_fifo_voice(fbuffer[i]); + } + + return TRUE; // continue recording +} + +// play callback +// length: bytes. float=4byte, 2channels, so it requests samples*8 +DWORD CALLBACK WriteStream_voice(HSTREAM handle, float* buffer, DWORD length, void* user) +{ + //printf("requested %ld samples\n", length / sizeof(float)); + int ret = pb_read_fifo_voice(buffer, length / sizeof(float)); + if (ret == 0) + { + // fifo empty, send 00 + memset(buffer, 0, length); + } + return length; +} + +#endif + +// set volume +void setVolume_voice(int pbcap, int v) +{ + if (pbcap == 0) setLSvolume(v); + else setMICvolume(v); +} + +// ================= resampling and other tasks for voice audio ================= + +// samples come from the data-audio capture with a speed of caprate +// resample (if required) to VOICE_SAMPRATE, which is the voice-audio rate +void toVoice(float sample) +{ + if (caprate == VOICE_SAMPRATE) + { + // resampling not required, just put in LS fifo + pb_write_fifo_voice(sample); + } + else + { + pb_write_fifo_voice(sample); + // samprate of incoming signal is 44100, voice needs 48000 + // we have 44100 samples/s, so we ar missing 3900 S/s. + // if we insert an additional sample every 11 samples + // this results in a rate of 48109 S/s + static int cnt = 0; + if (++cnt >= 11) + { + cnt = 0; + pb_write_fifo_voice(sample); + } + } +} + +// ================= VOICE FIFOs =================== + +#ifdef _WIN32_ +CRITICAL_SECTION cap_crit_sec_voice; +CRITICAL_SECTION pb_crit_sec_voice; +#define CAP_LOCK_VOICE EnterCriticalSection(&cap_crit_sec_voice) +#define PB_LOCK_VOICE EnterCriticalSection(&pb_crit_sec_voice) +void CAP_UNLOCK_VOICE() +{ + if (&cap_crit_sec_voice != NULL) + LeaveCriticalSection(&cap_crit_sec_voice); +} +void PB_UNLOCK_VOICE() +{ + if (&pb_crit_sec_voice != NULL) + LeaveCriticalSection(&pb_crit_sec_voice); +} +#endif + +#ifdef _LINUX_ +pthread_mutex_t cap_crit_sec_voice; +pthread_mutex_t pb_crit_sec_voice; +#define CAP_LOCK_VOICE pthread_mutex_lock(&cap_crit_sec_voice) +void CAP_UNLOCK_VOICE() { pthread_mutex_unlock(&cap_crit_sec_voice); } +#define PB_LOCK_VOICE pthread_mutex_lock(&pb_crit_sec_voice) +void PB_UNLOCK_VOICE() { pthread_mutex_unlock(&pb_crit_sec_voice); } +#endif + +#define AUDIO_PLAYBACK_BUFLEN_VOICE (48000) +#define AUDIO_CAPTURE_BUFLEN_VOICE (48000) + +int cap_wridx_voice = 0; +int cap_rdidx_voice = 0; +float cap_buffer_voice[AUDIO_CAPTURE_BUFLEN_VOICE]; + +int pb_wridx_voice = 0; +int pb_rdidx_voice = 0; +float pb_buffer_voice[AUDIO_PLAYBACK_BUFLEN_VOICE]; + +void init_pipes_voice() +{ +#ifdef _WIN32_ + if (&cap_crit_sec_voice != NULL) DeleteCriticalSection(&cap_crit_sec_voice); + InitializeCriticalSection(&cap_crit_sec_voice); + + if (&pb_crit_sec_voice != NULL) DeleteCriticalSection(&pb_crit_sec_voice); + InitializeCriticalSection(&pb_crit_sec_voice); +#endif +} + +// write one sample into the fifo +// overwrite old data if the fifo is full +void cap_write_fifo_voice(float sample) +{ + if (((cap_wridx_voice + 1) % AUDIO_CAPTURE_BUFLEN_VOICE) == cap_rdidx_voice) + { + //printf("cap_voice fifo full\n"); + CAP_UNLOCK_VOICE(); + return; + } + + CAP_LOCK_VOICE; + cap_buffer_voice[cap_wridx_voice] = sample; + if (++cap_wridx_voice >= AUDIO_CAPTURE_BUFLEN_VOICE) cap_wridx_voice = 0; + CAP_UNLOCK_VOICE(); +} + +int cap_read_fifo_voice(float* data) +{ + CAP_LOCK_VOICE; + + if (cap_rdidx_voice == cap_wridx_voice) + { + // Fifo empty, no data available + CAP_UNLOCK_VOICE(); + return 0; + } + + *data = cap_buffer_voice[cap_rdidx_voice]; + if (++cap_rdidx_voice >= AUDIO_CAPTURE_BUFLEN_VOICE) cap_rdidx_voice = 0; + CAP_UNLOCK_VOICE(); + + return 1; +} + +void cap_write_fifo_clear_voice() +{ + cap_wridx_voice = cap_rdidx_voice = 0; +} + + +void pb_write_fifo_clear_voice() +{ + pb_wridx_voice = pb_rdidx_voice = 0; +} + +int pb_fifo_freespace_voice(int nolock) +{ + int freebuf = 0; + + if (nolock == 0) PB_LOCK_VOICE; + + int elemInFifo = (pb_wridx_voice + AUDIO_PLAYBACK_BUFLEN_VOICE - pb_rdidx_voice) % AUDIO_PLAYBACK_BUFLEN_VOICE; + freebuf = AUDIO_PLAYBACK_BUFLEN_VOICE - elemInFifo; + + if (nolock == 0) PB_UNLOCK_VOICE(); + + return freebuf; +} + +void pb_write_fifo_voice(float sample) +{ + PB_LOCK_VOICE; + + // check if there is free space in fifo + if (pb_fifo_freespace_voice(1) == 0) + { + PB_UNLOCK_VOICE(); + //printf("************* pb fifo_voice full\n"); + return; + } + + pb_buffer_voice[pb_wridx_voice] = sample; + if (++pb_wridx_voice >= AUDIO_PLAYBACK_BUFLEN_VOICE) pb_wridx_voice = 0; + PB_UNLOCK_VOICE(); +} + +int pb_fifo_usedspace_voice() +{ + int anz = pb_fifo_freespace_voice(0); + return AUDIO_PLAYBACK_BUFLEN_VOICE - anz; +} + +// read elements floats from fifo or return 0 if not enough floats are available +int pb_read_fifo_voice(float* data, int elements) +{ + //printf("pb read fifo_voice: %d\n",elements); + PB_LOCK_VOICE; + + int e = AUDIO_PLAYBACK_BUFLEN_VOICE - pb_fifo_freespace_voice(1); + if (e < elements) + { + // Fifo empty, no data available + PB_UNLOCK_VOICE(); + //printf("pb fifo empty, need:%d have:%d size:%d\n",elements,e,AUDIO_PLAYBACK_BUFLEN); + return 0; + } + + for (int i = 0; i < elements; i+=2) + { + // channel1 and the same for channel 2 + data[i] = pb_buffer_voice[pb_rdidx_voice]; + data[i+1] = pb_buffer_voice[pb_rdidx_voice]; + if (++pb_rdidx_voice >= AUDIO_PLAYBACK_BUFLEN_VOICE) pb_rdidx_voice = 0; + } + //printf("read %d floats\n",elements); + + PB_UNLOCK_VOICE(); + return 1; +} + +void clear_voice_fifos() +{ + pb_write_fifo_clear_voice(); + cap_write_fifo_clear_voice(); +} \ No newline at end of file diff --git a/hsmodem/audio_voice_wasapi.cpp b/hsmodem/audio_voice_wasapi.cpp new file mode 100755 index 0000000..a9afafb --- /dev/null +++ b/hsmodem/audio_voice_wasapi.cpp @@ -0,0 +1,270 @@ +/* +* High Speed modem to transfer data in a 2,7kHz SSB channel +* ========================================================= +* Author: DJ0ABR +* +* (c) DJ0ABR +* www.dj0abr.de +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* audio.c ... very similar to audio.c but is used for Microphone / Loudspeaker +* +*/ + +#include "hsmodem.h" + +void cap_write_fifo(float sample); +int pb_read_fifo(float* data, int elements); +void close_wasapi_voice(); +DWORD CALLBACK PBcallback_wasapi_voice(void* buffer, DWORD length, void* user); +DWORD CALLBACK CAPcallback_wasapi_voice(void* buffer, DWORD length, void* user); +void cap_write_fifo_voice(float sample); +int pb_read_fifo_voice(float* data, int elements); + +#define WASAPI_CHANNELS_VOICE 2 + +float minPBvol_voice = 0; +float maxPBvol_voice = 99; +float minCAPvol_voice = 0; +float maxCAPvol_voice = 99; + +extern int openpbdev_voice; +extern int opencapdev_voice; + +extern float softwareCAPvolume_voice; + +int mic_channel_num = 2; + +#ifdef _WIN32_ + +int init_wasapi_voice(int pbdev, int capdev) +{ + int ret = 0; + + close_wasapi_voice(); + + if (VoiceAudioMode == VOICEMODE_OFF) return 0; // Voice off + + // ======= init PLAYBACK device ======== + +// initialize default output device + if (!BASS_WASAPI_Init(pbdev, VOICE_SAMPRATE, WASAPI_CHANNELS_VOICE, BASS_WASAPI_EXCLUSIVE, 0.1f, 0, PBcallback_wasapi_voice, NULL)) + { + printf("Can't initialize wasapi voice output device: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + + // read real device number since a -1 cannot be started + int device = BASS_WASAPI_GetDevice(); + if (device == -1) + { + printf("BASS_WASAPI_GetDevice_voice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + pbdev = device; + + // read the possible volume settings + BASS_WASAPI_INFO info; + if (!BASS_WASAPI_GetInfo(&info)) + { + printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + minPBvol_voice = info.volmin; + maxPBvol_voice = info.volmax; + + // start playback + if (!BASS_WASAPI_Start()) + { + printf("BASS_WASAPI_Start voice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + openpbdev_voice = pbdev; + } + } + } + + // ======= init CAPTURE device ======== + + // initalize default recording device + if (capdev == -1) capdev = -2; // cap: -2 is the default device for input + + BOOL micret = false; + mic_channel_num = 2; + micret = BASS_WASAPI_Init(capdev, VOICE_SAMPRATE, mic_channel_num, BASS_WASAPI_EXCLUSIVE, 0.1f, 0, CAPcallback_wasapi_voice, NULL); + if (!micret) + { + micret = BASS_WASAPI_Init(capdev, VOICE_SAMPRATE, 1, BASS_WASAPI_EXCLUSIVE, 0.1f, 0, CAPcallback_wasapi_voice, NULL); + if (!micret) + { + printf("Can't initialize wasapi voice recording device: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + mic_channel_num = 1; + } + } + + if(micret) + { + printf("mic opened with %d channels\n", mic_channel_num); + // read real device number since a -2 cannot be started + int device = BASS_WASAPI_GetDevice(); + if (device == -1) + { + printf("BASS_WASAPI_GetDevice: voice: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + capdev = device; + + // read the possible volume settings + BASS_WASAPI_INFO info; + if (!BASS_WASAPI_GetInfo(&info)) + { + printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + minCAPvol_voice = info.volmin; + maxCAPvol_voice = info.volmax; + + // start recording + if (!BASS_WASAPI_Start()) + { + printf("BASS_WASAPI_Start voice: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + opencapdev_voice = capdev; + } + } + } + + if (ret == 0) + printf("wasapi voice started successfully for PBdev:%d and CAPdev:%d\n", openpbdev_voice, opencapdev_voice); + else + { + opencapdev_voice = -1; + openpbdev_voice = -1; + readAudioDevices(); + } + if (ret == 1) + printf("wasapi voice initialized: PBerror CapOK\n"); + if (ret == 2) + printf("wasapi voice initialized: PBOK CapERROR\n"); + if (ret == 3) + printf("wasapi voice initialized: PBerror CapERROR\n"); + + return ret; +} + +int selectPBdevice_wasapi_voice() +{ + if (!BASS_WASAPI_SetDevice(openpbdev_voice)) + { + printf("BASS_WASAPI_SetDevice VOICE: %d err:%d\n", openpbdev_voice, BASS_ErrorGetCode()); + return 0; + } + return 1; +} + +int selectCAPdevice_wasapi_voice() +{ + if (!BASS_WASAPI_SetDevice(opencapdev_voice)) + { + printf("BASS_WASAPI_SetDevice VOICE: %d err:%d\n", opencapdev_voice, BASS_ErrorGetCode()); + return 0; + } + return 1; +} + +void close_wasapi_voice() +{ + printf("close WASAPI Voice Devices\n"); + + if (openpbdev_voice != -1) + { + if(selectPBdevice_wasapi_voice()) + if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free voice: dev:%d err:%d\n", openpbdev_voice, BASS_ErrorGetCode()); + } + + if (opencapdev_voice != -1) + { + if(selectCAPdevice_wasapi_voice()) + if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free voice: dev:%d err:%d\n", opencapdev_voice, BASS_ErrorGetCode()); + } + printf("closed WASAPI Voice Devices\n"); +} + +void setLSvolume(int v) +{ + // the volume comes in % 0..99 + // map to min/maxPBvol + float vf = v * (maxPBvol_voice - minPBvol_voice) / 100 + minPBvol_voice; + + if (vf < minPBvol_voice) vf = minPBvol_voice; + if (vf > maxPBvol_voice) vf = maxPBvol_voice; + + //printf("set PB volume to:%d / %f [%f..%f]\n", v, vf, minPBvol_voice, maxPBvol_voice); + + if(selectPBdevice_wasapi_voice()) + if (!BASS_WASAPI_SetVolume(BASS_WASAPI_CURVE_DB, vf)) + printf("setPBvolume: %d err:%d\n", openpbdev_voice, BASS_ErrorGetCode()); +} + +void setMICvolume(int v) +{ + // non of the BASS input level functions are working in WASAPI exclusive mode + // so we adjust the input level by software + softwareCAPvolume_voice = (float)v; + softwareCAPvolume_voice /= 50; +} + +DWORD CALLBACK PBcallback_wasapi_voice(void* buffer, DWORD length, void* user) +{ + float* fbuffer = (float*)buffer; + int ret = pb_read_fifo_voice(fbuffer, length / sizeof(float)); + if (ret == 0) + { + // fifo empty, send 00 + memset(buffer, 0, length); + } + return length; +} + +DWORD CALLBACK CAPcallback_wasapi_voice(void* buffer, DWORD length, void* user) +{ + float* fbuffer = (float*)buffer; + for (unsigned int i = 0; i < (length / sizeof(float)); i += mic_channel_num) + { + cap_write_fifo_voice(fbuffer[i]); + } + + return TRUE; // continue recording +} + +#endif diff --git a/hsmodem/audio_wasapi.cpp b/hsmodem/audio_wasapi.cpp index 84545a6..3828ecc 100755 --- a/hsmodem/audio_wasapi.cpp +++ b/hsmodem/audio_wasapi.cpp @@ -24,14 +24,12 @@ * wasapi is needed because we need exclusive access to the sound card which is not provided for Windows with the normal bass.lib */ - #include "hsmodem.h" #ifdef _WIN32_ #define WASAPI_CHANNELS 2 // wasapi works with 2 only -void init_pipes(); void cap_write_fifo(float sample); int pb_read_fifo(float* data, int elements); void close_wasapi(); @@ -48,104 +46,143 @@ extern int opencapdev; float softwareCAPvolume = 0.5; -int use_wasapi = -1; + int init_wasapi(int pbdev, int capdev) { - close_wasapi(); + int ret = 0; - use_wasapi = -1; + close_wasapi(); // ======= 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_wasapi, NULL)) + if (!BASS_WASAPI_Init(pbdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f, 0, PBcallback_wasapi, NULL)) { printf("Can't initialize output device: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; + ret = 1; } - - // read real device number since a -1 cannot be started - int ret = BASS_WASAPI_GetDevice(); - if (ret == -1) + else { - printf("BASS_WASAPI_GetDevice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; - } - pbdev = ret; - // read the possible volume settings - BASS_WASAPI_INFO info; - if (!BASS_WASAPI_GetInfo(&info)) - { - printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; - } - minPBvol = info.volmin; - maxPBvol = info.volmax; + // read real device number since a -1 cannot be started + int device = BASS_WASAPI_GetDevice(); + if (device == -1) + { + printf("BASS_WASAPI_GetDevice: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + pbdev = device; - // start playback - if (!BASS_WASAPI_Start()) - { - printf("BASS_WASAPI_Start: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; + // read the possible volume settings + BASS_WASAPI_INFO info; + if (!BASS_WASAPI_GetInfo(&info)) + { + printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + { + minPBvol = info.volmin; + maxPBvol = info.volmax; + + // start playback + if (!BASS_WASAPI_Start()) + { + printf("BASS_WASAPI_Start: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret = 1; + } + else + openpbdev = pbdev; + } + } } // ======= init CAPTURE device ======== // 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_wasapi, NULL)) + if (!BASS_WASAPI_Init(capdev, caprate, WASAPI_CHANNELS, BASS_WASAPI_EXCLUSIVE, 0.1f, 0, CAPcallback_wasapi, NULL)) { printf("Can't initialize recording device: %d err:%d\n", capdev, BASS_ErrorGetCode()); - return -1; + ret |= 2; } - - // read real device number since a -2 cannot be started - ret = BASS_WASAPI_GetDevice(); - if (ret == -1) + else { - printf("BASS_WASAPI_GetDevice: %d err:%d\n", capdev, BASS_ErrorGetCode()); - return -1; - } - capdev = ret; - // read the possible volume settings - if (!BASS_WASAPI_GetInfo(&info)) + // read real device number since a -2 cannot be started + int device = BASS_WASAPI_GetDevice(); + if (device == -1) + { + printf("BASS_WASAPI_GetDevice: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + capdev = device; + + // read the possible volume settings + BASS_WASAPI_INFO info; + if (!BASS_WASAPI_GetInfo(&info)) + { + printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + { + minCAPvol = info.volmin; + maxCAPvol = info.volmax; + + // start recording + if (!BASS_WASAPI_Start()) + { + printf("BASS_WASAPI_Start: %d err:%d\n", capdev, BASS_ErrorGetCode()); + ret |= 2; + } + else + opencapdev = capdev; + } + } + } + + if (ret == 0) + printf("WASAPI started successfully for PBdev:%d and CAPdev:%d\n", openpbdev, opencapdev); + else { - printf("BASS_WASAPI_GetInfo: %d err:%d\n", pbdev, BASS_ErrorGetCode()); - return -1; + opencapdev = -1; + openpbdev = -1; + readAudioDevices(); } - minCAPvol = info.volmin; - maxCAPvol = info.volmax; + if (ret == 1) + printf("wasapi audio initialized: PBerror CapOK\n"); + if (ret == 2) + printf("wasapi audio initialized: PBOK CapERROR\n"); + if (ret == 3) + printf("wasapi audio initialized: PBerror CapERROR\n"); - // start recording - if (!BASS_WASAPI_Start()) - { - printf("BASS_WASAPI_Start: %d err:%d\n", capdev, BASS_ErrorGetCode()); - return -1; - } - - printf("WASAPI started successfully for PBdev:%d and CAPdev:%d\n", pbdev, capdev); - - openpbdev = pbdev; - opencapdev = capdev; - - use_wasapi = 0; - - return 0; + return ret; } -void selectPBdevice_wasapi() +int selectPBdevice_wasapi() { if (!BASS_WASAPI_SetDevice(openpbdev)) + { printf("BASS_WASAPI_SetDevice: %d err:%d\n", openpbdev, BASS_ErrorGetCode()); + return 0; + } + return 1; } -void selectCAPdevice_wasapi() +int selectCAPdevice_wasapi() { if (!BASS_WASAPI_SetDevice(opencapdev)) + { printf("BASS_WASAPI_SetDevice: %d err:%d\n", opencapdev, BASS_ErrorGetCode()); + return 0; + } + return 1; } void setPBvolume(int v) @@ -159,9 +196,9 @@ void setPBvolume(int v) //printf("set PB volume to:%d / %f [%f..%f]\n", v, vf, minPBvol, maxPBvol); - selectPBdevice_wasapi(); - if (!BASS_WASAPI_SetVolume(BASS_WASAPI_CURVE_DB, vf)) - printf("setPBvolume: %d err:%d\n", openpbdev, BASS_ErrorGetCode()); + if(selectPBdevice_wasapi()) + if (!BASS_WASAPI_SetVolume(BASS_WASAPI_CURVE_DB, vf)) + printf("setPBvolume: %d err:%d\n", openpbdev, BASS_ErrorGetCode()); } void setCAPvolume(int v) @@ -178,14 +215,14 @@ void close_wasapi() if (openpbdev != -1) { - selectPBdevice_wasapi(); - if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", openpbdev, BASS_ErrorGetCode()); + if(selectPBdevice_wasapi()) + if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", openpbdev, BASS_ErrorGetCode()); } if (opencapdev != -1) { - selectCAPdevice_wasapi(); - if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", opencapdev, BASS_ErrorGetCode()); + if(selectCAPdevice_wasapi()) + if (!BASS_WASAPI_Free()) printf("BASS_WASAPI_Free: dev:%d err:%d\n", opencapdev, BASS_ErrorGetCode()); } } @@ -216,44 +253,7 @@ DWORD CALLBACK PBcallback_wasapi(void* buffer, DWORD length, void* user) free(fdata); return length; } -/* -#define MCHECK 10 -void nullChecker(float fv, float *pbuf, DWORD len) -{ - static float farr[MCHECK]; - static int idx = 0; - static int f = 1; - static int anz = 0; - if (f) - { - f = 0; - for (int i = 0; i < MCHECK; i++) - farr[i] = 1; - } - - farr[idx] = fv; - idx++; - if (idx == MCHECK) idx = 0; - - float nu = 0; - for (int i = 0; i < MCHECK; i++) - { - nu += farr[i]; - } - - if (nu == 0) - { - // how many 00s ar in the current buffer - int a = 0; - for (unsigned int i = 0; i < len-1; i++) - { - if (pbuf[i] == 0 && pbuf[i+1] == 0) a++; - } - printf("=============== null sequence detected: %d len:%d nullanz:%d\n",anz++,len,a); - } -} -*/ DWORD CALLBACK CAPcallback_wasapi(void* buffer, DWORD length, void* user) { //printf("CAP callback, len:%d\n",length); diff --git a/hsmodem/bassenc.h b/hsmodem/bassenc.h new file mode 100644 index 0000000..9e3d55c --- /dev/null +++ b/hsmodem/bassenc.h @@ -0,0 +1,207 @@ +/* + BASSenc 2.4 C/C++ header file + Copyright (c) 2003-2018 Un4seen Developments Ltd. + + See the BASSENC.CHM file for more detailed documentation +*/ + +#ifndef BASSENC_H +#define BASSENC_H + +#include "bass.h" + +#if BASSVERSION!=0x204 +#error conflicting BASS and BASSenc versions +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BASSENCDEF +#define BASSENCDEF(f) WINAPI f +#endif + +typedef DWORD HENCODE; // encoder handle + +// Additional error codes returned by BASS_ErrorGetCode +#define BASS_ERROR_ACM_CANCEL 2000 // ACM codec selection cancelled +#define BASS_ERROR_CAST_DENIED 2100 // access denied (invalid password) + +// Additional BASS_SetConfig options +#define BASS_CONFIG_ENCODE_PRIORITY 0x10300 +#define BASS_CONFIG_ENCODE_QUEUE 0x10301 +#define BASS_CONFIG_ENCODE_CAST_TIMEOUT 0x10310 + +// Additional BASS_SetConfigPtr options +#define BASS_CONFIG_ENCODE_ACM_LOAD 0x10302 +#define BASS_CONFIG_ENCODE_CAST_PROXY 0x10311 + +// BASS_Encode_Start flags +#define BASS_ENCODE_NOHEAD 1 // don't send a WAV header to the encoder +#define BASS_ENCODE_FP_8BIT 2 // convert floating-point sample data to 8-bit integer +#define BASS_ENCODE_FP_16BIT 4 // convert floating-point sample data to 16-bit integer +#define BASS_ENCODE_FP_24BIT 6 // convert floating-point sample data to 24-bit integer +#define BASS_ENCODE_FP_32BIT 8 // convert floating-point sample data to 32-bit integer +#define BASS_ENCODE_FP_AUTO 14 // convert floating-point sample data back to channel's format +#define BASS_ENCODE_BIGEND 16 // big-endian sample data +#define BASS_ENCODE_PAUSE 32 // start encording paused +#define BASS_ENCODE_PCM 64 // write PCM sample data (no encoder) +#define BASS_ENCODE_RF64 128 // send an RF64 header +#define BASS_ENCODE_MONO 0x100 // convert to mono (if not already) +#define BASS_ENCODE_QUEUE 0x200 // queue data to feed encoder asynchronously +#define BASS_ENCODE_WFEXT 0x400 // WAVEFORMATEXTENSIBLE "fmt" chunk +#define BASS_ENCODE_CAST_NOLIMIT 0x1000 // don't limit casting data rate +#define BASS_ENCODE_LIMIT 0x2000 // limit data rate to real-time +#define BASS_ENCODE_AIFF 0x4000 // send an AIFF header rather than WAV +#define BASS_ENCODE_DITHER 0x8000 // apply dither when converting floating-point sample data to integer +#define BASS_ENCODE_AUTOFREE 0x40000 // free the encoder when the channel is freed + +// BASS_Encode_GetACMFormat flags +#define BASS_ACM_DEFAULT 1 // use the format as default selection +#define BASS_ACM_RATE 2 // only list formats with same sample rate as the source channel +#define BASS_ACM_CHANS 4 // only list formats with same number of channels (eg. mono/stereo) +#define BASS_ACM_SUGGEST 8 // suggest a format (HIWORD=format tag) + +// BASS_Encode_GetCount counts +#define BASS_ENCODE_COUNT_IN 0 // sent to encoder +#define BASS_ENCODE_COUNT_OUT 1 // received from encoder +#define BASS_ENCODE_COUNT_CAST 2 // sent to cast server +#define BASS_ENCODE_COUNT_QUEUE 3 // queued +#define BASS_ENCODE_COUNT_QUEUE_LIMIT 4 // queue limit +#define BASS_ENCODE_COUNT_QUEUE_FAIL 5 // failed to queue + +// BASS_Encode_CastInit content MIME types +#define BASS_ENCODE_TYPE_MP3 "audio/mpeg" +#define BASS_ENCODE_TYPE_OGG "audio/ogg" +#define BASS_ENCODE_TYPE_AAC "audio/aacp" + +// BASS_Encode_CastGetStats types +#define BASS_ENCODE_STATS_SHOUT 0 // Shoutcast stats +#define BASS_ENCODE_STATS_ICE 1 // Icecast mount-point stats +#define BASS_ENCODE_STATS_ICESERV 2 // Icecast server stats + +typedef void (CALLBACK ENCODEPROC)(HENCODE handle, DWORD channel, const void *buffer, DWORD length, void *user); +/* Encoding callback function. +handle : The encoder +channel: The channel handle +buffer : Buffer containing the encoded data +length : Number of bytes +user : The 'user' parameter value given when starting the encoder */ + +typedef void (CALLBACK ENCODEPROCEX)(HENCODE handle, DWORD channel, const void *buffer, DWORD length, QWORD offset, void *user); +/* Encoding callback function with offset info. +handle : The encoder +channel: The channel handle +buffer : Buffer containing the encoded data +length : Number of bytes +offset : File offset of the data +user : The 'user' parameter value given when starting the encoder */ + +typedef DWORD (CALLBACK ENCODERPROC)(HENCODE handle, DWORD channel, void *buffer, DWORD length, DWORD maxout, void *user); +/* Encoder callback function. +handle : The encoder +channel: The channel handle +buffer : Buffer containing the PCM data (input) and receiving the encoded data (output) +length : Number of bytes in (-1=closing) +maxout : Maximum number of bytes out +user : The 'user' parameter value given when calling BASS_Encode_StartUser +RETURN : The amount of encoded data (-1=stop) */ + +typedef BOOL (CALLBACK ENCODECLIENTPROC)(HENCODE handle, BOOL connect, const char *client, char *headers, void *user); +/* Client connection notification callback function. +handle : The encoder +connect: TRUE/FALSE=client is connecting/disconnecting +client : The client's address (xxx.xxx.xxx.xxx:port) +headers: Request headers (optionally response headers on return) +user : The 'user' parameter value given when calling BASS_Encode_ServerInit +RETURN : TRUE/FALSE=accept/reject connection (ignored if connect=FALSE) */ + +typedef void (CALLBACK ENCODENOTIFYPROC)(HENCODE handle, DWORD status, void *user); +/* Encoder death notification callback function. +handle : The encoder +status : Notification (BASS_ENCODE_NOTIFY_xxx) +user : The 'user' parameter value given when calling BASS_Encode_SetNotify */ + +// Encoder notifications +#define BASS_ENCODE_NOTIFY_ENCODER 1 // encoder died +#define BASS_ENCODE_NOTIFY_CAST 2 // cast server connection died +#define BASS_ENCODE_NOTIFY_CAST_TIMEOUT 0x10000 // cast timeout +#define BASS_ENCODE_NOTIFY_QUEUE_FULL 0x10001 // queue is out of space +#define BASS_ENCODE_NOTIFY_FREE 0x10002 // encoder has been freed + +// BASS_Encode_ServerInit flags +#define BASS_ENCODE_SERVER_NOHTTP 1 // no HTTP headers +#define BASS_ENCODE_SERVER_META 2 // Shoutcast metadata + +DWORD BASSENCDEF(BASS_Encode_GetVersion)(); + +HENCODE BASSENCDEF(BASS_Encode_Start)(DWORD handle, const char *cmdline, DWORD flags, ENCODEPROC *proc, void *user); +HENCODE BASSENCDEF(BASS_Encode_StartLimit)(DWORD handle, const char *cmdline, DWORD flags, ENCODEPROC *proc, void *user, DWORD limit); +HENCODE BASSENCDEF(BASS_Encode_StartUser)(DWORD handle, const char *filename, DWORD flags, ENCODERPROC *proc, void *user); +BOOL BASSENCDEF(BASS_Encode_AddChunk)(HENCODE handle, const char *id, const void *buffer, DWORD length); +DWORD BASSENCDEF(BASS_Encode_IsActive)(DWORD handle); +BOOL BASSENCDEF(BASS_Encode_Stop)(DWORD handle); +BOOL BASSENCDEF(BASS_Encode_StopEx)(DWORD handle, BOOL queue); +BOOL BASSENCDEF(BASS_Encode_SetPaused)(DWORD handle, BOOL paused); +BOOL BASSENCDEF(BASS_Encode_Write)(DWORD handle, const void *buffer, DWORD length); +BOOL BASSENCDEF(BASS_Encode_SetNotify)(DWORD handle, ENCODENOTIFYPROC *proc, void *user); +QWORD BASSENCDEF(BASS_Encode_GetCount)(DWORD handle, DWORD count); +BOOL BASSENCDEF(BASS_Encode_SetChannel)(DWORD handle, DWORD channel); +DWORD BASSENCDEF(BASS_Encode_GetChannel)(HENCODE handle); +BOOL BASSENCDEF(BASS_Encode_UserOutput)(DWORD handle, QWORD offset, const void *buffer, DWORD length); + +#ifdef _WIN32 +DWORD BASSENCDEF(BASS_Encode_GetACMFormat)(DWORD handle, void *form, DWORD formlen, const char *title, DWORD flags); +HENCODE BASSENCDEF(BASS_Encode_StartACM)(DWORD handle, const void *form, DWORD flags, ENCODEPROC *proc, void *user); +HENCODE BASSENCDEF(BASS_Encode_StartACMFile)(DWORD handle, const void *form, DWORD flags, const char *filename); +#endif + +#ifdef __APPLE__ +HENCODE BASSENCDEF(BASS_Encode_StartCA)(DWORD handle, DWORD ftype, DWORD atype, DWORD flags, DWORD bitrate, ENCODEPROCEX *proc, void *user); +HENCODE BASSENCDEF(BASS_Encode_StartCAFile)(DWORD handle, DWORD ftype, DWORD atype, DWORD flags, DWORD bitrate, const char *filename); +void *BASSENCDEF(BASS_Encode_GetCARef)(DWORD handle); +#endif + +#ifndef _WIN32_WCE +BOOL BASSENCDEF(BASS_Encode_CastInit)(HENCODE handle, const char *server, const char *pass, const char *content, const char *name, const char *url, const char *genre, const char *desc, const char *headers, DWORD bitrate, BOOL pub); +BOOL BASSENCDEF(BASS_Encode_CastSetTitle)(HENCODE handle, const char *title, const char *url); +BOOL BASSENCDEF(BASS_Encode_CastSendMeta)(HENCODE handle, DWORD type, const void *data, DWORD length); +const char *BASSENCDEF(BASS_Encode_CastGetStats)(HENCODE handle, DWORD type, const char *pass); + +DWORD BASSENCDEF(BASS_Encode_ServerInit)(HENCODE handle, const char *port, DWORD buffer, DWORD burst, DWORD flags, ENCODECLIENTPROC *proc, void *user); +BOOL BASSENCDEF(BASS_Encode_ServerKick)(HENCODE handle, const char *client); +#endif + +#ifdef __cplusplus +} + +#ifdef _WIN32 +static inline HENCODE BASS_Encode_Start(DWORD handle, const WCHAR *cmdline, DWORD flags, ENCODEPROC *proc, void *user) +{ + return BASS_Encode_Start(handle, (const char*)cmdline, flags|BASS_UNICODE, proc, user); +} + +static inline HENCODE BASS_Encode_StartLimit(DWORD handle, const WCHAR *cmdline, DWORD flags, ENCODEPROC *proc, void *user, DWORD limit) +{ + return BASS_Encode_StartLimit(handle, (const char *)cmdline, flags|BASS_UNICODE, proc, user, limit); +} + +static inline HENCODE BASS_Encode_StartUser(DWORD handle, const WCHAR *filename, DWORD flags, ENCODERPROC *proc, void *user) +{ + return BASS_Encode_StartUser(handle, (const char *)filename, flags|BASS_UNICODE, proc, user); +} + +static inline DWORD BASS_Encode_GetACMFormat(DWORD handle, void *form, DWORD formlen, const WCHAR *title, DWORD flags) +{ + return BASS_Encode_GetACMFormat(handle, form, formlen, (const char *)title, flags|BASS_UNICODE); +} + +static inline HENCODE BASS_Encode_StartACMFile(DWORD handle, const void *form, DWORD flags, const WCHAR *filename) +{ + return BASS_Encode_StartACMFile(handle, form, flags|BASS_UNICODE, (const char *)filename); +} +#endif +#endif + +#endif diff --git a/hsmodem/bassenc_opus.h b/hsmodem/bassenc_opus.h new file mode 100644 index 0000000..94ce78c --- /dev/null +++ b/hsmodem/bassenc_opus.h @@ -0,0 +1,46 @@ +/* + BASSenc_OPUS 2.4 C/C++ header file + Copyright (c) 2016 Un4seen Developments Ltd. + + See the BASSENC_OPUS.CHM file for more detailed documentation +*/ + +#ifndef BASSENC_OPUS_H +#define BASSENC_OPUS_H + +#include "bassenc.h" + +#if BASSVERSION!=0x204 +#error conflicting BASS and BASSenc_OPUS versions +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BASSENCOPUSDEF +#define BASSENCOPUSDEF(f) WINAPI f +#endif + +DWORD BASSENCOPUSDEF(BASS_Encode_OPUS_GetVersion)(); + +HENCODE BASSENCOPUSDEF(BASS_Encode_OPUS_Start)(DWORD handle, const char *options, DWORD flags, ENCODEPROC *proc, void *user); +HENCODE BASSENCOPUSDEF(BASS_Encode_OPUS_StartFile)(DWORD handle, const char *options, DWORD flags, const char *filename); + +#ifdef __cplusplus +} + +#ifdef _WIN32 +static inline HENCODE BASS_Encode_OPUS_Start(DWORD handle, const WCHAR *options, DWORD flags, ENCODEPROC *proc, void *user) +{ + return BASS_Encode_OPUS_Start(handle, (const char*)options, flags|BASS_UNICODE, proc, user); +} + +static inline HENCODE BASS_Encode_OPUS_StartFile(DWORD handle, const WCHAR *options, DWORD flags, const WCHAR *filename) +{ + return BASS_Encode_OPUS_StartFile(handle, (const char*)options, flags|BASS_UNICODE, (const char*)filename); +} +#endif +#endif + +#endif diff --git a/hsmodem/codec2.cpp b/hsmodem/codec2.cpp new file mode 100755 index 0000000..7db49b0 --- /dev/null +++ b/hsmodem/codec2.cpp @@ -0,0 +1,166 @@ +/* +* High Speed modem to transfer data in a 2,7kHz SSB channel +* ========================================================= +* Author: DJ0ABR +* +* (c) DJ0ABR +* www.dj0abr.de +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* codec2.c ... function to handle voice transfer via codec2 +* +*/ + +#include "hsmodem.h" + +void sendCodecToModulator(uint8_t* pdata, int len); + +struct CODEC2 *pc2 = NULL; +int samplesPerPacket = 160; +int bytesPerPacket = 8; + +void init_codec2() +{ + close_codec2(); + + if (speedmode == 0) + pc2 = codec2_create(CODEC2_MODE_1600); + else if(speedmode == 1) + pc2 = codec2_create(CODEC2_MODE_2400); + else + pc2 = codec2_create(CODEC2_MODE_3200); + + if (pc2 == NULL) + { + printf("cannot create CODEC2\n"); + } + codec2_set_natural_or_gray(pc2, 0); + bytesPerPacket = codec2_bits_per_frame(pc2) / 8; + samplesPerPacket = codec2_samples_per_frame(pc2); + printf("Codec2: BytesPerFrame:%d SamplesPerFrame:%d\n", bytesPerPacket, samplesPerPacket); +} + +void close_codec2() +{ + if (pc2 != NULL) + { + codec2_destroy(pc2); + } + pc2 = NULL; +} + +// encode 160 voice samples (8kS/s) into 64 bits output +void encode_codec2(float f) +{ + static int decim = 0; + static int16_t sbuf[500]; // this is easily more than "samplesPerPacket" in any cases + static int fbuf_idx = 0; + uint8_t outbuf[50]; // this is easily more than "bytesPerPacket" in any cases + + if (pc2 == NULL) return; + + // this encoder is called with a sound card sample rate of 48000 + // codec2 needs 8 kS/s, so we have to decimate by 6 + if (++decim >= 6) + { + decim = 0; + + // here we have a sample rate of 8 kS/s + // one encoding call needs 160 samples + sbuf[fbuf_idx] = (int16_t)(f * 32768); // convert to short + if (++fbuf_idx >= samplesPerPacket) + { + fbuf_idx = 0; + + // we have 160 samples in fbuf, encode them now + codec2_encode(pc2, outbuf, sbuf); + + // outbuf is 64bit = 8byte long + + // send Codec data to modulator + if (VoiceAudioMode == VOICEMODE_DV_FULLDUPLEX) + { + memmove(outbuf + 1, outbuf, bytesPerPacket); + outbuf[0] = 0xff; // start of codec2 packet marker + sendCodecToModulator(outbuf, bytesPerPacket+1); + } + + if (VoiceAudioMode == VOICEMODE_CODECLOOP) + { + // codec loop mode: decode and play it + int16_t spbbuf[500]; + codec2_decode(pc2, spbbuf, outbuf); + + for (int i = 0; i < samplesPerPacket; i++) + { + float f = (float)spbbuf[i]; + f /= 32768; + // here we have 8kS/s, need to interpolate to 48 kS/s + for(int x=0; x<6; x++) + pb_write_fifo_voice(f); + } + } + } + } +} + +#define CHUNKSIZE_VOICE 40 + +void toCodecDecoder_codec2(uint8_t* pdata, int len) +{ + static uint8_t chunk[50]; + + // go through all data bytes + for (int vd = 0; vd < len; vd++) + { + // shift the data through the chunk buffer + for (int i = 0; i < CHUNKSIZE_VOICE - 1; i++) + chunk[i] = chunk[i + 1]; + chunk[CHUNKSIZE_VOICE - 1] = pdata[vd]; + + // an Codec-2 packet has max length of max 8 Byte + // in the chunk size of 40 fit minimum 4 chunks + // so lets test if 4 chunks are there, by looking for the marker + // at distance bytesPerPacket + int mfound = 1; + for (int m = 0; m < 4; m++) + { + if (chunk[(bytesPerPacket + 1) * m] != 0xff) + { + mfound = 0; + break; + } + } + + if (mfound) + { + //showbytestring("OPUS:", chunk + 1, opusPacketSize, opusPacketSize); + + // codec loop mode: decode and play it + int16_t spbbuf[500]; + codec2_decode(pc2, spbbuf, chunk+1); + + for (int i = 0; i < samplesPerPacket; i++) + { + float f = (float)spbbuf[i]; + f /= 32768; + // here we have 8kS/s, need to interpolate to 48 kS/s + for (int x = 0; x < 6; x++) + pb_write_fifo_voice(f); + } + } + } +} \ No newline at end of file diff --git a/hsmodem/codec2.h b/hsmodem/codec2.h new file mode 100755 index 0000000..c2dcf70 --- /dev/null +++ b/hsmodem/codec2.h @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2.h + AUTHOR......: David Rowe + DATE CREATED: 21 August 2010 + + Codec 2 fully quantised encoder and decoder functions. If you want use + Codec 2, these are the functions you need to call. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifndef __CODEC2__ +#define __CODEC2__ + +#include "version.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define CODEC2_MODE_3200 0 +#define CODEC2_MODE_2400 1 +#define CODEC2_MODE_1600 2 +#define CODEC2_MODE_1400 3 +#define CODEC2_MODE_1300 4 +#define CODEC2_MODE_1200 5 +#define CODEC2_MODE_700C 8 +#define CODEC2_MODE_450 10 +#define CODEC2_MODE_450PWB 11 + +#ifndef CODEC2_MODE_EN_DEFAULT +#define CODEC2_MODE_EN_DEFAULT 1 +#endif + +// by default we enable all modes +// disable during compile time with -DCODEC2_MODE_1600_EN=0 +// all but CODEC2 1600 are enabled then + +//or the other way round +// -DCODEC2_MODE_EN_DEFAULT=0 -DCODEC2_MODE_1600_EN=1 +// only CODEC2 Mode 1600 + +#if !defined(CODEC2_MODE_3200_EN) + #define CODEC2_MODE_3200_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_2400_EN) + #define CODEC2_MODE_2400_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_1600_EN) + #define CODEC2_MODE_1600_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_1400_EN) + #define CODEC2_MODE_1400_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_1300_EN) + #define CODEC2_MODE_1300_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_1200_EN) + #define CODEC2_MODE_1200_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_700C_EN) + #define CODEC2_MODE_700C_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_450_EN) + #define CODEC2_MODE_450_EN CODEC2_MODE_EN_DEFAULT +#endif +#if !defined(CODEC2_MODE_450PWB_EN) + #define CODEC2_MODE_450PWB_EN CODEC2_MODE_EN_DEFAULT +#endif + +#define CODEC2_MODE_ACTIVE(mode_name, var) ((mode_name##_EN) == 0 ? 0: (var) == mode_name) + +struct CODEC2; + +struct CODEC2 * codec2_create(int mode); +void codec2_destroy(struct CODEC2 *codec2_state); +void codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]); +void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits); +void codec2_decode_ber(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits, float ber_est); +int codec2_samples_per_frame(struct CODEC2 *codec2_state); +int codec2_bits_per_frame(struct CODEC2 *codec2_state); + +void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma); +int codec2_get_spare_bit_index(struct CODEC2 *codec2_state); +int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, char unpacked_bits[]); +void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); +void codec2_set_softdec(struct CODEC2 *c2, float *softdec); +float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); + +// support for ML and VQ experiments +void codec2_open_mlfeat(struct CODEC2 *codec2_state, char *feat_filename, char *model_filename); +void codec2_load_codebook(struct CODEC2 *codec2_state, int num, char *filename); +float codec2_get_var(struct CODEC2 *codec2_state); +float *codec2_enable_user_ratek(struct CODEC2 *codec2_state, int *K); + +// 700C post filter and equaliser +void codec2_700c_post_filter(struct CODEC2 *codec2_state, int en); +void codec2_700c_eq(struct CODEC2 *codec2_state, int en); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/hsmodem/fft.cpp b/hsmodem/fft.cpp index 1d6e2c5..ad78663 100755 --- a/hsmodem/fft.cpp +++ b/hsmodem/fft.cpp @@ -104,18 +104,19 @@ uint16_t *make_waterfall(float fre, int *retlen) void init_fft() { + /* char fn[300]; + * storing to a file in the working directory may be a problem under Windows, so we do not use wisdom files + sprintf(fn, "capture_fft_%d", fft_rate); // wisdom file for each capture rate - sprintf(fn, "capture_fft_%d", fft_rate); // wisdom file for each capture rate - - fftw_import_wisdom_from_filename(fn); + fftw_import_wisdom_from_filename(fn);*/ din = (double *)fftw_malloc(sizeof(double) * fft_rate); cpout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * fft_rate); plan = fftw_plan_dft_r2c_1d(fft_rate, din, cpout, FFTW_MEASURE); - fftw_export_wisdom_to_filename(fn); + //fftw_export_wisdom_to_filename(fn); } void exit_fft() diff --git a/hsmodem/frame_packer.cpp b/hsmodem/frame_packer.cpp index 0461514..6cb8866 100755 --- a/hsmodem/frame_packer.cpp +++ b/hsmodem/frame_packer.cpp @@ -254,14 +254,12 @@ uint8_t *unpack_data(uint8_t *rxd, int len) { memcpy(payload,pl, PAYLOADLEN+10); framerdy = 1; - if(symnum != 688) - printf("Header found, rotation: %d at symbol no.: %d result: OK\n", rotations, symnum); + //if(symnum != 688) printf("Header found, rotation: %d at symbol no.: %d result: OK\n", rotations, symnum); symnum = 0; } else { - if((symnum % ((UDPBLOCKLEN * 8) / bitsPerSymbol)) == 0) - printf("Header found, rotation: %d at symbol no.: %d result: %d\n", rotations, symnum, getPayload_error); + //if((symnum % ((UDPBLOCKLEN * 8) / bitsPerSymbol)) == 0) printf("Header found, rotation: %d at symbol no.: %d result: %d\n", rotations, symnum, getPayload_error); } } } diff --git a/hsmodem/hsmodem.cpp b/hsmodem/hsmodem.cpp index 8398a43..446b5ef 100755 --- a/hsmodem/hsmodem.cpp +++ b/hsmodem/hsmodem.cpp @@ -73,7 +73,7 @@ int keeprunning = 1; // UDP I/O int BC_sock_AppToModem = -1; int DATA_sock_AppToModem = -1; -int DATA_sock_from_GR = -1; +//int DATA_sock_from_GR = -1; int DATA_sock_FFT_from_GR = -1; int DATA_sock_I_Q_from_GR = -1; @@ -81,17 +81,11 @@ int UdpBCport_AppToModem = 40131; int UdpDataPort_AppToModem = 40132; int UdpDataPort_ModemToApp = 40133; -int UdpDataPort_toGR = 40134; -int UdpDataPort_fromGR = 40135; -int UdpDataPort_fromGR_FFT = 40136; -int UdpDataPort_fromGR_I_Q = 40137; - // op mode depending values // default mode if not set by the app int speedmode = 2; int bitsPerSymbol = 2; // QPSK=2, 8PSK=3 int constellationSize = 4; // QPSK=4, 8PSK=8 -int psk8mode=0; // 0=APSK8, 1=PSK8 char localIP[] = { "127.0.0.1" }; char ownfilename[] = { "hsmodem" }; @@ -106,9 +100,16 @@ int linespeed = 4410; int captureDeviceNo = -1; int playbackDeviceNo = -1; +int MicDeviceNo = -1; +int LSDeviceNo = -1; int initialPBvol = -1; int initialCAPvol = -1; int announcement = 0; +int VoiceAudioMode = VOICEMODE_OFF; +int codec = 1; // 0=opus, 1=codec2 + +int init_audio_result = 0; +int init_voice_result = 0; int main(int argc, char* argv[]) { @@ -169,17 +170,19 @@ int main(int argc, char* argv[]) } } #endif + init_packer(); - initFEC(); init_fft(); - int ar = init_audio(playbackDeviceNo, captureDeviceNo); + init_voiceproc(); + + /*int ar = init_audio(playbackDeviceNo, captureDeviceNo); if (ar == -1) { keeprunning = 0; exit(0); - } + }*/ // start udp RX to listen for broadcast search message from Application UdpRxInit(&BC_sock_AppToModem, UdpBCport_AppToModem, &bc_rxdata, &keeprunning); @@ -188,7 +191,7 @@ int main(int argc, char* argv[]) UdpRxInit(&DATA_sock_AppToModem, UdpDataPort_AppToModem, &appdata_rxdata, &keeprunning); // start udp RX to listen for data from GR Receiver - UdpRxInit(&DATA_sock_from_GR, UdpDataPort_fromGR, &GRdata_rxdata, &keeprunning); + //UdpRxInit(&DATA_sock_from_GR, UdpDataPort_fromGR, &GRdata_rxdata, &keeprunning); printf("QO100modem initialised and running\n"); @@ -201,9 +204,46 @@ int main(int argc, char* argv[]) } //doArraySend(); + if (VoiceAudioMode == VOICEMODE_INTERNALLOOP) + { + // loop voice mic to LS + float f; + if (cap_read_fifo_voice(&f)) + { + if(softwareCAPvolume_voice >= 0) + f *= softwareCAPvolume_voice; + pb_write_fifo_voice(f); + } + } - if (demodulator() == 0) - sleep_ms(10); + if (VoiceAudioMode == VOICEMODE_CODECLOOP || VoiceAudioMode == VOICEMODE_DV_FULLDUPLEX) + { + // send mic to codec + float f; + if (cap_read_fifo_voice(&f)) + { + if (softwareCAPvolume_voice >= 0) + f *= softwareCAPvolume_voice; + encode(f); + } + } + + // demodulate incoming audio data stream + static int old_tm = 0; + int tm = getus(); + if (tm >= (old_tm + 1000000)) + { + // read Audio device list every 1s + readAudioDevices(); + old_tm = tm; + } + + int dret = demodulator(); + +#ifdef _LINUX_ + if(dret == 0) + usleep(1); +#endif } printf("stopped: %d\n", keeprunning); @@ -225,32 +265,26 @@ typedef struct { int rx; int bpsym; int linespeed; + int codecrate; } SPEEDRATE; +// AudioRate, TX-Resampler, RX-Resampler/4, bit/symbol, Codec-Rate SPEEDRATE sr[8] = { // QPSK modes - {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}, + {48000, 32, 8, 2, 3000, 2400}, + {48000, 24, 6, 2, 4000, 3200}, + {44100, 20, 5, 2, 4410, 3600}, + {48000, 20, 5, 2, 4800, 4000}, // 8PSK modes - {44100, 24, 6, 3, 5500}, - {48000, 24, 6, 3, 6000}, - {44100, 20, 5, 3, 6600}, - {48000, 20, 5, 3, 7200} + {44100, 24, 6, 3, 5500, 4400}, + {48000, 24, 6, 3, 6000, 4800}, + {44100, 20, 5, 3, 6600, 5200}, + {48000, 20, 5, 3, 7200, 6000} }; void startModem() { - if (speedmode >= 8) - { - speedmode = speedmode - 4; - psk8mode = 1; - } - else - psk8mode = 0; - bitsPerSymbol = sr[speedmode].bpsym; constellationSize = (1 << bitsPerSymbol); // QPSK=4, 8PSK=8 @@ -258,16 +292,17 @@ void startModem() txinterpolfactor = sr[speedmode].tx; rxPreInterpolfactor = sr[speedmode].rx; linespeed = sr[speedmode].linespeed; + opusbitrate = sr[speedmode].codecrate; // int TX audio and modulator close_dsp(); - init_audio(playbackDeviceNo, captureDeviceNo); + init_audio_result = init_audio(playbackDeviceNo, captureDeviceNo); setPBvolume(initialPBvol); setCAPvolume(initialCAPvol); init_dsp(); } -void setAudioDevices(int pb, int cap, int pbvol, int capvol, int announce) +void setAudioDevices(int pb, int cap, int pbvol, int capvol, int announce, int pbls, int pbmic) { //printf("%d %d\n", pb, cap); @@ -278,6 +313,8 @@ void setAudioDevices(int pb, int cap, int pbvol, int capvol, int announce) captureDeviceNo = cap; initialPBvol = pbvol; initialCAPvol = capvol; + initialLSvol = pbls; + initialMICvol = pbmic; } announcement = announce; @@ -288,7 +325,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], pdata[5]); + setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], pdata[6], pdata[7]); char rxip[20]; strcpy(rxip, inet_ntoa(rxsock->sin_addr)); @@ -335,6 +372,11 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) if (type == 16) { // Byte 1 contains the resampler ratio for TX and RX modem + if (pdata[1] >= 8) + { + printf("wrong speedmode %d, ignoring\n", pdata[1]); + return; + } speedmode = pdata[1]; printf("set speedmode to %d\n", speedmode); restart_modems = 1; @@ -394,6 +436,42 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) return; } + if (type == 23) + { + // set playback volume (in % 0..100) + setVolume_voice(0, minfo); + return; + } + + if (type == 24) + { + // set capture volume (in % 0..100) + setVolume_voice(1, minfo); + return; + } + + if (type == 25) + { + //printf("%d %d %d %d %d\n", pdata[0], pdata[1], pdata[2], pdata[3], pdata[4]); + LSDeviceNo = pdata[1]; + MicDeviceNo = pdata[2]; + VoiceAudioMode = pdata[3]; + codec = pdata[4]; + + // init voice audio + init_voice_result = init_audio_voice(LSDeviceNo, MicDeviceNo); + init_voiceproc(); + + return; + } + + if (type == 26) + { + // GUI requests termination of this hsmodem + printf("shut down hsmodem\n"); + closeAllandTerminate(); + } + if (len != (PAYLOADLEN + 2)) { printf("data from app: wrong length:%d (should be %d)\n", len - 2, PAYLOADLEN); @@ -451,12 +529,21 @@ void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) uint8_t* pl = unpack_data(pdata, len); if (pl != NULL) { - // complete frame received - // send payload to app - uint8_t txpl[PAYLOADLEN + 10 + 1]; - memcpy(txpl + 1, pl, PAYLOADLEN + 10); - txpl[0] = 1; // type 1: payload data follows - sendUDP(appIP, UdpDataPort_ModemToApp, txpl, PAYLOADLEN + 10 + 1); + if (VoiceAudioMode != VOICEMODE_DV_FULLDUPLEX) + { + // complete frame received + // send payload to app + uint8_t txpl[PAYLOADLEN + 10 + 1]; + memcpy(txpl + 1, pl, PAYLOADLEN + 10); + txpl[0] = 1; // type 1: payload data follows + sendUDP(appIP, UdpDataPort_ModemToApp, txpl, PAYLOADLEN + 10 + 1); + } + else + { + // send to Codec decoder + if (*(pl + 3) != 0) // minfo=0 ... just a filler, ignore + toCodecDecoder(pl + 10, PAYLOADLEN); + } fnd = 0; } else @@ -464,7 +551,7 @@ void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) // no frame found // if longer ws seconds nothing found, reset liquid RX modem // comes here with symbol rate, i.e. 4000 S/s - int ws = 4; + int ws = 4; int wt = sr[speedmode].audio / sr[speedmode].tx; if (++fnd >= (wt * ws)) { diff --git a/hsmodem/hsmodem.h b/hsmodem/hsmodem.h index 2e406f9..8c70402 100755 --- a/hsmodem/hsmodem.h +++ b/hsmodem/hsmodem.h @@ -30,6 +30,7 @@ #include #include #include +#include "opus.h" #define _USE_MATH_DEFINES #include @@ -37,6 +38,8 @@ #pragma comment(lib, "basswasapi.lib") #pragma comment(lib, "libliquid.lib") #pragma comment(lib, "fftw_lib/libfftw3-3.lib") +#pragma comment(lib, "opus.lib") +#pragma comment(lib, "libcodec2.lib") #endif #ifdef _LINUX_ @@ -52,6 +55,7 @@ #include #include #include +#include #endif #include "bass.h" @@ -62,6 +66,8 @@ #include "fec.h" #include "udp.h" #include "symboltracker.h" +#include "bassenc_opus.h" +#include "codec2.h" #define jpg_tempfilename "rxdata.jpg" @@ -73,6 +79,18 @@ #define MAXDEVSTRLEN 2000 #define CHANNELS 1 // no of channels used +// voice audio sampling rate +#define VOICE_SAMPRATE 48000 // do NOT change, OPUS works with 48k only + +enum _VOICEMODES_ { + VOICEMODE_OFF, + VOICEMODE_LISTENAUDIOIN, + VOICEMODE_INTERNALLOOP, + VOICEMODE_CODECLOOP, + VOICEMODE_DV_FULLDUPLEX, + VOICEMODE_DV_RXONLY +}; + void init_packer(); uint8_t* Pack(uint8_t* payload, int type, int status, int* plen); uint8_t* unpack_data(uint8_t* rxd, int len); @@ -96,7 +114,7 @@ void TX_Scramble(uint8_t* data, int len); uint8_t* RX_Scramble(uint8_t* data, int len); uint16_t Crc16_messagecalc(int rxtx, uint8_t* data, int len); -void showbytestring(char* title, uint8_t* data, int anz); +void showbytestring(char* title, uint8_t* data, int totallen, int anz); void measure_speed_syms(int len); void measure_speed_bps(int len); @@ -106,6 +124,7 @@ int cfec_Reconstruct(uint8_t* darr, uint8_t* destination); int init_audio(int pbdev, int capdev); int pb_fifo_freespace(int nolock); +int pb_fifo_usedspace(); void pb_write_fifo_clear(); void pb_write_fifo(float sample); int cap_read_fifo(float* data); @@ -113,11 +132,17 @@ uint8_t* getAudioDevicelist(int* len); void setPBvolume(int v); void setCAPvolume(int v); void setVolume(int pbcap, int v); +void setVolume_voice(int pbcap, int v); int init_wasapi(int pbdev, int capdev); void sendAnnouncement(); +void readAudioDevices(); +void clear_audio_fifos(); +void clear_voice_fifos(); void sleep_ms(int ms); +int getus(); void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock); +void toGR_sendData(uint8_t* data, int type, int status); void modulator(uint8_t sym_in); int pb_fifo_usedBlocks(); @@ -131,6 +156,30 @@ void exit_fft(); void showbytestringf(char* title, float* data, int anz); uint16_t* make_waterfall(float fre, int* retlen); +int init_audio_voice(int setpbdev, int setcapdev); +void pb_write_fifo_voice(float sample); +int cap_read_fifo_voice(float* data); +void toVoice(float sample); +void toCodecDecoder(uint8_t* pdata, int len); + +void init_voiceproc(); +void encode(float f); + +int init_wasapi_voice(int pbdev, int capdev); +void init_codec2(); +void encode_codec2(float f); +void toCodecDecoder_codec2(uint8_t* pdata, int len); +void close_wasapi(); +void close_wasapi_voice(); + +void closeAllandTerminate(); +void close_voiceproc(); +void close_codec2(); +void close_audio(); +void close_audio_voice(); +int cap_fifo_usedPercent(); + + void km_symtrack_cccf_create(int _ftype, unsigned int _k, unsigned int _m, @@ -147,17 +196,33 @@ extern int speed; extern int keeprunning; extern int caprate; extern int BC_sock_AppToModem; +extern int DATA_sock_AppToModem; extern int UdpDataPort_ModemToApp; extern int txinterpolfactor; extern int rxPreInterpolfactor; extern char appIP[20]; extern float softwareCAPvolume; +extern float softwareCAPvolume_voice; extern int announcement; extern int ann_running; extern int transmissions; extern int linespeed; extern uint8_t maxLevel; -extern int psk8mode; +extern int VoiceAudioMode; +extern int opusbitrate; +extern int init_audio_result; +extern int init_voice_result; +extern int initialLSvol; +extern int initialMICvol; +extern int codec; + + +// audio device description table +typedef struct { + int bassdev; // bass (basswasapi) dev no + char name[256]; // DEV name + char id[256]; +} AUDIODEVS; #ifdef _LINUX_ int isRunning(char* prgname); diff --git a/hsmodem/hsmodem.vcxproj b/hsmodem/hsmodem.vcxproj index 149458e..a13355f 100755 --- a/hsmodem/hsmodem.vcxproj +++ b/hsmodem/hsmodem.vcxproj @@ -162,6 +162,7 @@ true true wsock32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + /NODEFAULTLIB:libcmt.lib %(AdditionalOptions) @@ -220,20 +221,28 @@ - + + + + + + + + + @@ -246,6 +255,7 @@ + diff --git a/hsmodem/hsmodem.vcxproj.filters b/hsmodem/hsmodem.vcxproj.filters index e85a854..f9c6313 100755 --- a/hsmodem/hsmodem.vcxproj.filters +++ b/hsmodem/hsmodem.vcxproj.filters @@ -57,6 +57,18 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -86,10 +98,25 @@ Header Files - + Header Files - + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + Header Files diff --git a/hsmodem/libcodec2.lib b/hsmodem/libcodec2.lib new file mode 100755 index 0000000..1189621 Binary files /dev/null and b/hsmodem/libcodec2.lib differ diff --git a/hsmodem/liquid_if.cpp b/hsmodem/liquid_if.cpp index e7b384f..d35364e 100755 --- a/hsmodem/liquid_if.cpp +++ b/hsmodem/liquid_if.cpp @@ -53,10 +53,7 @@ modulation_scheme getMod() return LIQUID_MODEM_QPSK; else { - if(psk8mode == 0) - return LIQUID_MODEM_APSK8; - else - return LIQUID_MODEM_PSK8; + return LIQUID_MODEM_APSK8; } } @@ -281,10 +278,15 @@ void make_FFTdata(float f) int bidx = 0; txpl[bidx++] = 4; // type 4: FFT data follows + int us = pb_fifo_usedBlocks(); if (us > 255 || ann_running == 1) us = 255; txpl[bidx++] = us; // usage of TX fifo + us = cap_fifo_usedPercent(); + if (us > 255) us = 255; + txpl[bidx++] = us; // usage of TX fifo + for (int i = 0; i < fftlen; i++) { txpl[bidx++] = fft[i] >> 8; diff --git a/hsmodem/main_helper.cpp b/hsmodem/main_helper.cpp index fd9bd81..035cd9c 100755 --- a/hsmodem/main_helper.cpp +++ b/hsmodem/main_helper.cpp @@ -69,9 +69,36 @@ void install_signal_handler() } #endif // _LINUX_ -void showbytestring(char *title, uint8_t *data, int anz) +void closeAllandTerminate() { - printf("%s. Len %d: ",title,anz); + // terminate all Threads + keeprunning = 0; + // close audio +#ifdef _LINUX_ + close_audio(); + close_audio_voice(); +#endif +#ifdef _WIN32_ + close_wasapi(); + close_wasapi_voice(); +#endif + // close fft + exit_fft(); + // close codec2 and opus + close_codec2(); + close_voiceproc(); + // close liquid-SDR + close_dsp(); + // close network sockets + close(BC_sock_AppToModem); + close(DATA_sock_AppToModem); + + exit(0); +} + +void showbytestring(char *title, uint8_t *data, int totallen, int anz) +{ + printf("%s. Len %d: ",title, totallen); for(int i=0; i + *
  • audio_frame is the audio data in opus_int16 (or float for opus_encode_float())
  • + *
  • frame_size is the duration of the frame in samples (per channel)
  • + *
  • packet is the byte array to which the compressed data is written
  • + *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). + * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • + * + * + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. + * The return value can be negative, which indicates that an error has occurred. If the return value + * is 2 bytes or less, then the packet does not need to be transmitted (DTX). + * + * Once the encoder state if no longer needed, it can be destroyed with + * + * @code + * opus_encoder_destroy(enc); + * @endcode + * + * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), + * then no action is required aside from potentially freeing the memory that was manually + * allocated for it (calling free(enc) for the example above) + * + */ + +/** Opus encoder state. + * This contains the complete state of an Opus encoder. + * It is position independent and can be freely copied. + * @see opus_encoder_create,opus_encoder_init + */ +typedef struct OpusEncoder OpusEncoder; + +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); + +/** + */ + +/** Allocates and initializes an encoder state. + * There are three coding modes: + * + * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice + * signals. It enhances the input signal by high-pass filtering and + * emphasizing formants and harmonics. Optionally it includes in-band + * forward error correction to protect against packet loss. Use this + * mode for typical VoIP applications. Because of the enhancement, + * even at high bitrates the output may sound different from the input. + * + * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most + * non-voice signals like music. Use this mode for music and mixed + * (music/voice) content, broadcast, and applications requiring less + * than 15 ms of coding delay. + * + * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that + * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. + * + * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [out] error int*: @ref opus_errorcodes + * @note Regardless of the sampling rate and number channels selected, the Opus encoder + * can switch to a lower audio bandwidth or number of channels if the bitrate + * selected is too low. This also means that it is safe to always use 48 kHz stereo input + * and let the encoder optimize the encoding. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( + opus_int32 Fs, + int channels, + int application, + int *error +); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_encoder_create(),opus_encoder_get_size() + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_encoder_init( + OpusEncoder *st, + opus_int32 Fs, + int channels, + int application +) OPUS_ARG_NONNULL(1); + +/** Encodes an Opus frame. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( + OpusEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes an Opus frame from floating point input. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( + OpusEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusEncoder allocated by opus_encoder_create(). + * @param[in] st OpusEncoder*: State to be freed. + */ +OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); + +/** Perform a CTL function on an Opus encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls + */ +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); +/**@}*/ + +/** @defgroup opus_decoder Opus Decoder + * @{ + * + * @brief This page describes the process and functions used to decode Opus. + * + * The decoding process also starts with creating a decoder + * state. This can be done with: + * @code + * int error; + * OpusDecoder *dec; + * dec = opus_decoder_create(Fs, channels, &error); + * @endcode + * where + * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 + * @li channels is the number of channels (1 or 2) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) + * @li the return value is a newly created decoder state to be used for decoding + * + * While opus_decoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * @code + * int size; + * int error; + * OpusDecoder *dec; + * size = opus_decoder_get_size(channels); + * dec = malloc(size); + * error = opus_decoder_init(dec, Fs, channels); + * @endcode + * where opus_decoder_get_size() returns the required size for the decoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The decoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: + * @code + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); + * @endcode + * where + * + * @li packet is the byte array containing the compressed data + * @li len is the exact number of bytes contained in the packet + * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) + * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array + * + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio + * buffer is too small to hold the decoded audio. + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ + +/** Opus decoder state. + * This contains the complete state of an Opus decoder. + * It is position independent and can be freely copied. + * @see opus_decoder_create,opus_decoder_init + */ +typedef struct OpusDecoder OpusDecoder; + +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); + +/** Allocates and initializes a decoder state. + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( + opus_int32 Fs, + int channels, + int *error +); + +/** Initializes a previously allocated decoder state. + * The state must be at least the size returned by opus_decoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusDecoder*: Decoder state. + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_init( + OpusDecoder *st, + opus_int32 Fs, + int channels +) OPUS_ARG_NONNULL(1); + +/** Decode an Opus packet. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload* + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an Opus packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusDecoder allocated by opus_decoder_create(). + * @param[in] st OpusDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); + +/** Parse an opus packet into one or more frames. + * Opus_decode will perform this operation internally so most applications do + * not need to use this function. + * This function does not copy the frames, the returned pointers are pointers into + * the input packet. + * @param [in] data char*: Opus packet to be parsed + * @param [in] len opus_int32: size of data + * @param [out] out_toc char*: TOC pointer + * @param [out] frames char*[48] encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames + * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) + * @returns number of frames + */ +OPUS_EXPORT int opus_packet_parse( + const unsigned char *data, + opus_int32 len, + unsigned char *out_toc, + const unsigned char *frames[48], + opus_int16 size[48], + int *payload_offset +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5); + +/** Gets the bandwidth of an Opus packet. + * @param [in] data char*: Opus packet + * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) + * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) + * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) + * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) + * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples per frame from an Opus packet. + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of channels from an Opus packet. + * @param [in] data char*: Opus packet + * @returns Number of channels + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of frames in an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of frames + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] dec OpusDecoder*: Decoder state + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +/** Applies soft-clipping to bring a float signal within the [-1,1] range. If + * the signal is already in that range, nothing is done. If there are values + * outside of [-1,1], then the signal is clipped as smoothly as possible to + * both fit in the range and avoid creating excessive distortion in the + * process. + * @param [in,out] pcm float*: Input PCM and modified PCM + * @param [in] frame_size int Number of samples per channel to process + * @param [in] channels int: Number of channels + * @param [in,out] softclip_mem float*: State memory for the soft clipping process (one float per channel, initialized to zero) + */ +OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem); + + +/**@}*/ + +/** @defgroup opus_repacketizer Repacketizer + * @{ + * + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. The 120 ms limit comes from the + * specification and limits decoder memory requirements at a point where + * framing overhead becomes negligible. + * + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. + * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. + */ + +typedef struct OpusRepacketizer OpusRepacketizer; + +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); + +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); + +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ +OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); + +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); + +/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence). + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least as large as len. + * @returns an error code + * @retval #OPUS_OK \a on success. + * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len); + +/** Remove all padding from a given Opus packet and rewrite the TOC sequence to + * minimize space usage. + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @returns The new size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG \a len was less than 1. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len); + +/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence). + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least 1. + * @param nb_streams opus_int32: The number of streams (not channels) in the packet. + * This must be at least as large as len. + * @returns an error code + * @retval #OPUS_OK \a on success. + * @retval #OPUS_BAD_ARG \a len was less than 1. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams); + +/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to + * minimize space usage. + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param nb_streams opus_int32: The number of streams (not channels) in the packet. + * This must be at least 1. + * @returns The new size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_H */ diff --git a/hsmodem/opus.lib b/hsmodem/opus.lib new file mode 100755 index 0000000..26dd9f5 Binary files /dev/null and b/hsmodem/opus.lib differ diff --git a/hsmodem/opus_defines.h b/hsmodem/opus_defines.h new file mode 100755 index 0000000..d141418 --- /dev/null +++ b/hsmodem/opus_defines.h @@ -0,0 +1,799 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @file opus_defines.h + * @brief Opus reference implementation constants + */ + +#ifndef OPUS_DEFINES_H +#define OPUS_DEFINES_H + +#include "opus_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup opus_errorcodes Error codes + * @{ + */ +/** No error @hideinitializer*/ +#define OPUS_OK 0 +/** One or more invalid/out of range arguments @hideinitializer*/ +#define OPUS_BAD_ARG -1 +/** Not enough bytes allocated in the buffer @hideinitializer*/ +#define OPUS_BUFFER_TOO_SMALL -2 +/** An internal error was detected @hideinitializer*/ +#define OPUS_INTERNAL_ERROR -3 +/** The compressed data passed is corrupted @hideinitializer*/ +#define OPUS_INVALID_PACKET -4 +/** Invalid/unsupported request number @hideinitializer*/ +#define OPUS_UNIMPLEMENTED -5 +/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ +#define OPUS_INVALID_STATE -6 +/** Memory allocation has failed @hideinitializer*/ +#define OPUS_ALLOC_FAIL -7 +/**@}*/ + +/** @cond OPUS_INTERNAL_DOC */ +/**Export control for opus functions */ + +#ifndef OPUS_EXPORT +# if defined(WIN32) +# if defined(OPUS_BUILD) && defined(DLL_EXPORT) +# define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) +# else +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT +# endif +#else +# define OPUS_RESTRICT restrict +#endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(2,7) +# define OPUS_INLINE __inline__ +# elif (defined(_MSC_VER)) +# define OPUS_INLINE __inline +# else +# define OPUS_INLINE +# endif +#else +# define OPUS_INLINE inline +#endif + +/**Warning attributes for opus functions + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) +#endif + +/** These are the actual Encoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +#define OPUS_SET_APPLICATION_REQUEST 4000 +#define OPUS_GET_APPLICATION_REQUEST 4001 +#define OPUS_SET_BITRATE_REQUEST 4002 +#define OPUS_GET_BITRATE_REQUEST 4003 +#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 +#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 +#define OPUS_SET_VBR_REQUEST 4006 +#define OPUS_GET_VBR_REQUEST 4007 +#define OPUS_SET_BANDWIDTH_REQUEST 4008 +#define OPUS_GET_BANDWIDTH_REQUEST 4009 +#define OPUS_SET_COMPLEXITY_REQUEST 4010 +#define OPUS_GET_COMPLEXITY_REQUEST 4011 +#define OPUS_SET_INBAND_FEC_REQUEST 4012 +#define OPUS_GET_INBAND_FEC_REQUEST 4013 +#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 +#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 +#define OPUS_SET_DTX_REQUEST 4016 +#define OPUS_GET_DTX_REQUEST 4017 +#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 +#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 +#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 +#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 +#define OPUS_SET_SIGNAL_REQUEST 4024 +#define OPUS_GET_SIGNAL_REQUEST 4025 +#define OPUS_GET_LOOKAHEAD_REQUEST 4027 +/* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 +#define OPUS_GET_FINAL_RANGE_REQUEST 4031 +#define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 +#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040 +#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 +#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042 +#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043 +/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ +#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 +#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 +#define OPUS_GET_IN_DTX_REQUEST 4049 + +/** Defines for the presence of extended APIs. */ +#define OPUS_HAVE_OPUS_PROJECTION_H + +/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ +#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) +#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) +#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +/** @endcond */ + +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls + * @{ + */ +/* Values for the various encoder CTLs */ +#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. + * + * @hideinitializer */ +#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. + * @hideinitializer */ +#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) + +/** Configures the bitrate in the encoder. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. + * @hideinitializer */ +#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. + * @hideinitializer */ +#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables variable bitrate (VBR) in the encoder. + * The configured bitrate may not be met exactly because frames must + * be an integer number of bytes in length. + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
    + *
    1
    VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
    + *
    + * @hideinitializer */ +#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Hard CBR.
    + *
    1
    VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
    + *
    + * @hideinitializer */ +#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. + * @warning Only the MDCT mode of Opus currently heeds the constraint. + * Speech mode ignores it completely, hybrid mode may fail to obey it + * if the LPC layer uses more bitrate than the constraint would have + * permitted. + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
    + *
    + * @hideinitializer */ +#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default).
    + *
    + * @hideinitializer */ +#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) + +/** Configures mono/stereo forcing in the encoder. + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    + * @hideinitializer */ +#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    + * @hideinitializer */ +#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) + +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    + * @hideinitializer */ +#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    + * @hideinitializer */ +#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    + * @hideinitializer */ +#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Configures the type of signal being encoded. + * This is a hint which helps the encoder's mode selection. + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    + * @hideinitializer */ +#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    + * @hideinitializer */ +#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) + + +/** Configures the encoder's intended application. + * The initial value is a mandatory argument to the encoder_create function. + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @hideinitializer */ +#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @hideinitializer */ +#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the total samples of delay added by the entire codec. + * This can be queried by the encoder and then the provided number of samples can be + * skipped on from the start of the decoder's output to provide time aligned input + * and output. From the perspective of a decoding application the real data begins this many + * samples late. + * + * The decoder contribution to this delay is identical for all decoders, but the + * encoder portion of the delay may vary from implementation to implementation, + * version to version, or even depend on the encoder's initial configuration. + * Applications needing delay compensation should call this CTL rather than + * hard-coding a value. + * @param[out] x opus_int32 *: Number of lookahead samples + * @hideinitializer */ +#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of inband forward error correction (FEC). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable inband FEC (default).
    + *
    1
    Enable inband FEC.
    + *
    + * @hideinitializer */ +#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Inband FEC disabled (default).
    + *
    1
    Inband FEC enabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's expected packet loss percentage. + * Higher values trigger progressively more loss resistant behavior in the encoder + * at the expense of quality at a given bitrate in the absence of packet loss, but + * greater quality under loss. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of discontinuous transmission (DTX). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable DTX (default).
    + *
    1
    Enabled DTX.
    + *
    + * @hideinitializer */ +#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    DTX disabled (default).
    + *
    1
    DTX enabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * + * This is a hint which helps the encoder identify silence and near-silence. + * It represents the number of significant bits of linear intensity below + * which the signal contains ignorable quantization or other noise. + * + * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting + * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate + * for 16-bit linear pcm input with opus_encode_float(). + * + * When using opus_encode() instead of opus_encode_float(), or when libopus + * is compiled for fixed-point, the encoder uses the minimum of the value + * set here and the value 16. + * + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of variable duration frames. + * When variable duration is enabled, the encoder is free to use a shorter frame + * size than the one requested in the opus_encode*() call. + * It is then the user's responsibility + * to verify how much audio was encoded by checking the ToC byte of the encoded + * packet. The part of the audio that was not encoded needs to be resent to the + * encoder for the next call. Do not use this option unless you really + * know what you are doing. + * @see OPUS_GET_EXPERT_FRAME_DURATION + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_80_MS
    Use 80 ms frames.
    + *
    OPUS_FRAMESIZE_100_MS
    Use 100 ms frames.
    + *
    OPUS_FRAMESIZE_120_MS
    Use 120 ms frames.
    + *
    + * @hideinitializer */ +#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured use of variable duration frames. + * @see OPUS_SET_EXPERT_FRAME_DURATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_80_MS
    Use 80 ms frames.
    + *
    OPUS_FRAMESIZE_100_MS
    Use 100 ms frames.
    + *
    OPUS_FRAMESIZE_120_MS
    Use 120 ms frames.
    + *
    + * @hideinitializer */ +#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** If set to 1, disables almost all use of prediction, making frames almost + * completely independent. This reduces quality. + * @see OPUS_GET_PREDICTION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Enable prediction (default).
    + *
    1
    Disable prediction.
    + *
    + * @hideinitializer */ +#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured prediction status. + * @see OPUS_SET_PREDICTION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Prediction enabled (default).
    + *
    1
    Prediction disabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_genericctls Generic CTLs + * + * These macros are used with the \c opus_decoder_ctl and + * \c opus_encoder_ctl calls to generate a particular + * request. + * + * When called on an \c OpusDecoder they apply to that + * particular decoder instance. When called on an + * \c OpusEncoder they apply to the corresponding setting + * on that encoder instance, if present. + * + * Some usage examples: + * + * @code + * int ret; + * opus_int32 pitch; + * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); + * if (ret == OPUS_OK) return ret; + * + * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); + * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); + * + * opus_int32 enc_bw, dec_bw; + * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); + * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); + * if (enc_bw != dec_bw) { + * printf("packet bandwidth mismatch!\n"); + * } + * @endcode + * + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls + * @{ + */ + +/** Resets the codec state to be equivalent to a freshly initialized state. + * This should be called when switching streams in order to prevent + * the back to back decoding from giving different results from + * one at a time decoding. + * @hideinitializer */ +#define OPUS_RESET_STATE 4028 + +/** Gets the final state of the codec's entropy coder. + * This is used for testing purposes, + * The encoder and decoder state should be identical after coding a payload + * (assuming no data corruption or software bugs) + * + * @param[out] x opus_uint32 *: Entropy coder state + * + * @hideinitializer */ +#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    + * @hideinitializer */ +#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + +/** If set to 1, disables the use of phase inversion for intensity stereo, + * improving the quality of mono downmixes, but slightly reducing normal + * stereo quality. Disabling phase inversion in the decoder does not comply + * with RFC 6716, although it does not cause any interoperability issue and + * is expected to become part of the Opus standard once RFC 6716 is updated + * by draft-ietf-codec-opus-update. + * @see OPUS_GET_PHASE_INVERSION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Enable phase inversion (default).
    + *
    1
    Disable phase inversion.
    + *
    + * @hideinitializer */ +#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured phase inversion status. + * @see OPUS_SET_PHASE_INVERSION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Stereo phase inversion enabled (default).
    + *
    1
    Stereo phase inversion disabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x) +/** Gets the DTX state of the encoder. + * Returns whether the last encoded frame was either a comfort noise update + * during DTX or not encoded because of DTX. + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    The encoder is not in DTX.
    + *
    1
    The encoder is in DTX.
    + *
    + * @hideinitializer */ +#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the pitch of the last decoded frame, if available. + * This can be used for any post-processing algorithm requiring the use of pitch, + * e.g. time stretching/shortening. If the last frame was not voiced, or if the + * pitch was not coded in the frame, then zero is returned. + * + * This CTL is only implemented for decoder instances. + * + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) + * + * @hideinitializer */ +#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions + * @{ + */ + +/** Converts an opus error code into a human readable string. + * + * @param[in] error int: Error number + * @returns Error string + */ +OPUS_EXPORT const char *opus_strerror(int error); + +/** Gets the libopus version string. + * + * Applications may look for the substring "-fixed" in the version string to + * determine whether they have a fixed-point or floating-point build at + * runtime. + * + * @returns Version string + */ +OPUS_EXPORT const char *opus_get_version_string(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_DEFINES_H */ diff --git a/hsmodem/opus_types.h b/hsmodem/opus_types.h new file mode 100755 index 0000000..7cf6755 --- /dev/null +++ b/hsmodem/opus_types.h @@ -0,0 +1,166 @@ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ +/* Modified by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* opus_types.h based on ogg_types.h from libogg */ + +/** + @file opus_types.h + @brief Opus reference implementation types +*/ +#ifndef OPUS_TYPES_H +#define OPUS_TYPES_H + +#define opus_int int /* used for counters etc; at least 16 bits */ +#define opus_int64 long long +#define opus_int8 signed char + +#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ +#define opus_uint64 unsigned long long +#define opus_uint8 unsigned char + +/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ +#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) +#include +# undef opus_int64 +# undef opus_int8 +# undef opus_uint64 +# undef opus_uint8 + typedef int8_t opus_int8; + typedef uint8_t opus_uint8; + typedef int16_t opus_int16; + typedef uint16_t opus_uint16; + typedef int32_t opus_int32; + typedef uint32_t opus_uint32; + typedef int64_t opus_int64; + typedef uint64_t opus_uint64; +#elif defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t opus_int32; + typedef _G_uint32_t opus_uint32; + typedef _G_int16 opus_int16; + typedef _G_uint16 opus_uint16; +# elif defined(__MINGW32__) + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; +# elif defined(__MWERKS__) + typedef int opus_int32; + typedef unsigned int opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; +# else + /* MSVC/Borland */ + typedef __int32 opus_int32; + typedef unsigned __int32 opus_uint32; + typedef __int16 opus_int16; + typedef unsigned __int16 opus_uint16; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 opus_int16; + typedef UInt16 opus_uint16; + typedef SInt32 opus_int32; + typedef UInt32 opus_uint32; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t opus_int16; + typedef u_int16_t opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16 opus_int16; + typedef u_int16 opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int opus_int32; + typedef unsigned opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short opus_int16; + typedef unsigned short opus_uint16; + typedef signed int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef long opus_int32; + typedef unsigned long opus_uint32; + +#elif defined(CONFIG_TI_C6X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#else + + /* Give up, take a reasonable guess */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#endif + +#endif /* OPUS_TYPES_H */ diff --git a/hsmodem/speed.cpp b/hsmodem/speed.cpp index 4c4aee2..3fcb953 100755 --- a/hsmodem/speed.cpp +++ b/hsmodem/speed.cpp @@ -26,7 +26,7 @@ int speed = 0; -#define MAXSPDARR 5 +#define MAXSPDARR 50 int spdarr[MAXSPDARR]; int spdarrbps[MAXSPDARR]; @@ -82,12 +82,12 @@ static int f=1; int meanvalbps(int v) { - static int f = 1; + static int f = 5; if (f) { + f--; for (int i = 0; i < MAXSPDARR; i++) spdarrbps[i] = -1; - f = 0; } for (int i = (MAXSPDARR - 1); i > 0; i--) diff --git a/hsmodem/version.h b/hsmodem/version.h new file mode 100644 index 0000000..bae2151 --- /dev/null +++ b/hsmodem/version.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: version.h + AUTHOR......: Tomas Härdin + DATE CREATED: 03 November 2017 + + Codec 2 VERSION #defines + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2017 Tomas Härdin + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +//this functions both as an include guard and your typical HAVE macro +#ifndef CODEC2_HAVE_VERSION +#define CODEC2_HAVE_VERSION + +#define CODEC2_VERSION_MAJOR 0 +#define CODEC2_VERSION_MINOR 9 +#define CODEC2_VERSION_PATCH 2 +#define CODEC2_VERSION "0.9.2" + +#endif //CODEC2_HAVE_VERSION diff --git a/hsmodem/voiceprocessor.cpp b/hsmodem/voiceprocessor.cpp new file mode 100755 index 0000000..e62cb1b --- /dev/null +++ b/hsmodem/voiceprocessor.cpp @@ -0,0 +1,252 @@ +/* +* High Speed modem to transfer data in a 2,7kHz SSB channel +* ========================================================= +* Author: DJ0ABR +* +* (c) DJ0ABR +* www.dj0abr.de +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* voiceprocessor.c ... function to handle voice transfer +* +*/ + +#include "hsmodem.h" + +int opusbitrate = 0; + +void sendCodecToModulator(uint8_t* pdata, int len); + +OpusEncoder* opusenc = (OpusEncoder*)NULL; +OpusDecoder* opusdec = (OpusDecoder*)NULL; + +void init_voiceproc() +{ + if (codec == 1) + { + init_codec2(); + return; + } + + if (opusbitrate == 0) + { + printf("Codec bitrate not set\n"); + return; + } + + close_voiceproc(); + if (VoiceAudioMode == VOICEMODE_CODECLOOP || VoiceAudioMode == VOICEMODE_DV_FULLDUPLEX || VoiceAudioMode == VOICEMODE_DV_RXONLY) + { + int err; + opusenc = opus_encoder_create(VOICE_SAMPRATE, 1, OPUS_APPLICATION_VOIP, &err); + if (opusenc == (OpusEncoder*)NULL || err != OPUS_OK) + { + printf("opus_encoder_create failed\n"); + return; + } + opus_encoder_ctl(opusenc, OPUS_SET_BITRATE(opusbitrate)); + printf("set opus rate: %d\n", opusbitrate); + opus_encoder_ctl(opusenc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_encoder_ctl(opusenc, OPUS_SET_VBR(0)); // hard-CBR + opus_encoder_ctl(opusenc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + + opusdec = opus_decoder_create(VOICE_SAMPRATE, 1 , &err); + if (opusdec == (OpusDecoder*)NULL || err != OPUS_OK) + { + printf("opus_encoder_create failed\n"); + return; + } + } +} + +void close_voiceproc() +{ + if(opusenc != (OpusEncoder*)NULL) + opus_encoder_destroy(opusenc); + opusenc = (OpusEncoder*)NULL; + + if (opusdec != (OpusDecoder*)NULL) + opus_decoder_destroy(opusdec); + opusdec = (OpusDecoder*)NULL; +} + +#define ENC_FRAMESIZE 2880 +void encode(float f) +{ + if (codec == 1) + { + encode_codec2(f); + return; + } + + if (opusenc == (OpusEncoder*)NULL) return; + + static float farr[ENC_FRAMESIZE]; + static int farridx = 0; + uint8_t opusdata[10000]; + + // collect samples until we have ENC_FRAMESIZE + farr[farridx] = f; + if (++farridx == ENC_FRAMESIZE) + { + opus_int32 ret = opus_encode_float(opusenc, farr, farridx, opusdata, opusbitrate); + if (ret < 0) + { + printf("opus_encode_float error: %d", ret); + } + + // length of an OPUS packet: + // duration[ms] * OutSampRate[kbps] / 8 + // line speed 7200: sample rate=6, PacketSize = (ENC_FRAMESIZE*1000/48000) * 6 / 8 = (ENC_FRAMESIZE/48)*6/8 = 45 + + //measure_speed_bps(ret*8); + //showbytestring("ENC:", opusdata, ret, ret); + + // send Codec data to modulator + if (VoiceAudioMode == VOICEMODE_DV_FULLDUPLEX) + { + memmove(opusdata + 1, opusdata, ret); + opusdata[0] = 0xff; // start of opus packet marker + sendCodecToModulator(opusdata, ret+1); + } + + // decode and send samples to loadspeaker + if (VoiceAudioMode == VOICEMODE_CODECLOOP) + { + static float fresult[ENC_FRAMESIZE]; + int r = opus_decode_float(opusdec, opusdata, ret, fresult, ENC_FRAMESIZE, 0); + if (r < 0) + { + printf("opus_decode_float error: %d", r); + } + + for (int i = 0; i < r; i++) + pb_write_fifo_voice(fresult[i]); + } + + farridx = 0; + } +} + +// void toGR_sendData(uint8_t* data, int type, int status) +// this function expects "data" with length: payloadlen +// so we have to collect samples until one payload is filled +// this may take too long, in this case send the frame immediately +// the first byte in the payload is the marker 0xff +// type=6 ... voice payload +// minfo=1 ... voice data available +// minfo=0 ... filler payload, just ignore + +void sendCodecToModulator(uint8_t *pdata, int len) +{ + static uint8_t payload[PAYLOADLEN]; + static int vdidx = 0; + + // fill the new voice data "pdata" into the buffer "voicedata" + for (int i = 0; i < len; i++) + { + if (vdidx >= PAYLOADLEN) printf("vdidx too high: %d", vdidx); + payload[vdidx++] = pdata[i]; + + // if the voicedata buffer is full, send it to the modem + if (vdidx == PAYLOADLEN) + { + vdidx = 0; + toGR_sendData(payload, 6, 1); // 6 ... voice data, 1 ... valid voice data + } + + while (1) + { + // we have to check if the TX fifo has enough data. In case of an underrun the Q(8A)PSK signal will be distorted + int us = pb_fifo_usedspace(); + if (us < 20000) + { + //printf("tx filler\n"); + // not enough samples in the TX buffer + // send a dummy frame, a frame with 0 voice data + uint8_t dummy[PAYLOADLEN]; + memset(dummy, 0, PAYLOADLEN); + toGR_sendData(dummy, 6, 0); + } + else + break; + } + } +} + +// we get the received data stream with length: PAYLOADLEN +// find opus packets marked with 0xff and a length of opusPacketSize +// send send these chunks to the codec_decoder +#define CHUNKSIZE 200 + +void toCodecDecoder(uint8_t *pdata, int len) +{ + if (codec == 1) + { + toCodecDecoder_codec2(pdata, len); + return; + } + + static uint8_t chunk[CHUNKSIZE]; + int opusPacketSize = ((ENC_FRAMESIZE / 48) * (opusbitrate/100)) / 80; + + if (opusPacketSize > 45) + { + printf("wrong opusPacketSize: %d\n", opusPacketSize); + return; + } + + // go through all data bytes + for (int vd = 0; vd < len; vd++) + { + // shift the data through the chunk buffer + for (int i = 0; i < CHUNKSIZE - 1; i++) + chunk[i] = chunk[i + 1]; + chunk[CHUNKSIZE - 1] = pdata[vd]; + + // an OPUS packet has max length of 45 Byte. + // in the chunk size of 200 fit minimum 4 chunks + // so lets test if 4 chunks are there, by looking for the marker + // at distance opusPacketSize + int mfound = 1; + for (int m = 0; m < 4; m++) + { + if (chunk[(opusPacketSize+1) * m] != 0xff) + { + mfound = 0; + break; + } + } + + if (mfound) + { + //showbytestring("OPUS:", chunk + 1, opusPacketSize, opusPacketSize); + + static float fresult[ENC_FRAMESIZE]; + int r = opus_decode_float(opusdec, chunk + 1, opusPacketSize, fresult, ENC_FRAMESIZE, 0); + if (r < 0) + { + printf("opus_decode_float error: %d\n", r); + } + else + { + //measure_speed_bps(r); + for (int j = 0; j < r; j++) + pb_write_fifo_voice(fresult[j]); + } + } + } +} diff --git a/oscardata/oscardata/ArraySend.cs b/oscardata/oscardata/ArraySend.cs index 142a06e..494e286 100755 --- a/oscardata/oscardata/ArraySend.cs +++ b/oscardata/oscardata/ArraySend.cs @@ -176,8 +176,9 @@ namespace oscardata { // send as the last frame Array.Copy(txdata, txpos, txarr, 0, restlen); // unused byte will be 0 - txudp(txarr, txtype, statics.LastFrame); - txudp(txarr, txtype, statics.LastFrame); + // send the last frame a couple of times + for(int i=0; i<10; i++) + txudp(txarr, txtype, statics.LastFrame); setSending(false); // transmission complete } else diff --git a/oscardata/oscardata/Form1.Designer.cs b/oscardata/oscardata/Form1.Designer.cs index e37db4b..06e7ee9 100755 --- a/oscardata/oscardata/Form1.Designer.cs +++ b/oscardata/oscardata/Form1.Designer.cs @@ -40,36 +40,42 @@ this.timer_qpsk = new System.Windows.Forms.Timer(this.components); this.panel_txspectrum = new System.Windows.Forms.Panel(); this.tabPage1 = new System.Windows.Forms.TabPage(); - this.button_stopBERtest = new System.Windows.Forms.Button(); - this.button_startBERtest = new System.Windows.Forms.Button(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); this.rtb = new System.Windows.Forms.RichTextBox(); this.tabPage2 = new System.Windows.Forms.TabPage(); this.groupBox1 = new System.Windows.Forms.Panel(); this.label_nextimage = new System.Windows.Forms.Label(); this.cb_loop = new System.Windows.Forms.CheckBox(); - this.bt_rximages = new System.Windows.Forms.Button(); - this.button_loadimage = new System.Windows.Forms.Button(); this.comboBox_quality = new System.Windows.Forms.ComboBox(); this.label2 = new System.Windows.Forms.Label(); this.checkBox_big = new System.Windows.Forms.CheckBox(); - this.button_cancelimg = new System.Windows.Forms.Button(); - this.button_sendimage = new System.Windows.Forms.Button(); this.label_rximage = new System.Windows.Forms.Label(); this.label_tximage = new System.Windows.Forms.Label(); - this.pictureBox_rximage = new System.Windows.Forms.PictureBox(); - this.pictureBox_tximage = new System.Windows.Forms.PictureBox(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPage3 = new System.Windows.Forms.TabPage(); - this.button2 = new System.Windows.Forms.Button(); - this.bt_openrxfile = new System.Windows.Forms.Button(); this.label_rxfile = new System.Windows.Forms.Label(); this.label_txfile = new System.Windows.Forms.Label(); this.rtb_RXfile = new System.Windows.Forms.RichTextBox(); this.rtb_TXfile = new System.Windows.Forms.RichTextBox(); - this.bt_file_send = new System.Windows.Forms.Button(); - this.bt_sendBinaryFile = new System.Windows.Forms.Button(); - this.bt_file_html = new System.Windows.Forms.Button(); - this.bt_file_ascii = new System.Windows.Forms.Button(); + this.tabPage_audio = new System.Windows.Forms.TabPage(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.rb_codec2 = new System.Windows.Forms.RadioButton(); + this.rb_opus = new System.Windows.Forms.RadioButton(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.cb_digitalVoiceRXonly = new System.Windows.Forms.CheckBox(); + this.cb_digitalVoice = new System.Windows.Forms.CheckBox(); + this.cb_codecloop = new System.Windows.Forms.CheckBox(); + this.cb_switchtoLS = new System.Windows.Forms.CheckBox(); + this.cb_voiceloop = new System.Windows.Forms.CheckBox(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.label8 = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.tb_mic = new System.Windows.Forms.TrackBar(); + this.tb_loadspeaker = new System.Windows.Forms.TrackBar(); + this.cb_loudspeaker = new System.Windows.Forms.ComboBox(); + this.label10 = new System.Windows.Forms.Label(); + this.cb_mic = new System.Windows.Forms.ComboBox(); + this.label11 = new System.Windows.Forms.Label(); this.tabPage5 = new System.Windows.Forms.TabPage(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.cb_autostart = new System.Windows.Forms.CheckBox(); @@ -88,6 +94,9 @@ this.cb_audioCAP = new System.Windows.Forms.ComboBox(); this.label4 = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.cb_stampinfo = new System.Windows.Forms.CheckBox(); + this.tb_info = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); this.textBox5 = new System.Windows.Forms.TextBox(); this.cb_announcement = new System.Windows.Forms.ComboBox(); this.textBox4 = new System.Windows.Forms.TextBox(); @@ -96,30 +105,65 @@ this.label1 = new System.Windows.Forms.Label(); this.cb_stampcall = new System.Windows.Forms.CheckBox(); this.cb_savegoodfiles = new System.Windows.Forms.CheckBox(); + this.tabPage4 = new System.Windows.Forms.TabPage(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.cb_speed = new System.Windows.Forms.ComboBox(); this.label_speed = new System.Windows.Forms.Label(); this.timer_searchmodem = new System.Windows.Forms.Timer(this.components); this.progressBar_fifo = new System.Windows.Forms.ProgressBar(); this.label_fifo = new System.Windows.Forms.Label(); - this.trackBar_maxlevel = new System.Windows.Forms.TrackBar(); - this.tb_info = new System.Windows.Forms.TextBox(); - this.label7 = new System.Windows.Forms.Label(); - this.cb_stampinfo = new System.Windows.Forms.CheckBox(); + this.bt_blockinfo = new System.Windows.Forms.Button(); + this.bt_rximages = new System.Windows.Forms.Button(); + this.button_loadimage = new System.Windows.Forms.Button(); + this.button_cancelimg = new System.Windows.Forms.Button(); + this.button_sendimage = new System.Windows.Forms.Button(); + this.pictureBox_rximage = new System.Windows.Forms.PictureBox(); + this.pictureBox_tximage = new System.Windows.Forms.PictureBox(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.button2 = new System.Windows.Forms.Button(); + this.bt_openrxfile = new System.Windows.Forms.Button(); + this.bt_file_send = new System.Windows.Forms.Button(); + this.bt_sendBinaryFile = new System.Windows.Forms.Button(); + this.bt_file_html = new System.Windows.Forms.Button(); + this.bt_file_ascii = new System.Windows.Forms.Button(); + this.pictureBox2 = new System.Windows.Forms.PictureBox(); + this.pb_voice = new System.Windows.Forms.PictureBox(); + this.pb_voiceCAPstatus = new System.Windows.Forms.PictureBox(); + this.pb_voicePBstatus = new System.Windows.Forms.PictureBox(); + this.button_stopBERtest = new System.Windows.Forms.Button(); + this.button_startBERtest = new System.Windows.Forms.Button(); + this.pb_audioCAPstatus = new System.Windows.Forms.PictureBox(); + this.pb_audioPBstatus = new System.Windows.Forms.PictureBox(); + this.progressBar_capfifo = new System.Windows.Forms.ProgressBar(); + this.label_capfifo = new System.Windows.Forms.Label(); this.statusStrip1.SuspendLayout(); this.tabPage1.SuspendLayout(); this.tabPage2.SuspendLayout(); this.groupBox1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox_rximage)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox_tximage)).BeginInit(); this.tabControl1.SuspendLayout(); this.tabPage3.SuspendLayout(); + this.tabPage_audio.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.groupBox5.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.tb_mic)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.tb_loadspeaker)).BeginInit(); this.tabPage5.SuspendLayout(); this.groupBox4.SuspendLayout(); this.groupBox3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.tb_CAPvol)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.tb_PBvol)).BeginInit(); this.groupBox2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar_maxlevel)).BeginInit(); + this.tabPage4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox_rximage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox_tximage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voice)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voiceCAPstatus)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voicePBstatus)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_audioCAPstatus)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_audioPBstatus)).BeginInit(); this.SuspendLayout(); // // timer_udpTX @@ -191,35 +235,32 @@ this.tabPage1.Controls.Add(this.button_stopBERtest); this.tabPage1.Controls.Add(this.button_startBERtest); this.tabPage1.Controls.Add(this.rtb); - this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.ImageIndex = 4; + this.tabPage1.Location = new System.Drawing.Point(4, 23); this.tabPage1.Name = "tabPage1"; this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(1291, 553); + this.tabPage1.Size = new System.Drawing.Size(1291, 552); this.tabPage1.TabIndex = 0; this.tabPage1.Text = "BER Test"; this.tabPage1.UseVisualStyleBackColor = true; // - // button_stopBERtest + // imageList1 // - this.button_stopBERtest.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button_stopBERtest.Location = new System.Drawing.Point(113, 13); - this.button_stopBERtest.Name = "button_stopBERtest"; - this.button_stopBERtest.Size = new System.Drawing.Size(101, 32); - this.button_stopBERtest.TabIndex = 4; - this.button_stopBERtest.Text = "STOP"; - this.button_stopBERtest.UseVisualStyleBackColor = true; - this.button_stopBERtest.Click += new System.EventHandler(this.button_stopBERtest_Click); - // - // button_startBERtest - // - this.button_startBERtest.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.button_startBERtest.Location = new System.Drawing.Point(6, 13); - this.button_startBERtest.Name = "button_startBERtest"; - this.button_startBERtest.Size = new System.Drawing.Size(101, 32); - this.button_startBERtest.TabIndex = 3; - this.button_startBERtest.Text = "START"; - this.button_startBERtest.UseVisualStyleBackColor = true; - this.button_startBERtest.Click += new System.EventHandler(this.button_startBERtest_Click); + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "binary.png"); + this.imageList1.Images.SetKeyName(1, "cancel.png"); + this.imageList1.Images.SetKeyName(2, "html.png"); + this.imageList1.Images.SetKeyName(3, "image.png"); + this.imageList1.Images.SetKeyName(4, "meter.png"); + this.imageList1.Images.SetKeyName(5, "openfolder.png"); + this.imageList1.Images.SetKeyName(6, "setup.png"); + this.imageList1.Images.SetKeyName(7, "start.png"); + this.imageList1.Images.SetKeyName(8, "stop.png"); + this.imageList1.Images.SetKeyName(9, "text.png"); + this.imageList1.Images.SetKeyName(10, "transmit.png"); + this.imageList1.Images.SetKeyName(11, "voice.png"); + this.imageList1.Images.SetKeyName(12, "about.png"); // // rtb // @@ -237,10 +278,11 @@ this.tabPage2.Controls.Add(this.label_tximage); this.tabPage2.Controls.Add(this.pictureBox_rximage); this.tabPage2.Controls.Add(this.pictureBox_tximage); - this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.ImageIndex = 3; + this.tabPage2.Location = new System.Drawing.Point(4, 23); this.tabPage2.Name = "tabPage2"; this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(1291, 553); + this.tabPage2.Size = new System.Drawing.Size(1291, 552); this.tabPage2.TabIndex = 1; this.tabPage2.Text = "Image"; this.tabPage2.UseVisualStyleBackColor = true; @@ -264,7 +306,7 @@ // label_nextimage // this.label_nextimage.AutoSize = true; - this.label_nextimage.Location = new System.Drawing.Point(618, 19); + this.label_nextimage.Location = new System.Drawing.Point(641, 19); this.label_nextimage.Name = "label_nextimage"; this.label_nextimage.Size = new System.Drawing.Size(81, 13); this.label_nextimage.TabIndex = 12; @@ -273,33 +315,13 @@ // cb_loop // this.cb_loop.AutoSize = true; - this.cb_loop.Location = new System.Drawing.Point(621, 5); + this.cb_loop.Location = new System.Drawing.Point(644, 5); this.cb_loop.Name = "cb_loop"; this.cb_loop.Size = new System.Drawing.Size(167, 17); this.cb_loop.TabIndex = 11; this.cb_loop.Text = "loop (send all images in folder)"; this.cb_loop.UseVisualStyleBackColor = true; // - // bt_rximages - // - this.bt_rximages.Location = new System.Drawing.Point(534, 5); - this.bt_rximages.Name = "bt_rximages"; - this.bt_rximages.Size = new System.Drawing.Size(75, 23); - this.bt_rximages.TabIndex = 10; - this.bt_rximages.Text = "RX Images"; - this.bt_rximages.UseVisualStyleBackColor = true; - this.bt_rximages.Click += new System.EventHandler(this.bt_rximages_Click); - // - // button_loadimage - // - this.button_loadimage.Location = new System.Drawing.Point(265, 5); - this.button_loadimage.Name = "button_loadimage"; - this.button_loadimage.Size = new System.Drawing.Size(75, 23); - this.button_loadimage.TabIndex = 0; - this.button_loadimage.Text = "Load Image"; - this.button_loadimage.UseVisualStyleBackColor = true; - this.button_loadimage.Click += new System.EventHandler(this.button_loadimage_Click); - // // comboBox_quality // this.comboBox_quality.FormattingEnabled = true; @@ -336,26 +358,6 @@ this.checkBox_big.UseVisualStyleBackColor = true; this.checkBox_big.CheckedChanged += new System.EventHandler(this.checkBox_small_CheckedChanged); // - // button_cancelimg - // - this.button_cancelimg.Location = new System.Drawing.Point(443, 5); - this.button_cancelimg.Name = "button_cancelimg"; - this.button_cancelimg.Size = new System.Drawing.Size(75, 23); - this.button_cancelimg.TabIndex = 9; - this.button_cancelimg.Text = "Cancel"; - this.button_cancelimg.UseVisualStyleBackColor = true; - this.button_cancelimg.Click += new System.EventHandler(this.button_cancelimg_Click); - // - // button_sendimage - // - this.button_sendimage.Location = new System.Drawing.Point(346, 5); - this.button_sendimage.Name = "button_sendimage"; - this.button_sendimage.Size = new System.Drawing.Size(75, 23); - this.button_sendimage.TabIndex = 1; - this.button_sendimage.Text = "Send Image"; - this.button_sendimage.UseVisualStyleBackColor = true; - this.button_sendimage.Click += new System.EventHandler(this.button_sendimage_Click); - // // label_rximage // this.label_rximage.AutoSize = true; @@ -376,33 +378,15 @@ this.label_tximage.TabIndex = 4; this.label_tximage.Text = "TX image"; // - // pictureBox_rximage - // - this.pictureBox_rximage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(250)))), ((int)(((byte)(240))))); - this.pictureBox_rximage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.pictureBox_rximage.Location = new System.Drawing.Point(642, 27); - this.pictureBox_rximage.Name = "pictureBox_rximage"; - this.pictureBox_rximage.Size = new System.Drawing.Size(640, 480); - this.pictureBox_rximage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.pictureBox_rximage.TabIndex = 3; - this.pictureBox_rximage.TabStop = false; - // - // pictureBox_tximage - // - this.pictureBox_tximage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(250)))), ((int)(((byte)(250)))), ((int)(((byte)(240))))); - this.pictureBox_tximage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.pictureBox_tximage.Location = new System.Drawing.Point(1, 27); - this.pictureBox_tximage.Name = "pictureBox_tximage"; - this.pictureBox_tximage.Size = new System.Drawing.Size(640, 480); - this.pictureBox_tximage.TabIndex = 2; - this.pictureBox_tximage.TabStop = false; - // // tabControl1 // this.tabControl1.Controls.Add(this.tabPage2); this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Controls.Add(this.tabPage_audio); this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(this.tabPage5); + this.tabControl1.Controls.Add(this.tabPage4); + this.tabControl1.ImageList = this.imageList1; this.tabControl1.Location = new System.Drawing.Point(5, 3); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; @@ -411,6 +395,7 @@ // // tabPage3 // + this.tabPage3.Controls.Add(this.pictureBox1); this.tabPage3.Controls.Add(this.button2); this.tabPage3.Controls.Add(this.bt_openrxfile); this.tabPage3.Controls.Add(this.label_rxfile); @@ -421,33 +406,14 @@ this.tabPage3.Controls.Add(this.bt_sendBinaryFile); this.tabPage3.Controls.Add(this.bt_file_html); this.tabPage3.Controls.Add(this.bt_file_ascii); - this.tabPage3.Location = new System.Drawing.Point(4, 22); + this.tabPage3.ImageIndex = 9; + this.tabPage3.Location = new System.Drawing.Point(4, 23); this.tabPage3.Name = "tabPage3"; - this.tabPage3.Size = new System.Drawing.Size(1291, 553); + this.tabPage3.Size = new System.Drawing.Size(1291, 552); this.tabPage3.TabIndex = 2; this.tabPage3.Text = "File"; this.tabPage3.UseVisualStyleBackColor = true; // - // button2 - // - this.button2.Location = new System.Drawing.Point(17, 218); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(137, 23); - this.button2.TabIndex = 12; - this.button2.Text = "Cancel"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button_cancelimg_Click); - // - // bt_openrxfile - // - this.bt_openrxfile.Location = new System.Drawing.Point(17, 306); - this.bt_openrxfile.Name = "bt_openrxfile"; - this.bt_openrxfile.Size = new System.Drawing.Size(137, 33); - this.bt_openrxfile.TabIndex = 11; - this.bt_openrxfile.Text = "Open RX file folder"; - this.bt_openrxfile.UseVisualStyleBackColor = true; - this.bt_openrxfile.Click += new System.EventHandler(this.bt_openrxfile_Click); - // // label_rxfile // this.label_rxfile.AutoSize = true; @@ -486,56 +452,234 @@ this.rtb_TXfile.TabIndex = 4; this.rtb_TXfile.Text = ""; // - // bt_file_send + // tabPage_audio // - this.bt_file_send.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.bt_file_send.ForeColor = System.Drawing.Color.Red; - this.bt_file_send.Location = new System.Drawing.Point(17, 157); - this.bt_file_send.Name = "bt_file_send"; - this.bt_file_send.Size = new System.Drawing.Size(137, 37); - this.bt_file_send.TabIndex = 3; - this.bt_file_send.Text = "SEND"; - this.bt_file_send.UseVisualStyleBackColor = true; - this.bt_file_send.Click += new System.EventHandler(this.bt_file_send_Click); + this.tabPage_audio.Controls.Add(this.groupBox7); + this.tabPage_audio.Controls.Add(this.groupBox6); + this.tabPage_audio.Controls.Add(this.groupBox5); + this.tabPage_audio.ImageIndex = 11; + this.tabPage_audio.Location = new System.Drawing.Point(4, 23); + this.tabPage_audio.Name = "tabPage_audio"; + this.tabPage_audio.Size = new System.Drawing.Size(1291, 552); + this.tabPage_audio.TabIndex = 5; + this.tabPage_audio.Text = "Voice Audio"; + this.tabPage_audio.UseVisualStyleBackColor = true; // - // bt_sendBinaryFile + // groupBox7 // - this.bt_sendBinaryFile.Location = new System.Drawing.Point(17, 89); - this.bt_sendBinaryFile.Name = "bt_sendBinaryFile"; - this.bt_sendBinaryFile.Size = new System.Drawing.Size(137, 23); - this.bt_sendBinaryFile.TabIndex = 2; - this.bt_sendBinaryFile.Text = "Load Binary File"; - this.bt_sendBinaryFile.UseVisualStyleBackColor = true; - this.bt_sendBinaryFile.Click += new System.EventHandler(this.bt_sendBinaryFile_Click); + this.groupBox7.Controls.Add(this.rb_codec2); + this.groupBox7.Controls.Add(this.pictureBox2); + this.groupBox7.Controls.Add(this.rb_opus); + this.groupBox7.Location = new System.Drawing.Point(18, 295); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(765, 95); + this.groupBox7.TabIndex = 21; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "Codec Selection"; // - // bt_file_html + // rb_codec2 // - this.bt_file_html.Location = new System.Drawing.Point(17, 60); - this.bt_file_html.Name = "bt_file_html"; - this.bt_file_html.Size = new System.Drawing.Size(137, 23); - this.bt_file_html.TabIndex = 1; - this.bt_file_html.Text = "Load HTML File"; - this.bt_file_html.UseVisualStyleBackColor = true; - this.bt_file_html.Click += new System.EventHandler(this.button2_Click); + this.rb_codec2.AutoSize = true; + this.rb_codec2.Location = new System.Drawing.Point(92, 50); + this.rb_codec2.Name = "rb_codec2"; + this.rb_codec2.Size = new System.Drawing.Size(289, 17); + this.rb_codec2.TabIndex = 23; + this.rb_codec2.Text = "CODEC-2 parametric audio codec. Audio rate: 3200 bps"; + this.rb_codec2.UseVisualStyleBackColor = true; // - // bt_file_ascii + // rb_opus // - this.bt_file_ascii.Location = new System.Drawing.Point(17, 31); - this.bt_file_ascii.Name = "bt_file_ascii"; - this.bt_file_ascii.Size = new System.Drawing.Size(137, 23); - this.bt_file_ascii.TabIndex = 0; - this.bt_file_ascii.Text = "Load ASCII Text File"; - this.bt_file_ascii.UseVisualStyleBackColor = true; - this.bt_file_ascii.Click += new System.EventHandler(this.bt_file_ascii_Click); + this.rb_opus.AutoSize = true; + this.rb_opus.Checked = true; + this.rb_opus.Location = new System.Drawing.Point(92, 27); + this.rb_opus.Name = "rb_opus"; + this.rb_opus.Size = new System.Drawing.Size(290, 17); + this.rb_opus.TabIndex = 0; + this.rb_opus.TabStop = true; + this.rb_opus.Text = "OPUS rate adaptive codec. Audio rate: 84% of data rate"; + this.rb_opus.UseVisualStyleBackColor = true; + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.pb_voice); + this.groupBox6.Controls.Add(this.cb_digitalVoiceRXonly); + this.groupBox6.Controls.Add(this.cb_digitalVoice); + this.groupBox6.Controls.Add(this.cb_codecloop); + this.groupBox6.Controls.Add(this.cb_switchtoLS); + this.groupBox6.Controls.Add(this.cb_voiceloop); + this.groupBox6.Location = new System.Drawing.Point(18, 135); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(765, 154); + this.groupBox6.TabIndex = 20; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "Voice Audio Operating Mode"; + // + // cb_digitalVoiceRXonly + // + this.cb_digitalVoiceRXonly.AutoSize = true; + this.cb_digitalVoiceRXonly.Location = new System.Drawing.Point(15, 100); + this.cb_digitalVoiceRXonly.Name = "cb_digitalVoiceRXonly"; + this.cb_digitalVoiceRXonly.Size = new System.Drawing.Size(308, 17); + this.cb_digitalVoiceRXonly.TabIndex = 21; + this.cb_digitalVoiceRXonly.Text = "Digital Voice RX: Receiver ---> Codec ---> Loudspeaker"; + this.cb_digitalVoiceRXonly.UseVisualStyleBackColor = true; + this.cb_digitalVoiceRXonly.CheckedChanged += new System.EventHandler(this.cb_digitalVoiceRXonly_CheckedChanged); + // + // cb_digitalVoice + // + this.cb_digitalVoice.AutoSize = true; + this.cb_digitalVoice.Location = new System.Drawing.Point(15, 123); + this.cb_digitalVoice.Name = "cb_digitalVoice"; + this.cb_digitalVoice.Size = new System.Drawing.Size(508, 17); + this.cb_digitalVoice.TabIndex = 20; + this.cb_digitalVoice.Text = "Digital Voice RX+TX: Microphone ---> Codec ---> Transmitter | Receiver ---> C" + + "odec ---> Loudspeaker"; + this.cb_digitalVoice.UseVisualStyleBackColor = true; + this.cb_digitalVoice.CheckedChanged += new System.EventHandler(this.cb_digitalVoice_CheckedChanged); + // + // cb_codecloop + // + this.cb_codecloop.AutoSize = true; + this.cb_codecloop.Location = new System.Drawing.Point(15, 77); + this.cb_codecloop.Name = "cb_codecloop"; + this.cb_codecloop.Size = new System.Drawing.Size(284, 17); + this.cb_codecloop.TabIndex = 19; + this.cb_codecloop.Text = "Codec Loop: Microphone ---> Codec ---> Loudspeaker"; + this.cb_codecloop.UseVisualStyleBackColor = true; + this.cb_codecloop.CheckedChanged += new System.EventHandler(this.cb_codecloop_CheckedChanged); + // + // cb_switchtoLS + // + this.cb_switchtoLS.AutoSize = true; + this.cb_switchtoLS.Location = new System.Drawing.Point(15, 31); + this.cb_switchtoLS.Name = "cb_switchtoLS"; + this.cb_switchtoLS.Size = new System.Drawing.Size(225, 17); + this.cb_switchtoLS.TabIndex = 17; + this.cb_switchtoLS.Text = "Digital Monitor: Receiver ---> Loudspeaker"; + this.cb_switchtoLS.UseVisualStyleBackColor = true; + this.cb_switchtoLS.CheckedChanged += new System.EventHandler(this.cb_switchtoLS_CheckedChanged); + // + // cb_voiceloop + // + this.cb_voiceloop.AutoSize = true; + this.cb_voiceloop.Location = new System.Drawing.Point(15, 54); + this.cb_voiceloop.Name = "cb_voiceloop"; + this.cb_voiceloop.Size = new System.Drawing.Size(232, 17); + this.cb_voiceloop.TabIndex = 18; + this.cb_voiceloop.Text = "internal Loop: Microphone ---> Loudspeaker"; + this.cb_voiceloop.UseVisualStyleBackColor = true; + this.cb_voiceloop.CheckedChanged += new System.EventHandler(this.cb_voiceloop_CheckedChanged); + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.pb_voiceCAPstatus); + this.groupBox5.Controls.Add(this.pb_voicePBstatus); + this.groupBox5.Controls.Add(this.label8); + this.groupBox5.Controls.Add(this.label9); + this.groupBox5.Controls.Add(this.tb_mic); + this.groupBox5.Controls.Add(this.tb_loadspeaker); + this.groupBox5.Controls.Add(this.cb_loudspeaker); + this.groupBox5.Controls.Add(this.label10); + this.groupBox5.Controls.Add(this.cb_mic); + this.groupBox5.Controls.Add(this.label11); + this.groupBox5.Location = new System.Drawing.Point(18, 21); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(765, 107); + this.groupBox5.TabIndex = 15; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "Loadspeaker / Microphone / Headset"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(423, 60); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(45, 13); + this.label8.TabIndex = 16; + this.label8.Text = "Volume:"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(423, 29); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(45, 13); + this.label9.TabIndex = 15; + this.label9.Text = "Volume:"; + // + // tb_mic + // + this.tb_mic.Cursor = System.Windows.Forms.Cursors.SizeAll; + this.tb_mic.Location = new System.Drawing.Point(474, 56); + this.tb_mic.Maximum = 100; + this.tb_mic.MaximumSize = new System.Drawing.Size(0, 24); + this.tb_mic.MinimumSize = new System.Drawing.Size(100, 0); + this.tb_mic.Name = "tb_mic"; + this.tb_mic.Size = new System.Drawing.Size(100, 24); + this.tb_mic.TabIndex = 14; + this.tb_mic.TickStyle = System.Windows.Forms.TickStyle.None; + this.tb_mic.Value = 50; + this.tb_mic.Scroll += new System.EventHandler(this.tb_mic_Scroll); + // + // tb_loadspeaker + // + this.tb_loadspeaker.Cursor = System.Windows.Forms.Cursors.SizeAll; + this.tb_loadspeaker.Location = new System.Drawing.Point(474, 25); + this.tb_loadspeaker.Maximum = 100; + this.tb_loadspeaker.MaximumSize = new System.Drawing.Size(0, 24); + this.tb_loadspeaker.MinimumSize = new System.Drawing.Size(100, 0); + this.tb_loadspeaker.Name = "tb_loadspeaker"; + this.tb_loadspeaker.Size = new System.Drawing.Size(100, 24); + this.tb_loadspeaker.TabIndex = 13; + this.tb_loadspeaker.TickStyle = System.Windows.Forms.TickStyle.None; + this.tb_loadspeaker.Value = 50; + this.tb_loadspeaker.Scroll += new System.EventHandler(this.tb_loadspeaker_Scroll); + // + // cb_loudspeaker + // + this.cb_loudspeaker.FormattingEnabled = true; + this.cb_loudspeaker.Location = new System.Drawing.Point(151, 25); + this.cb_loudspeaker.Name = "cb_loudspeaker"; + this.cb_loudspeaker.Size = new System.Drawing.Size(230, 21); + this.cb_loudspeaker.TabIndex = 7; + this.cb_loudspeaker.Text = "Default"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(12, 29); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(133, 13); + this.label10.TabIndex = 8; + this.label10.Text = "Loadspeaker/Headphone:"; + // + // cb_mic + // + this.cb_mic.FormattingEnabled = true; + this.cb_mic.Location = new System.Drawing.Point(151, 58); + this.cb_mic.Name = "cb_mic"; + this.cb_mic.Size = new System.Drawing.Size(230, 21); + this.cb_mic.TabIndex = 9; + this.cb_mic.Text = "Default"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(12, 62); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(66, 13); + this.label11.TabIndex = 10; + this.label11.Text = "Microphone:"; // // tabPage5 // this.tabPage5.Controls.Add(this.groupBox4); this.tabPage5.Controls.Add(this.groupBox3); this.tabPage5.Controls.Add(this.groupBox2); - this.tabPage5.Location = new System.Drawing.Point(4, 22); + this.tabPage5.ImageIndex = 6; + this.tabPage5.Location = new System.Drawing.Point(4, 23); this.tabPage5.Name = "tabPage5"; - this.tabPage5.Size = new System.Drawing.Size(1291, 553); + this.tabPage5.Size = new System.Drawing.Size(1291, 552); this.tabPage5.TabIndex = 4; this.tabPage5.Text = "Setup"; this.tabPage5.UseVisualStyleBackColor = true; @@ -562,9 +706,9 @@ this.cb_autostart.CheckState = System.Windows.Forms.CheckState.Checked; this.cb_autostart.Location = new System.Drawing.Point(17, 23); this.cb_autostart.Name = "cb_autostart"; - this.cb_autostart.Size = new System.Drawing.Size(131, 17); + this.cb_autostart.Size = new System.Drawing.Size(156, 17); this.cb_autostart.TabIndex = 4; - this.cb_autostart.Text = "AUTO start HSmodem"; + this.cb_autostart.Text = "AUTO start/stop HSmodem"; this.cb_autostart.UseVisualStyleBackColor = true; // // bt_shutdown @@ -627,6 +771,8 @@ // // groupBox3 // + this.groupBox3.Controls.Add(this.pb_audioCAPstatus); + this.groupBox3.Controls.Add(this.pb_audioPBstatus); this.groupBox3.Controls.Add(this.label6); this.groupBox3.Controls.Add(this.label5); this.groupBox3.Controls.Add(this.tb_CAPvol); @@ -645,7 +791,7 @@ // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(391, 54); + this.label6.Location = new System.Drawing.Point(428, 54); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(45, 13); this.label6.TabIndex = 16; @@ -654,7 +800,7 @@ // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(391, 23); + this.label5.Location = new System.Drawing.Point(428, 23); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(45, 13); this.label5.TabIndex = 15; @@ -663,7 +809,7 @@ // tb_CAPvol // this.tb_CAPvol.Cursor = System.Windows.Forms.Cursors.SizeAll; - this.tb_CAPvol.Location = new System.Drawing.Point(442, 50); + this.tb_CAPvol.Location = new System.Drawing.Point(479, 50); this.tb_CAPvol.Maximum = 100; this.tb_CAPvol.MaximumSize = new System.Drawing.Size(0, 24); this.tb_CAPvol.MinimumSize = new System.Drawing.Size(100, 0); @@ -677,7 +823,7 @@ // tb_PBvol // this.tb_PBvol.Cursor = System.Windows.Forms.Cursors.SizeAll; - this.tb_PBvol.Location = new System.Drawing.Point(442, 19); + this.tb_PBvol.Location = new System.Drawing.Point(479, 19); this.tb_PBvol.Maximum = 100; this.tb_PBvol.MaximumSize = new System.Drawing.Size(0, 24); this.tb_PBvol.MinimumSize = new System.Drawing.Size(100, 0); @@ -744,6 +890,35 @@ this.groupBox2.TabStop = false; this.groupBox2.Text = "Personal Settings"; // + // cb_stampinfo + // + this.cb_stampinfo.AutoSize = true; + this.cb_stampinfo.Checked = true; + this.cb_stampinfo.CheckState = System.Windows.Forms.CheckState.Checked; + this.cb_stampinfo.Location = new System.Drawing.Point(71, 82); + this.cb_stampinfo.Name = "cb_stampinfo"; + this.cb_stampinfo.Size = new System.Drawing.Size(128, 17); + this.cb_stampinfo.TabIndex = 23; + this.cb_stampinfo.Text = "Insert Info into picture"; + this.cb_stampinfo.UseVisualStyleBackColor = true; + // + // tb_info + // + this.tb_info.Location = new System.Drawing.Point(243, 28); + this.tb_info.Name = "tb_info"; + this.tb_info.Size = new System.Drawing.Size(413, 20); + this.tb_info.TabIndex = 22; + this.tb_info.Text = "tnx fer QSO, vy 73"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(204, 31); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(28, 13); + this.label7.TabIndex = 21; + this.label7.Text = "Info:"; + // // textBox5 // this.textBox5.BorderStyle = System.Windows.Forms.BorderStyle.None; @@ -842,22 +1017,38 @@ this.cb_savegoodfiles.Text = "Save good files/images only"; this.cb_savegoodfiles.UseVisualStyleBackColor = true; // + // tabPage4 + // + this.tabPage4.Controls.Add(this.richTextBox1); + this.tabPage4.ImageIndex = 12; + this.tabPage4.Location = new System.Drawing.Point(4, 23); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Size = new System.Drawing.Size(1291, 552); + this.tabPage4.TabIndex = 6; + this.tabPage4.Text = "About"; + this.tabPage4.UseVisualStyleBackColor = true; + // + // richTextBox1 + // + this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBox1.Location = new System.Drawing.Point(17, 22); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(855, 527); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = resources.GetString("richTextBox1.Text"); + // // cb_speed // this.cb_speed.FormattingEnabled = true; this.cb_speed.Items.AddRange(new object[] { "3000 QPSK BW: 1700 Hz ", "4000 QPSK BW: 2400 Hz ", - "4410 QPSK BW: 2500 Hz (QO-100)", + "4410 QPSK BW: 2500 Hz (QO-100 Standard)", "4800 QPSK BW: 2700 Hz", "5500 8APSK BW: 2300 Hz", - "6000 8APSK BW: 2500 Hz (QO-100)", + "6000 8APSK BW: 2500 Hz (QO-100 Transceiver)", "6600 8APSK BW: 2600 Hz", - "7200 8APSK BW: 2700 Hz", - "5500 8PSK BW: 2300 Hz", - "6000 8PSK BW: 2500 Hz (QO-100)", - "6600 8PSK BW: 2600 Hz", - "7200 8PSK BW: 2700 Hz"}); + "7200 8APSK BW: 2700 Hz (QO-100 SDR)"}); this.cb_speed.Location = new System.Drawing.Point(658, 591); this.cb_speed.Name = "cb_speed"; this.cb_speed.Size = new System.Drawing.Size(304, 21); @@ -881,10 +1072,11 @@ // // progressBar_fifo // + this.progressBar_fifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); this.progressBar_fifo.Location = new System.Drawing.Point(658, 618); this.progressBar_fifo.Maximum = 20; this.progressBar_fifo.Name = "progressBar_fifo"; - this.progressBar_fifo.Size = new System.Drawing.Size(304, 23); + this.progressBar_fifo.Size = new System.Drawing.Size(304, 18); this.progressBar_fifo.Step = 11; this.progressBar_fifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.progressBar_fifo.TabIndex = 13; @@ -892,59 +1084,303 @@ // label_fifo // this.label_fifo.AutoSize = true; - this.label_fifo.Location = new System.Drawing.Point(567, 623); + this.label_fifo.Location = new System.Drawing.Point(567, 620); this.label_fifo.Name = "label_fifo"; this.label_fifo.Size = new System.Drawing.Size(55, 13); this.label_fifo.TabIndex = 14; this.label_fifo.Text = "TX Buffer:"; // - // trackBar_maxlevel + // bt_blockinfo // - this.trackBar_maxlevel.Location = new System.Drawing.Point(535, 591); - this.trackBar_maxlevel.Maximum = 100; - this.trackBar_maxlevel.Name = "trackBar_maxlevel"; - this.trackBar_maxlevel.Orientation = System.Windows.Forms.Orientation.Vertical; - this.trackBar_maxlevel.Size = new System.Drawing.Size(45, 75); - this.trackBar_maxlevel.TabIndex = 15; - this.trackBar_maxlevel.TickFrequency = 10; - this.trackBar_maxlevel.TickStyle = System.Windows.Forms.TickStyle.TopLeft; - this.trackBar_maxlevel.Value = 50; + this.bt_blockinfo.Location = new System.Drawing.Point(1213, 591); + this.bt_blockinfo.Name = "bt_blockinfo"; + this.bt_blockinfo.Size = new System.Drawing.Size(68, 23); + this.bt_blockinfo.TabIndex = 13; + this.bt_blockinfo.Text = "Block Info"; + this.bt_blockinfo.UseVisualStyleBackColor = true; + this.bt_blockinfo.Click += new System.EventHandler(this.bt_blockinfo_Click); // - // tb_info + // bt_rximages // - this.tb_info.Location = new System.Drawing.Point(243, 28); - this.tb_info.Name = "tb_info"; - this.tb_info.Size = new System.Drawing.Size(413, 20); - this.tb_info.TabIndex = 22; - this.tb_info.Text = "tnx fer QSO, vy 73"; + this.bt_rximages.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_rximages.ImageIndex = 5; + this.bt_rximages.ImageList = this.imageList1; + this.bt_rximages.Location = new System.Drawing.Point(534, 5); + this.bt_rximages.Name = "bt_rximages"; + this.bt_rximages.Size = new System.Drawing.Size(92, 23); + this.bt_rximages.TabIndex = 10; + this.bt_rximages.Text = " RX Images"; + this.bt_rximages.UseVisualStyleBackColor = true; + this.bt_rximages.Click += new System.EventHandler(this.bt_rximages_Click); // - // label7 + // button_loadimage // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(204, 31); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(28, 13); - this.label7.TabIndex = 21; - this.label7.Text = "Info:"; + this.button_loadimage.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button_loadimage.ImageIndex = 5; + this.button_loadimage.ImageList = this.imageList1; + this.button_loadimage.Location = new System.Drawing.Point(265, 5); + this.button_loadimage.Name = "button_loadimage"; + this.button_loadimage.Size = new System.Drawing.Size(88, 23); + this.button_loadimage.TabIndex = 0; + this.button_loadimage.Text = " Load Image"; + this.button_loadimage.UseVisualStyleBackColor = true; + this.button_loadimage.Click += new System.EventHandler(this.button_loadimage_Click); // - // cb_stampinfo + // button_cancelimg // - this.cb_stampinfo.AutoSize = true; - this.cb_stampinfo.Checked = true; - this.cb_stampinfo.CheckState = System.Windows.Forms.CheckState.Checked; - this.cb_stampinfo.Location = new System.Drawing.Point(71, 82); - this.cb_stampinfo.Name = "cb_stampinfo"; - this.cb_stampinfo.Size = new System.Drawing.Size(128, 17); - this.cb_stampinfo.TabIndex = 23; - this.cb_stampinfo.Text = "Insert Info into picture"; - this.cb_stampinfo.UseVisualStyleBackColor = true; + this.button_cancelimg.ForeColor = System.Drawing.Color.Red; + this.button_cancelimg.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button_cancelimg.ImageIndex = 8; + this.button_cancelimg.ImageList = this.imageList1; + this.button_cancelimg.Location = new System.Drawing.Point(443, 5); + this.button_cancelimg.Name = "button_cancelimg"; + this.button_cancelimg.Size = new System.Drawing.Size(75, 23); + this.button_cancelimg.TabIndex = 9; + this.button_cancelimg.Text = " Cancel"; + this.button_cancelimg.UseVisualStyleBackColor = true; + this.button_cancelimg.Click += new System.EventHandler(this.button_cancelimg_Click); + // + // button_sendimage + // + this.button_sendimage.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button_sendimage.ForeColor = System.Drawing.Color.Blue; + this.button_sendimage.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button_sendimage.ImageIndex = 10; + this.button_sendimage.ImageList = this.imageList1; + this.button_sendimage.Location = new System.Drawing.Point(361, 5); + this.button_sendimage.Name = "button_sendimage"; + this.button_sendimage.Size = new System.Drawing.Size(75, 23); + this.button_sendimage.TabIndex = 1; + this.button_sendimage.Text = "Send"; + this.button_sendimage.UseVisualStyleBackColor = true; + this.button_sendimage.Click += new System.EventHandler(this.button_sendimage_Click); + // + // pictureBox_rximage + // + this.pictureBox_rximage.BackgroundImage = global::oscardata.Properties.Resources.image1; + this.pictureBox_rximage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.pictureBox_rximage.Location = new System.Drawing.Point(642, 27); + this.pictureBox_rximage.Name = "pictureBox_rximage"; + this.pictureBox_rximage.Size = new System.Drawing.Size(640, 480); + this.pictureBox_rximage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBox_rximage.TabIndex = 3; + this.pictureBox_rximage.TabStop = false; + // + // pictureBox_tximage + // + this.pictureBox_tximage.BackgroundImage = global::oscardata.Properties.Resources.image; + this.pictureBox_tximage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.pictureBox_tximage.Location = new System.Drawing.Point(1, 27); + this.pictureBox_tximage.Name = "pictureBox_tximage"; + this.pictureBox_tximage.Size = new System.Drawing.Size(640, 480); + this.pictureBox_tximage.TabIndex = 2; + this.pictureBox_tximage.TabStop = false; + // + // pictureBox1 + // + this.pictureBox1.BackgroundImage = global::oscardata.Properties.Resources.text_big; + this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.pictureBox1.Location = new System.Drawing.Point(17, 371); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(127, 134); + this.pictureBox1.TabIndex = 13; + this.pictureBox1.TabStop = false; + // + // button2 + // + this.button2.ForeColor = System.Drawing.Color.Red; + this.button2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button2.ImageIndex = 8; + this.button2.ImageList = this.imageList1; + this.button2.Location = new System.Drawing.Point(17, 218); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(137, 23); + this.button2.TabIndex = 12; + this.button2.Text = "Cancel"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button_cancelimg_Click); + // + // bt_openrxfile + // + this.bt_openrxfile.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_openrxfile.ImageIndex = 5; + this.bt_openrxfile.ImageList = this.imageList1; + this.bt_openrxfile.Location = new System.Drawing.Point(17, 306); + this.bt_openrxfile.Name = "bt_openrxfile"; + this.bt_openrxfile.Size = new System.Drawing.Size(137, 30); + this.bt_openrxfile.TabIndex = 11; + this.bt_openrxfile.Text = "Open RX file folder"; + this.bt_openrxfile.UseVisualStyleBackColor = true; + this.bt_openrxfile.Click += new System.EventHandler(this.bt_openrxfile_Click); + // + // bt_file_send + // + this.bt_file_send.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.bt_file_send.ForeColor = System.Drawing.Color.Blue; + this.bt_file_send.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_file_send.ImageIndex = 10; + this.bt_file_send.ImageList = this.imageList1; + this.bt_file_send.Location = new System.Drawing.Point(17, 157); + this.bt_file_send.Name = "bt_file_send"; + this.bt_file_send.Size = new System.Drawing.Size(137, 30); + this.bt_file_send.TabIndex = 3; + this.bt_file_send.Text = "SEND"; + this.bt_file_send.UseVisualStyleBackColor = true; + this.bt_file_send.Click += new System.EventHandler(this.bt_file_send_Click); + // + // bt_sendBinaryFile + // + this.bt_sendBinaryFile.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_sendBinaryFile.ImageIndex = 0; + this.bt_sendBinaryFile.ImageList = this.imageList1; + this.bt_sendBinaryFile.Location = new System.Drawing.Point(17, 89); + this.bt_sendBinaryFile.Name = "bt_sendBinaryFile"; + this.bt_sendBinaryFile.Size = new System.Drawing.Size(137, 23); + this.bt_sendBinaryFile.TabIndex = 2; + this.bt_sendBinaryFile.Text = "Load Binary File"; + this.bt_sendBinaryFile.UseVisualStyleBackColor = true; + this.bt_sendBinaryFile.Click += new System.EventHandler(this.bt_sendBinaryFile_Click); + // + // bt_file_html + // + this.bt_file_html.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_file_html.ImageIndex = 2; + this.bt_file_html.ImageList = this.imageList1; + this.bt_file_html.Location = new System.Drawing.Point(17, 60); + this.bt_file_html.Name = "bt_file_html"; + this.bt_file_html.Size = new System.Drawing.Size(137, 23); + this.bt_file_html.TabIndex = 1; + this.bt_file_html.Text = "Load HTML File"; + this.bt_file_html.UseVisualStyleBackColor = true; + this.bt_file_html.Click += new System.EventHandler(this.button2_Click); + // + // bt_file_ascii + // + this.bt_file_ascii.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.bt_file_ascii.ImageIndex = 9; + this.bt_file_ascii.ImageList = this.imageList1; + this.bt_file_ascii.Location = new System.Drawing.Point(17, 31); + this.bt_file_ascii.Name = "bt_file_ascii"; + this.bt_file_ascii.Size = new System.Drawing.Size(137, 23); + this.bt_file_ascii.TabIndex = 0; + this.bt_file_ascii.Text = " Load ASCII Text File"; + this.bt_file_ascii.UseVisualStyleBackColor = true; + this.bt_file_ascii.Click += new System.EventHandler(this.bt_file_ascii_Click); + // + // pictureBox2 + // + this.pictureBox2.BackgroundImage = global::oscardata.Properties.Resources.voice_big; + this.pictureBox2.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.pictureBox2.Location = new System.Drawing.Point(6, 13); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size(75, 76); + this.pictureBox2.TabIndex = 22; + this.pictureBox2.TabStop = false; + // + // pb_voice + // + this.pb_voice.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.pb_voice.Location = new System.Drawing.Point(308, 19); + this.pb_voice.Name = "pb_voice"; + this.pb_voice.Size = new System.Drawing.Size(440, 85); + this.pb_voice.TabIndex = 22; + this.pb_voice.TabStop = false; + // + // pb_voiceCAPstatus + // + this.pb_voiceCAPstatus.BackgroundImage = global::oscardata.Properties.Resources.ok; + this.pb_voiceCAPstatus.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.pb_voiceCAPstatus.Location = new System.Drawing.Point(387, 58); + this.pb_voiceCAPstatus.Name = "pb_voiceCAPstatus"; + this.pb_voiceCAPstatus.Size = new System.Drawing.Size(21, 21); + this.pb_voiceCAPstatus.TabIndex = 19; + this.pb_voiceCAPstatus.TabStop = false; + // + // pb_voicePBstatus + // + this.pb_voicePBstatus.BackgroundImage = global::oscardata.Properties.Resources.ok; + this.pb_voicePBstatus.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.pb_voicePBstatus.Location = new System.Drawing.Point(387, 25); + this.pb_voicePBstatus.Name = "pb_voicePBstatus"; + this.pb_voicePBstatus.Size = new System.Drawing.Size(21, 21); + this.pb_voicePBstatus.TabIndex = 18; + this.pb_voicePBstatus.TabStop = false; + // + // button_stopBERtest + // + this.button_stopBERtest.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button_stopBERtest.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button_stopBERtest.ImageIndex = 8; + this.button_stopBERtest.ImageList = this.imageList1; + this.button_stopBERtest.Location = new System.Drawing.Point(113, 13); + this.button_stopBERtest.Name = "button_stopBERtest"; + this.button_stopBERtest.Size = new System.Drawing.Size(101, 32); + this.button_stopBERtest.TabIndex = 4; + this.button_stopBERtest.Text = "STOP"; + this.button_stopBERtest.UseVisualStyleBackColor = true; + this.button_stopBERtest.Click += new System.EventHandler(this.button_stopBERtest_Click); + // + // button_startBERtest + // + this.button_startBERtest.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button_startBERtest.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.button_startBERtest.ImageIndex = 7; + this.button_startBERtest.ImageList = this.imageList1; + this.button_startBERtest.Location = new System.Drawing.Point(6, 13); + this.button_startBERtest.Name = "button_startBERtest"; + this.button_startBERtest.Size = new System.Drawing.Size(101, 32); + this.button_startBERtest.TabIndex = 3; + this.button_startBERtest.Text = "START"; + this.button_startBERtest.UseVisualStyleBackColor = true; + this.button_startBERtest.Click += new System.EventHandler(this.button_startBERtest_Click); + // + // pb_audioCAPstatus + // + this.pb_audioCAPstatus.BackgroundImage = global::oscardata.Properties.Resources.ok; + this.pb_audioCAPstatus.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.pb_audioCAPstatus.Location = new System.Drawing.Point(375, 52); + this.pb_audioCAPstatus.Name = "pb_audioCAPstatus"; + this.pb_audioCAPstatus.Size = new System.Drawing.Size(21, 21); + this.pb_audioCAPstatus.TabIndex = 18; + this.pb_audioCAPstatus.TabStop = false; + // + // pb_audioPBstatus + // + this.pb_audioPBstatus.BackgroundImage = global::oscardata.Properties.Resources.ok; + this.pb_audioPBstatus.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.pb_audioPBstatus.Location = new System.Drawing.Point(375, 19); + this.pb_audioPBstatus.Name = "pb_audioPBstatus"; + this.pb_audioPBstatus.Size = new System.Drawing.Size(21, 21); + this.pb_audioPBstatus.TabIndex = 17; + this.pb_audioPBstatus.TabStop = false; + // + // progressBar_capfifo + // + this.progressBar_capfifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); + this.progressBar_capfifo.Location = new System.Drawing.Point(658, 642); + this.progressBar_capfifo.Name = "progressBar_capfifo"; + this.progressBar_capfifo.Size = new System.Drawing.Size(304, 18); + this.progressBar_capfifo.Step = 1; + this.progressBar_capfifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBar_capfifo.TabIndex = 15; + // + // label_capfifo + // + this.label_capfifo.AutoSize = true; + this.label_capfifo.Location = new System.Drawing.Point(567, 643); + this.label_capfifo.Name = "label_capfifo"; + this.label_capfifo.Size = new System.Drawing.Size(56, 13); + this.label_capfifo.TabIndex = 16; + this.label_capfifo.Text = "RX Buffer:"; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1293, 691); - this.Controls.Add(this.trackBar_maxlevel); + this.Controls.Add(this.label_capfifo); + this.Controls.Add(this.progressBar_capfifo); + this.Controls.Add(this.bt_blockinfo); this.Controls.Add(this.label_fifo); this.Controls.Add(this.progressBar_fifo); this.Controls.Add(this.cb_speed); @@ -956,7 +1392,7 @@ this.ForeColor = System.Drawing.SystemColors.ControlText; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "Form1"; - this.Text = "QO-100 NB Transponder HS Transmission AMSAT-DL V0.2 by DJ0ABR"; + this.Text = "QO-100 NB Transponder HS Multimedia Modem AMSAT-DL V0.4 by DJ0ABR"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); @@ -965,11 +1401,18 @@ this.tabPage2.PerformLayout(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox_rximage)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox_tximage)).EndInit(); this.tabControl1.ResumeLayout(false); this.tabPage3.ResumeLayout(false); this.tabPage3.PerformLayout(); + this.tabPage_audio.ResumeLayout(false); + this.groupBox7.ResumeLayout(false); + this.groupBox7.PerformLayout(); + this.groupBox6.ResumeLayout(false); + this.groupBox6.PerformLayout(); + this.groupBox5.ResumeLayout(false); + this.groupBox5.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.tb_mic)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.tb_loadspeaker)).EndInit(); this.tabPage5.ResumeLayout(false); this.groupBox4.ResumeLayout(false); this.groupBox4.PerformLayout(); @@ -979,7 +1422,16 @@ ((System.ComponentModel.ISupportInitialize)(this.tb_PBvol)).EndInit(); this.groupBox2.ResumeLayout(false); this.groupBox2.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar_maxlevel)).EndInit(); + this.tabPage4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox_rximage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox_tximage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voice)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voiceCAPstatus)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_voicePBstatus)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_audioCAPstatus)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pb_audioPBstatus)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -1058,10 +1510,41 @@ private System.Windows.Forms.TextBox textBox4; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox3; - private System.Windows.Forms.TrackBar trackBar_maxlevel; private System.Windows.Forms.CheckBox cb_stampinfo; private System.Windows.Forms.TextBox tb_info; private System.Windows.Forms.Label label7; + private System.Windows.Forms.TabPage tabPage_audio; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TrackBar tb_mic; + private System.Windows.Forms.TrackBar tb_loadspeaker; + private System.Windows.Forms.ComboBox cb_loudspeaker; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.ComboBox cb_mic; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Button bt_blockinfo; + private System.Windows.Forms.CheckBox cb_switchtoLS; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.CheckBox cb_voiceloop; + private System.Windows.Forms.CheckBox cb_codecloop; + private System.Windows.Forms.CheckBox cb_digitalVoice; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.RadioButton rb_opus; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.PictureBox pictureBox2; + private System.Windows.Forms.TabPage tabPage4; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.PictureBox pb_voiceCAPstatus; + private System.Windows.Forms.PictureBox pb_voicePBstatus; + private System.Windows.Forms.PictureBox pb_audioCAPstatus; + private System.Windows.Forms.PictureBox pb_audioPBstatus; + private System.Windows.Forms.RadioButton rb_codec2; + private System.Windows.Forms.CheckBox cb_digitalVoiceRXonly; + private System.Windows.Forms.PictureBox pb_voice; + private System.Windows.Forms.ProgressBar progressBar_capfifo; + private System.Windows.Forms.Label label_capfifo; } } diff --git a/oscardata/oscardata/Form1.cs b/oscardata/oscardata/Form1.cs index 46a7ae4..3a0ffeb 100755 --- a/oscardata/oscardata/Form1.cs +++ b/oscardata/oscardata/Form1.cs @@ -29,6 +29,7 @@ using System.Text; using System.IO; using System.Drawing.Drawing2D; using System.Diagnostics; +using System.Threading; namespace oscardata { @@ -42,6 +43,8 @@ namespace oscardata String old_tsip = ""; bool modemrunning = false; receivefile recfile = new receivefile(); + int last_initAudioStatus; + int last_initVoiceStatus; public Form1() { @@ -60,6 +63,8 @@ namespace oscardata else statics.ostype = 1; // Linux + statics.CreateAllDirs(); + // set temp paths statics.zip_TXtempfilename = statics.addTmpPath(statics.zip_TXtempfilename); statics.zip_RXtempfilename = statics.addTmpPath(statics.zip_RXtempfilename); @@ -192,19 +197,42 @@ namespace oscardata { statics.GotAudioDevices = 2; // populate combo boxes + cb_audioPB.BeginUpdate(); + cb_audioPB.Items.Clear(); + cb_loudspeaker.BeginUpdate(); + cb_loudspeaker.Items.Clear(); foreach (String s in statics.AudioPBdevs) { - if(s.Length > 1) + if (s.Length > 1) + { cb_audioPB.Items.Add(s); + cb_loudspeaker.Items.Add(s); + } } + cb_loudspeaker.EndUpdate(); + cb_audioPB.EndUpdate(); + // check if displayed text is available in the item list + findDevice(cb_loudspeaker); + findDevice(cb_audioPB); + + cb_audioCAP.BeginUpdate(); + cb_audioCAP.Items.Clear(); + cb_mic.BeginUpdate(); + cb_mic.Items.Clear(); foreach (String s in statics.AudioCAPdevs) { if (s.Length > 1) + { cb_audioCAP.Items.Add(s); + cb_mic.Items.Add(s); + } } + cb_mic.EndUpdate(); + cb_audioCAP.EndUpdate(); + findDevice(cb_mic); + findDevice(cb_audioCAP); } - if (setPBvolume >= 0) { Byte[] txdata = new byte[2]; @@ -222,15 +250,124 @@ namespace oscardata Udp.UdpSendCtrl(txdata); setCAPvolume = -1; } + + if (setLSvolume >= 0) + { + Byte[] txdata = new byte[2]; + txdata[0] = (Byte)statics.SetLSvolume; + txdata[1] = (Byte)setLSvolume; + Udp.UdpSendCtrl(txdata); + setLSvolume = -1; + } + + if (setMICvolume != -1) + { + Byte[] txdata = new byte[2]; + txdata[0] = (Byte)statics.SetMICvolume; + txdata[1] = (Byte)setMICvolume; + Udp.UdpSendCtrl(txdata); + setMICvolume = -1; + } + + if (last_initAudioStatus != statics.initAudioStatus) + { + if ((statics.initAudioStatus & 1) == 1) + pb_audioPBstatus.BackgroundImage = Properties.Resources.fail; + else + pb_audioPBstatus.BackgroundImage = Properties.Resources.ok; + + if ((statics.initAudioStatus & 2) == 2) + pb_audioCAPstatus.BackgroundImage = Properties.Resources.fail; + else + pb_audioCAPstatus.BackgroundImage = Properties.Resources.ok; + + last_initAudioStatus = statics.initAudioStatus; + } + + if (last_initVoiceStatus != statics.initVoiceStatus) + { + if ((statics.initVoiceStatus & 1) == 1) + pb_voicePBstatus.BackgroundImage = Properties.Resources.fail; + else + pb_voicePBstatus.BackgroundImage = Properties.Resources.ok; + + if ((statics.initVoiceStatus & 2) == 2) + pb_voiceCAPstatus.BackgroundImage = Properties.Resources.fail; + else + pb_voiceCAPstatus.BackgroundImage = Properties.Resources.ok; + + last_initVoiceStatus = statics.initVoiceStatus; + } } + // correct entries in the Audio Device Comboboxes if Devices have changed + void findDevice(ComboBox cb) + { + int pos = -1; + + if (cb.Text.Length >= 4) + { + // Device Name starts at Index 3 in the string + String dn = cb.Text.Substring(3); + int anz = cb.Items.Count; + for (int i = 0; i < anz; i++) + { + String name = cb.Items[i].ToString(); + name = name.Substring(3); + if (dn == name) + { + pos = i; + break; + } + } + } + + if (pos == -1) + { + // not available, reset to first item which usually is Default + if (cb.Items.Count == 0) + cb.Text = "no sound devices available"; + else + cb.Text = cb.Items[0].ToString(); + } + else + cb.Text = cb.Items[pos].ToString(); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) { save_Setup(); + if (cb_autostart.Checked) { - statics.killall("hsmodem"); - statics.killall("hsmodem.exe"); + // tell hsmodem to terminate itself + Byte[] txdata = new byte[1]; + txdata[0] = (Byte)statics.terminate; + Udp.UdpSendCtrl(txdata); + + Thread.Sleep(250); + + if (statics.ostype == 0) + { + int to = 0; + while(statics.isProcRunning("hsmodem.exe")) + { + Thread.Sleep(250); + // tell hsmodem to terminate itself + Udp.UdpSendCtrl(txdata); + if (++to >= 10) break; // give up after 2,5s + } + + if (to >= 10) + statics.killall("hsmodem.exe"); + } + else + { + Thread.Sleep(250); + statics.killall("hsmodem"); + } + } // exit the threads statics.running = false; @@ -264,13 +401,6 @@ namespace oscardata rxbytecounter += statics.UdpBlocklen; - trackBar_maxlevel.Value = maxlevel; - int v1 = 255; - int v2 = 220; - if (maxlevel < 20 || maxlevel > 70) trackBar_maxlevel.BackColor = Color.FromArgb(v1,v2,v2); - else if (maxlevel < 30 || maxlevel > 60) trackBar_maxlevel.BackColor = Color.FromArgb(v1, v1, v2); - else trackBar_maxlevel.BackColor = Color.FromArgb(v2, v1, v2); - Byte[] rxdata = new byte[rxd.Length - 10]; Array.Copy(rxd, 10, rxdata, 0, rxd.Length - 10); @@ -334,6 +464,10 @@ namespace oscardata printText(rtb_RXfile, "transmission speed: " + ((int)(recfile.filesize * 8 / recfile.runtime.TotalSeconds)).ToString() + " bit/s" + "\r\n\r\n"); printText(rtb_RXfile, "file size : " + recfile.filesize + " byte\r\n\r\n"); printText(rtb_RXfile, "file name : " + recfile.filename + "\r\n\r\n"); + if(recfile.filename.Length <= 1) + { + printText(rtb_RXfile, "file status : not complete, retransmit\r\n\r\n"); + } } } @@ -378,6 +512,11 @@ namespace oscardata if (statics.PBfifousage < progressBar_fifo.Minimum) progressBar_fifo.Value = progressBar_fifo.Minimum; else if (statics.PBfifousage >= progressBar_fifo.Maximum) progressBar_fifo.Value = progressBar_fifo.Maximum-1; else progressBar_fifo.Value = statics.PBfifousage; + + progressBar_capfifo.Invalidate(); + if (statics.CAPfifousage < progressBar_capfifo.Minimum) progressBar_capfifo.Value = progressBar_capfifo.Minimum; + else if (statics.CAPfifousage >= progressBar_capfifo.Maximum) progressBar_capfifo.Value = progressBar_capfifo.Maximum - 1; + else progressBar_capfifo.Value = statics.CAPfifousage; } private void panel_constel_Paint(object sender, PaintEventArgs e) @@ -877,14 +1016,18 @@ namespace oscardata label_txfile.Location = new Point(rtb_TXfile.Location.X, ly); label_rxfile.Location = new Point(rtb_RXfile.Location.X, ly); - trackBar_maxlevel.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 5, panel_txspectrum.Location.Y); - trackBar_maxlevel.Size = new Size(20, panel_txspectrum.Size.Height); - - label_speed.Location = new Point(trackBar_maxlevel.Location.X + trackBar_maxlevel.Size.Width + 15,panel_txspectrum.Location.Y+10); + label_speed.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 15,panel_txspectrum.Location.Y+10); cb_speed.Location = new Point(label_speed.Location.X + label_speed.Size.Width + 10, label_speed.Location.Y-5); - label_fifo.Location = new Point(label_speed.Location.X, label_speed.Location.Y + 35); - progressBar_fifo.Location = new Point(cb_speed.Location.X, cb_speed.Location.Y + 35); + int y = 26; + label_fifo.Location = new Point(label_speed.Location.X, label_speed.Location.Y + y); + progressBar_fifo.Location = new Point(cb_speed.Location.X, cb_speed.Location.Y + y+5); + progressBar_fifo.Size = new Size(progressBar_fifo.Width, 18); + + y = 20; + label_capfifo.Location = new Point(label_fifo.Location.X, label_fifo.Location.Y + y); + progressBar_capfifo.Location = new Point(progressBar_fifo.Location.X, progressBar_fifo.Location.Y + y); + progressBar_capfifo.Size = new Size(progressBar_capfifo.Width, 18); } public String GetMyBroadcastIP() @@ -923,6 +1066,24 @@ namespace oscardata return x; } + Byte getLSaudioDevice() + { + String s = cb_loudspeaker.Text; + Byte x = (Byte)cb_loudspeaker.Items.IndexOf(s); + Console.WriteLine("LS:" + s + " " + x); + //if (s.ToUpper() == "DEFAULT") x = 255; + return x; + } + + Byte getMICaudioDevice() + { + String s = cb_mic.Text; + Byte x = (Byte)cb_mic.Items.IndexOf(s); + Console.WriteLine("MIC:" + s + " " + x); + //if (s.ToUpper() == "DEFAULT") x = 255; + return x; + } + /* * search for the modem IP: * send a search message via UDP to port UdpBCport @@ -933,13 +1094,15 @@ namespace oscardata private void search_modem() { - Byte[] txb = new byte[6]; + Byte[] txb = new byte[8]; txb[0] = 0x3c; // ID of this message txb[1] = getPBaudioDevice(); txb[2] = getCAPaudioDevice(); txb[3] = (Byte)tb_PBvol.Value; txb[4] = (Byte)tb_CAPvol.Value; txb[5] = (Byte)cb_announcement.Items.IndexOf(cb_announcement.Text); + txb[6] = (Byte)tb_loadspeaker.Value; + txb[7] = (Byte)tb_mic.Value; Udp.UdpBCsend(txb, GetMyBroadcastIP(), statics.UdpBCport_AppToModem); @@ -1128,6 +1291,17 @@ namespace oscardata s = ReadString(sr); try { cb_stampinfo.Checked = (s == "1"); } catch { } try { tb_info.Text = ReadString(sr); } catch { } + try { cb_loudspeaker.Text = ReadString(sr); } catch { } + try { cb_mic.Text = ReadString(sr); } catch { } + try { tb_loadspeaker.Value = ReadInt(sr); } catch { } + try { tb_mic.Value = ReadInt(sr); } catch { } + try + { + s = ReadString(sr); + rb_opus.Checked = (s == "1"); + rb_codec2.Checked = (s != "1"); + } + catch { } } } catch @@ -1158,6 +1332,11 @@ namespace oscardata sw.WriteLine(cb_announcement.Text); sw.WriteLine(cb_stampinfo.Checked ? "1" : "0"); sw.WriteLine(tb_info.Text); + sw.WriteLine(cb_loudspeaker.Text); + sw.WriteLine(cb_mic.Text); + sw.WriteLine(tb_loadspeaker.Value.ToString()); + sw.WriteLine(tb_mic.Value.ToString()); + sw.WriteLine(rb_opus.Checked ? "1" : "0"); } } catch { } @@ -1208,5 +1387,137 @@ namespace oscardata { setCAPvolume = tb_CAPvol.Value; } + + private void bt_blockinfo_Click(object sender, EventArgs e) + { + String s; + int[] d = new int[2]; + recfile.oldblockinfo(d); + int failed = d[0] - d[1]; + + s = "Received Blocks\n" + + "---------------\n" + + "total : " + d[0] + "\n" + + "good : " + d[1] + "\n" + + "failed: " + failed + "\n"; + if(failed > 1) + { + s += "\nfile incomplete, ask for retransmission"; + } + + Form2_showtext sf = new Form2_showtext("Block Info",s); + sf.ShowDialog(); + } + + void setVoiceAudio() + { + Byte[] txdata = new byte[5]; + txdata[0] = (Byte)statics.SetVoiceMode; + txdata[1] = (Byte)getLSaudioDevice(); + txdata[2] = (Byte)getMICaudioDevice(); + Byte opmode = 0; + // values see: hsmodem.h _VOICEMODES_ + if (cb_switchtoLS.Checked) opmode = 1; + if (cb_voiceloop.Checked) opmode = 2; + if (cb_codecloop.Checked) opmode = 3; + if (cb_digitalVoice.Checked) opmode = 4; + if (cb_digitalVoiceRXonly.Checked) opmode = 5; + if(opmode == 0) pb_voice.BackgroundImage = null; + txdata[3] = opmode; + Byte codec; + if (rb_opus.Checked) codec = 0; + else codec = 1; + txdata[4] = codec; + Udp.UdpSendCtrl(txdata); + + if(opmode > 0) + { + rb_opus.Enabled = false; + rb_codec2.Enabled = false; + } + else + { + rb_opus.Enabled = true; + rb_codec2.Enabled = true; + } + } + + private void cb_switchtoLS_CheckedChanged(object sender, EventArgs e) + { + if(cb_switchtoLS.Checked) + { + cb_voiceloop.Checked = false; + cb_codecloop.Checked = false; + cb_digitalVoice.Checked = false; + cb_digitalVoiceRXonly.Checked = false; + pb_voice.BackgroundImage = Properties.Resources.cdc_digital; + } + setVoiceAudio(); + } + + private void cb_voiceloop_CheckedChanged(object sender, EventArgs e) + { + if (cb_voiceloop.Checked) + { + cb_switchtoLS.Checked = false; + cb_codecloop.Checked = false; + cb_digitalVoice.Checked = false; + cb_digitalVoiceRXonly.Checked = false; + pb_voice.BackgroundImage = Properties.Resources.cdc_intloop; + } + setVoiceAudio(); + } + + private void cb_codecloop_CheckedChanged(object sender, EventArgs e) + { + if (cb_codecloop.Checked) + { + cb_switchtoLS.Checked = false; + cb_voiceloop.Checked = false; + cb_digitalVoice.Checked = false; + cb_digitalVoiceRXonly.Checked = false; + pb_voice.BackgroundImage = Properties.Resources.cdc_codecloop; + } + setVoiceAudio(); + } + + private void cb_digitalVoice_CheckedChanged(object sender, EventArgs e) + { + if (cb_digitalVoice.Checked) + { + cb_switchtoLS.Checked = false; + cb_voiceloop.Checked = false; + cb_codecloop.Checked = false; + cb_digitalVoiceRXonly.Checked = false; + pb_voice.BackgroundImage = Properties.Resources.cdc_dv; + } + setVoiceAudio(); + } + + private void cb_digitalVoiceRXonly_CheckedChanged(object sender, EventArgs e) + { + if (cb_digitalVoiceRXonly.Checked) + { + cb_switchtoLS.Checked = false; + cb_voiceloop.Checked = false; + cb_codecloop.Checked = false; + cb_digitalVoice.Checked = false; + pb_voice.BackgroundImage = Properties.Resources.cdc_dvrx; + } + setVoiceAudio(); + } + + int setLSvolume = -1; + int setMICvolume = -1; + + private void tb_loadspeaker_Scroll(object sender, EventArgs e) + { + setLSvolume = tb_loadspeaker.Value; + } + + private void tb_mic_Scroll(object sender, EventArgs e) + { + setMICvolume = tb_mic.Value; + } } } diff --git a/oscardata/oscardata/Form1.resx b/oscardata/oscardata/Form1.resx index a7c4dc1..0ec0ac3 100755 --- a/oscardata/oscardata/Form1.resx +++ b/oscardata/oscardata/Form1.resx @@ -129,6 +129,158 @@ 371, 17 + + 644, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABw + FwAAAk1TRnQBSQFMAgEBDQEAAbABAAGwAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAUADAAEBAQABCAYAARAYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wQAARoBmQEbAf8CAAH/ + AfQBGgGZAf81AAF0ATIBNwFLAfEB9AF0ATEBOAEyAfM1AAF5AzgCNwM4ATEB8zUAAZkEOAH7AzgBMQH0 + NQABmQg4ATEB9jUAAZkEegJZAjgBMQH0MwAB/wGZAVgIegFZAXkB/zIAARoBWQt6AVIB/zAAAfQBeQ16 + ARowAAHzAVIMegF5AZkxAAH2ARsBGgGZBnoBmQEaARsB9AH/NQABGwF6ApoBegF5Af85AAH/AXkCoAF6 + AfY7AAH2AXoBoAEaPQABGwGaAf93AAH/DPIB9AH/BwABBwHsAeoBbQHqAewBvBMABP8B9AHzAQcB7wHw + AfQF/wEAAZMDRQZGBEUB9AkAAW0BEwHsBgAC/wn2Af8FAAH0AfAB9wEUARECEAYAAf8BbwIfAUYGJQFG + ASQBHwFFAfIDAAH0BfMBbQFDAZIFAAH/AZkBUwkyAXUB/wEAAf8BBwHwAfEB9AH/AfMCBwHyAwAB/wIA + Af8BbwEfAW8B9AF0ASUCJgIlARsBkwEfAUUB8gMAAe0BEQFEAQEBRAIRAQ8BkgUAAf8CUwGaAVMBwwFZ + AcMBWQQyAfYBAAH/AfIB8AERAfQHAAHxAUMB8wEAAf8BbwEfAZMC8wF1AiwBTQHxAfMB8AFFASQB8gQA + Af8BRQEfAW4B/wHrAQ4B7QUAAf8BMgFTARoBWQH/AVkB/wFZBDIB9gEAAfQB7AETAQ8B8gcAAe8BEQEV + AfEB/wFvAR8BJAGTAfIB8QF1ASwBvAHxAbwBJAEfASQB8gUAAW8BIAGTAQABbQEAAe0FAAH/AzIBmgHD + AVkB/wE4BDIB9gEAAfQBDgHqARAB8gcAAe8BQwEVAZIB/wFvAh8BJAGTAfEB8AK8AQcBRgMfAfIFAAFv + ASABkwEAAW0BAAHtBQAB/wEyAVMBGgGaAVMBmgF6BTIB9gEAAfQB6gHrAUMB8gcAAe8BEwHqAQcB/wFv + AQEBHwEkAUYBHAHxAfABBwElAh8BAQEfAfIFAAFvASABkwEAAesBEAHtBQAB/wEsAjIBWQH2ARoBUwUy + AfYCAAEHAe0BFAHyBwAB7wFtAewB8AH/AW8BRQFGAUwBbwPxAfABkwFvAUYCRQHyBAAB/wFuASABkwEA + AesBDwGSAwAB8wEAAf8BUwF6AcMBGgGaAXoBWQJ6A1MB/wIAAfIBvAESAfMHAAEHAesB8AHzAf8EbwHx + AfIBvAEHAfEB8gGTA28B8gQAAfMBCwEfAZMBAAHrAREBkgMAARMBAAH/AVMDdQR6BHUB/wIAAfQBvAH/ + CQAB/wHvAf8BAAJvAZMC8wG8AZMBbwEHAfIB8wGTAm8B8wQAAfQBDwEBAZMBAAHrAUMBkgEAAf8BvAER + AQAB/wFTCnoBdQH/AgAB/wGSAfQJAAHyAe8B/wEAAm8BvAHzAfAEbwHvAvMBkwFvAfMEAAH/AREBEAFD + AW0BQwIVAW0BFAERARQBAAH/AVMKegF1Af8DAAH/AfIJAAHyAwADkwEHBpMB7wOTAfMB9AFvAgAB/wIS + AW0D7QFEAu0B7AGSAQAB/wF1CpoBegH/BAABvAHvAf8FAAH0AewB8QMADpMB8wH/AUUB/wIAARwB7QHv + AgAB8QFFBQAB/wEbAXoJdQEaAf8EAAH/AkMBvAL/AfQBBwEQAW0B/wMAAfMMkwEaAv8CbgLvAW4B9wHs + Ae8BkwJuBgAM/wYAAf8B7wETAw4BFAEHAf8TAAH/C28bAAH/AfMB/wYABP8C9AHvAewBkgHyAfQF/wMA + C/8CAAH/AfAB7wHyAf8HAAH/AfMBGgH/EwAB9AESAewE7wHsAfAFAAH/AfQK8gHzAf8BAAH/AQcB/wHv + AfIB/wUAAf8B8gFSATgBGgQAAfQBCAwAAfAC7ALwAv8B9AGSAfAB7QQAAf8B8gHxAQgCvAHwAQgEGwLz + Av8BBwG8AewB7QHyAf8DAAH/AfABUgI4AZkEAAHyAU8BlwH0CQAB/wHsAW0D/wL0Av8BBwHzAQcDAAH0 + AfMBcgEoAS4BLwF4AS8ENQEbAfIB/wEAAfQBBwEUAQ8B7QH0Af8BAAH/AfIBMQE4AVkBdAH/BAAB8gIt + AU8B/wgAAeoBbQH0AbwD9AHzAfQBBwH0AZIBBwMAAfQB8wFyAigCmAIvAzUBGwHyAf8BAAH/AfQB7wET + ARQB9wH0Af8B8wFSAlkBmQH/BQAB8gIzAS0BTwG8Af8FAAH/Ae0BvAT0AfMB8gT0AfEBBwIAAfQB8wFy + AigB/wEIBS8BCAHyAf8DAAH/AQcBEgFDAe8BvAExATgBWQGZAf8GAAHyAjMCLQECAZgB/wQAAfAB7AH0 + AfMC9AEHAfQBGgP0AfAB7QHsAgAB9AHzAXICKAH/AfQBUAEuAXgBUAEvAbwB8gH/BAAB/wEHAhIB7QFZ + ATIB8wH/BwAB8gIzAS0CAgEnAXIB9AMAAQcB7AL0AvMB9AEfAbwE9AHtAe8BDgEAAfQB8wFyAigB9AL/ + AbwB/wFQASgBvAHyAf8FAAH/Ae8B7AHwAfcBvAH/CAAB8gMtAgIBJwEhAUkB9AIAAbwBkgLzAfAC8wEH + Ae0E8wHtAe8B/wEAAfQB8wFyAigBUAH0A/8BUAEoAbwB8gH/BQAB/wIHAewB6wEHAfMC/wYAAfEGTwFJ + AZgB/wIAAf8BBwHxAfMB8gHzAZMC8wEHAvMB8QHwAQcCAAH0AfMBcgMoAZgD/wFQASgBvAHyAf8EAAH/ + AQcB8QHyAQcB7wHsAesB7AHvAfQB/wQAAfEGTwEIBQABBwHrAfMB7wHzARoD8wHwAfEB7AHzAf8CAAH0 + AfMBcgIoAVAECAFKASgBvAHyAf8DAAH0AQcBvAHyAv8B8AHsAe0B7wLtAfQEAAHxAU8EcgHxAf8FAAHz + AfEB7AHyAfAD8wHyAbwB7AHxAe8DAAH0AfMBcgkoAbwB8gH/AgAB/wEHAfIB8wMAAfIBvAEHAbwC7wHx + BAAB8QFyAZcBcgFJAfQIAAEHAfMB6wHvAfcBBwHvAe0BbQHwAe0B9wHtAf8BAAH0AfMBHAlyAfEB8gL/ + AfMB7wG8AfMB/wMAAfQBBwHyAQcB9AH/AfQEAAHxAnIB7wH/CgAC8wG8Ae0C7AEHAfMBBwHyAbwB9AEH + AQAB/wHwCvMB8gH0AQAB/wIHAfMFAAH/Ae8B9AHvAfMB/wUAAfEBTwEIAf8NAAHzAbwBBwG8AfICAAHy + AfQBAAG8AQAC/wr0Av8BAAH/AfEB8gH/BQAB/wHyAfAB8wEHAfQFAAH/AfMXAALxHAAB/wHzAf8cAAH/ + AfADmAH0IAAF/wH0Cv8B9A3yAZEB7xAAEP8QAAHxAvQC/wHvA/8B8gHxAfQBCAG7AfABkQQAAQEBHgQA + Af8BRQEBAwAB8wHwBfIC8QbyAfABAAG8ArQLtQH/AfIC9AL/Ae8D/wHyAfEBcgFxAZEBSQFyAwABAQH5 + AUcBCwIAAf8BHgH5ARcBAQIAAfIB8wP/AfMBuwK0AQkB9AT/AfABAAH3AUMBFQJKAUQBQwERA0MBFQFD + ARMB9AHyAvQC/wHvA/8B8gHxAUkC/wEHAXECAAGTAW8C+QFHAQsB/wELA/kBRQIAAfIB8wL/AfQBtAGz + AgkCtAHxA/8B8AEAAfcBEQFDAkoBFQMQAhEBQwERAWYB9AHyBAcB7AG8AvACvAFJAfMB9AHxAXIDAAJv + AiABRgEOAyABAQH/AgAB8gHzAv8CiwG0AgkBtAGLAa4D/wHwAQAB9wEQAUMCSgFEAREDEAMRARUB9AHy + BLwBkgHwAvEB8AG8AUkB7wHwAewB7wQAAW8BTAUgAQEB/wMAAfIB8wH/AQcBhgGtAbQBCQG6AbMBrQGG + AQcC/wHwAQAB9wIUAkoBFAERARABDwQOARUB9AHyAfQBBwEIAf8BBwH/AfIB/wHzAfEB8AFJAQ0B7QH/ + BQABbwFMAyABHwH/BAAB8gHzAf8BtQGGArQCswGtAosBrgL/AfEBAAHvAusBbQHqARIBFAEVAREBEAIP + ARABFQH0AfIC8wEHAfQBBwH/AbwB/wHzAfED/wHyAf8EAAH/AR8DRgFvAUYBHwQAAfIB8wH/AbUBhgG7 + AQkBtAGtAosBzwGuAv8B8QEAAQcBkwF0AXkCegJTAkwDKwFLAfQB8gHzAQcBvAH0AQcB/wHwAf8B8wHy + A/8B8wQAAf8BHwNGAXQCRgFvAR8DAAHyAfMB/wK1AgkBtAKLAYYBiwG1Av8B8QEAAQcBlAGaAqABegF1 + AlMETQFvAfQB8gG8AwcB9wG8BPAB8wH0Af8B8wMAAf8BHwNvAQEBbgF0Am8BFgEfAgAB8gHzAf8B8wG1 + AQcBCQG0Ac8CiwGuAfQC/wHxAQABBwKUA5oDdQLjAhcBbwH0BfMBBwP0AfMB8gP/AfMDAAEaAUwCFgEf + Af8BAAFvAxYBHwIAAfIB8wL/AfABtQEJAa4BtAGuAc8BvAP/AfEBAAEHBrcDlAOxAY4B9ALzAggB8wG8 + A/QB8wHyA/8B8wQAARoBTAEfAf8DAAFvARYBHwMAAvID8wG8ArUBrgG1AbwE8wHxAQABBwHPDLUB9ALz + AfIBBwHzAfAE8wHyA/QB8wUAARoB/wUAAZMEAAHyCfAC7wO1AfABAAG7A60DswK0BdUB9ALzAvAB8wHw + BfMD9AHzEQAB9Am8AQcBvAMHAfIBAAHyBQkE3QQZAv8G8gfzAf8xAAFCAU0BPgcAAT4DAAEoAwABQAMA + AUADAAEBAQABAQYAAQIWAAP/AQAB4QGDBgAB4AEDBgAB4AEDBgAB4AEDBgAB4AEDBgAB4AEDBgABgAEB + BgABgBcAAYAHAAH4AQ8GAAH4AR8GAAH8AT8GAAH+AT8GAAL/BgABgAEAAf4BAwL/AYABAAGAAQAB/wGP + AcABAwHgAT8CAAHgAQ8BgAEBAQABOwIAAeABDwGAAQEBBwHxAgAB8AEPAYABAQEHAfACAAH4AY8BgAEB + AQcB8AIAAfgBjwGAAQEBBwHwAgAB+AGPAYABAQGHAfACAAHwAY4BgAEBAYcB8AIAAfABjgGAAQEBjwH4 + AYABAAHwAYgBgAEBAY8B+AGAAQAB8AEAAYABAQHPAfsBgAEAATABAAGAAQEC4wGAAQABGAHPAYABAQHg + AQMBgAIAAQ8BwAEDAfABBwL/AQABDwL/Af4BPwIAAeABAwEHAfAC/wHgAQ8BgAEBAQMB4AHzAf8BwAEH + AYABAAEBAcAB8AH/AYABAwGAAQACgAHwAX8BgAEDAYABAAGAAQEB8AEfAQABAQGAAQAB4AEDAfABDwEA + AQEBgAEAAfABBwHwAQcCAAGAAQAB+AEPAfABAwIAAYABAAH4AQMB8AEDAQABAQGAAQAB8AEAAfABDwGA + AQEBgAEAAeABAAHwAQ8BgAEDAYABAAHDAYAB8AE/AcABAAGAAQABAwGAAfABfwHgAQABgAEBAQ8BgQHw + Af8B+AEyAYABAQEPAYEB8wL/AfkD/wHjA/8BwAT/BAAC/wIAAv8CAAHzAccCAAGAAwAB4QGDAgABgAMA + AcABAwIAAYADAAHgAQMCAAGAAwAB8AEHAgABgAMAAfgBDwIAAYADAAHwAQ8CAAGAAgABAQHgAQcCAAGA + AgABAQHAAQMCAAGAAgABAQHAAYMCAAGAAgABAQHhAccCAAGAAgABAQHzAe8CAAGAAgABAQL/AgABgAIA + AQEG/ws= + + + + QO-100 Multimedia High Speed Modem for Linux and Windows + +(c) by DJ0ABR, Kurt Moraw, Germany https://dj0abr.de/ +for Amsat-DL: https://amsat-dl.org/ +Open Source: https://github.com/dj0abr/SSB_HighSpeed_Modem + +3rd Party, Credits and Licensing: + +BASS audio library: +www.un4seen.com: BASS is free for non-commercial use + +DSP Library liquid-DSP: +https://liquidsdr.org/ +MIT License + +OPUS Codec: +https://opus-codec.org/ +BSD-licensed + +FFTW: http://www.fftw.org/ +GNU General Public License + +FreeDV: https://github.com/drowe67/codec2 +GNU Lesser General Public License v2.1 + +Image from ICON Archive: https://www.iconarchive.com/ +Artist: Oxygen Team +Iconset: Oxygen Icons (883 icons) +License: GNU Lesser General Public License + +Artist: Sallee Design (Available for custom work) +Iconset: Music Icons (29 icons) +License: CC Attribution 4.0 + +Testing & Manual: +DD1US: https://www.dd1us.de/ + +VIP user: DP0GVN: https://www.awi.de/expedition/stationen/neumayer-station-iii.html + + 482, 17 diff --git a/oscardata/oscardata/Form2_showtext.Designer.cs b/oscardata/oscardata/Form2_showtext.Designer.cs new file mode 100755 index 0000000..f12a7ba --- /dev/null +++ b/oscardata/oscardata/Form2_showtext.Designer.cs @@ -0,0 +1,75 @@ +namespace oscardata +{ + partial class Form2_showtext + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rtb = new System.Windows.Forms.RichTextBox(); + this.bt_OK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // rtb + // + this.rtb.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtb.Location = new System.Drawing.Point(13, 13); + this.rtb.Name = "rtb"; + this.rtb.Size = new System.Drawing.Size(310, 315); + this.rtb.TabIndex = 0; + this.rtb.Text = ""; + // + // bt_OK + // + this.bt_OK.Location = new System.Drawing.Point(247, 335); + this.bt_OK.Name = "bt_OK"; + this.bt_OK.Size = new System.Drawing.Size(75, 23); + this.bt_OK.TabIndex = 1; + this.bt_OK.Text = "OK"; + this.bt_OK.UseVisualStyleBackColor = true; + this.bt_OK.Click += new System.EventHandler(this.bt_OK_Click); + // + // Form2_showtext + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(335, 367); + this.Controls.Add(this.bt_OK); + this.Controls.Add(this.rtb); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Form2_showtext"; + this.ShowIcon = false; + this.Text = "Form2_showtext"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.RichTextBox rtb; + private System.Windows.Forms.Button bt_OK; + } +} \ No newline at end of file diff --git a/oscardata/oscardata/Form2_showtext.cs b/oscardata/oscardata/Form2_showtext.cs new file mode 100755 index 0000000..79f0940 --- /dev/null +++ b/oscardata/oscardata/Form2_showtext.cs @@ -0,0 +1,65 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace oscardata +{ + public partial class Form2_showtext : Form + { + public Form2_showtext(String title,String s) + { + InitializeComponent(); + this.Text = title; + PrintText(rtb,s); + } + + void PrintText(RichTextBox rtb, String s) + { + AppendTextOnce(rtb, new Font("Courier New", (float)8), Color.Blue, Color.White, s); + } + + void AppendTextOnce(RichTextBox rtb, Font selfont, Color color, Color bcolor, string text) + { + try + { + if (text.Contains("\n")) + { + char[] ca = new char[] { '\n', '\r' }; + + text = text.Trim(ca); + text += "\n"; + } + + // max. xxx Zeilen, wenn mehr dann lösche älteste + if (rtb.Lines.Length > 200) + { + rtb.SelectionStart = 0; + rtb.SelectionLength = rtb.Text.IndexOf("\n", 0) + 1; + rtb.SelectedText = ""; + } + + int start = rtb.TextLength; + rtb.AppendText(text); + int end = rtb.TextLength; + + // Textbox may transform chars, so (end-start) != text.Length + rtb.Select(start, end - start); + rtb.SelectionColor = color; + rtb.SelectionFont = selfont; + rtb.SelectionBackColor = bcolor; + rtb.Select(end, 0); + + rtb.ScrollToCaret(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void bt_OK_Click(object sender, EventArgs e) + { + this.Close(); + } + } +} diff --git a/oscardata/oscardata/Form2_showtext.resx b/oscardata/oscardata/Form2_showtext.resx new file mode 100755 index 0000000..29dcb1b --- /dev/null +++ b/oscardata/oscardata/Form2_showtext.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/oscardata/oscardata/Properties/Resources.Designer.cs b/oscardata/oscardata/Properties/Resources.Designer.cs index 0dc25c9..0ec796f 100755 --- a/oscardata/oscardata/Properties/Resources.Designer.cs +++ b/oscardata/oscardata/Properties/Resources.Designer.cs @@ -63,9 +63,9 @@ namespace oscardata.Properties { /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap constelBG { + internal static System.Drawing.Bitmap binary { get { - object obj = ResourceManager.GetObject("constelBG", resourceCulture); + object obj = ResourceManager.GetObject("binary", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -73,9 +73,159 @@ namespace oscardata.Properties { /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap defaultpic { + internal static System.Drawing.Bitmap cancel { get { - object obj = ResourceManager.GetObject("defaultpic", resourceCulture); + object obj = ResourceManager.GetObject("cancel", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_codecloop { + get { + object obj = ResourceManager.GetObject("cdc_codecloop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_dig { + get { + object obj = ResourceManager.GetObject("cdc_dig", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_digital { + get { + object obj = ResourceManager.GetObject("cdc_digital", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_dv { + get { + object obj = ResourceManager.GetObject("cdc_dv", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_dvrx { + get { + object obj = ResourceManager.GetObject("cdc_dvrx", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cdc_intloop { + get { + object obj = ResourceManager.GetObject("cdc_intloop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap fail { + get { + object obj = ResourceManager.GetObject("fail", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap html { + get { + object obj = ResourceManager.GetObject("html", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap image { + get { + object obj = ResourceManager.GetObject("image", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap image1 { + get { + object obj = ResourceManager.GetObject("image1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap image3 { + get { + object obj = ResourceManager.GetObject("image3", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap meter { + get { + object obj = ResourceManager.GetObject("meter", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap meter_big { + get { + object obj = ResourceManager.GetObject("meter_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ok { + get { + object obj = ResourceManager.GetObject("ok", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap openfolder { + get { + object obj = ResourceManager.GetObject("openfolder", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -89,5 +239,105 @@ namespace oscardata.Properties { return ((System.Drawing.Bitmap)(obj)); } } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Satellite_icon1 { + get { + object obj = ResourceManager.GetObject("Satellite_icon1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap setup { + get { + object obj = ResourceManager.GetObject("setup", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap setup_big { + get { + object obj = ResourceManager.GetObject("setup_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap start { + get { + object obj = ResourceManager.GetObject("start", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap stop { + get { + object obj = ResourceManager.GetObject("stop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text { + get { + object obj = ResourceManager.GetObject("text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text_big { + get { + object obj = ResourceManager.GetObject("text_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap transmit { + get { + object obj = ResourceManager.GetObject("transmit", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap voice { + get { + object obj = ResourceManager.GetObject("voice", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap voice_big { + get { + object obj = ResourceManager.GetObject("voice_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/oscardata/oscardata/Properties/Resources.resx b/oscardata/oscardata/Properties/Resources.resx index fb8a259..4ea7cf5 100755 --- a/oscardata/oscardata/Properties/Resources.resx +++ b/oscardata/oscardata/Properties/Resources.resx @@ -118,13 +118,88 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - defaultpic.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - Satellite-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - constelBG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + image.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + image1.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + binary.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cancel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + html.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + image.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + meter.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + meter_big.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + openfolder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Satellite-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + setup.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + setup_big.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + start.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + text.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + text_big.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + transmit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + voice.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + voice_big.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + fail.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ok.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_codecloop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_dig.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_digital.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_dv.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_dvrx.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + cdc_intloop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/oscardata/oscardata/Properties/about.png b/oscardata/oscardata/Properties/about.png new file mode 100644 index 0000000..7f16618 Binary files /dev/null and b/oscardata/oscardata/Properties/about.png differ diff --git a/oscardata/oscardata/Properties/binary.png b/oscardata/oscardata/Properties/binary.png new file mode 100644 index 0000000..7737519 Binary files /dev/null and b/oscardata/oscardata/Properties/binary.png differ diff --git a/oscardata/oscardata/Properties/cancel.png b/oscardata/oscardata/Properties/cancel.png new file mode 100644 index 0000000..b50e6bd Binary files /dev/null and b/oscardata/oscardata/Properties/cancel.png differ diff --git a/oscardata/oscardata/Properties/cdc_codecloop.png b/oscardata/oscardata/Properties/cdc_codecloop.png new file mode 100644 index 0000000..385b25e Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_codecloop.png differ diff --git a/oscardata/oscardata/Properties/cdc_dig.png b/oscardata/oscardata/Properties/cdc_dig.png new file mode 100644 index 0000000..876470c Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_dig.png differ diff --git a/oscardata/oscardata/Properties/cdc_digital.png b/oscardata/oscardata/Properties/cdc_digital.png new file mode 100644 index 0000000..eaac3c8 Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_digital.png differ diff --git a/oscardata/oscardata/Properties/cdc_dv.png b/oscardata/oscardata/Properties/cdc_dv.png new file mode 100644 index 0000000..9e1a3e0 Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_dv.png differ diff --git a/oscardata/oscardata/Properties/cdc_dvrx.png b/oscardata/oscardata/Properties/cdc_dvrx.png new file mode 100644 index 0000000..c051157 Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_dvrx.png differ diff --git a/oscardata/oscardata/Properties/cdc_intloop.png b/oscardata/oscardata/Properties/cdc_intloop.png new file mode 100644 index 0000000..63e3ed9 Binary files /dev/null and b/oscardata/oscardata/Properties/cdc_intloop.png differ diff --git a/oscardata/oscardata/Properties/documentation.pdf b/oscardata/oscardata/Properties/documentation.pdf new file mode 100644 index 0000000..d4108b1 Binary files /dev/null and b/oscardata/oscardata/Properties/documentation.pdf differ diff --git a/oscardata/oscardata/Properties/draft-spittka-payload-rtp-opus-03.pdf b/oscardata/oscardata/Properties/draft-spittka-payload-rtp-opus-03.pdf new file mode 100644 index 0000000..e6f5fdc Binary files /dev/null and b/oscardata/oscardata/Properties/draft-spittka-payload-rtp-opus-03.pdf differ diff --git a/oscardata/oscardata/Properties/fail.png b/oscardata/oscardata/Properties/fail.png new file mode 100644 index 0000000..016c1b9 Binary files /dev/null and b/oscardata/oscardata/Properties/fail.png differ diff --git a/oscardata/oscardata/Properties/html.png b/oscardata/oscardata/Properties/html.png new file mode 100644 index 0000000..e51a3cb Binary files /dev/null and b/oscardata/oscardata/Properties/html.png differ diff --git a/oscardata/oscardata/Properties/image.jpg b/oscardata/oscardata/Properties/image.jpg new file mode 100644 index 0000000..7f3105f Binary files /dev/null and b/oscardata/oscardata/Properties/image.jpg differ diff --git a/oscardata/oscardata/Properties/image.png b/oscardata/oscardata/Properties/image.png new file mode 100644 index 0000000..15c826f Binary files /dev/null and b/oscardata/oscardata/Properties/image.png differ diff --git a/oscardata/oscardata/Properties/image1.jpg b/oscardata/oscardata/Properties/image1.jpg new file mode 100644 index 0000000..1119ea7 Binary files /dev/null and b/oscardata/oscardata/Properties/image1.jpg differ diff --git a/oscardata/oscardata/Properties/meter.png b/oscardata/oscardata/Properties/meter.png new file mode 100644 index 0000000..4aab3a2 Binary files /dev/null and b/oscardata/oscardata/Properties/meter.png differ diff --git a/oscardata/oscardata/Properties/meter_big.png b/oscardata/oscardata/Properties/meter_big.png new file mode 100644 index 0000000..3b6c207 Binary files /dev/null and b/oscardata/oscardata/Properties/meter_big.png differ diff --git a/oscardata/oscardata/Properties/ok.png b/oscardata/oscardata/Properties/ok.png new file mode 100644 index 0000000..f36515c Binary files /dev/null and b/oscardata/oscardata/Properties/ok.png differ diff --git a/oscardata/oscardata/Properties/openfolder.png b/oscardata/oscardata/Properties/openfolder.png new file mode 100644 index 0000000..5fc7522 Binary files /dev/null and b/oscardata/oscardata/Properties/openfolder.png differ diff --git a/oscardata/oscardata/Properties/setup.png b/oscardata/oscardata/Properties/setup.png new file mode 100644 index 0000000..7307500 Binary files /dev/null and b/oscardata/oscardata/Properties/setup.png differ diff --git a/oscardata/oscardata/Properties/setup_big.png b/oscardata/oscardata/Properties/setup_big.png new file mode 100644 index 0000000..35336ea Binary files /dev/null and b/oscardata/oscardata/Properties/setup_big.png differ diff --git a/oscardata/oscardata/Properties/start.png b/oscardata/oscardata/Properties/start.png new file mode 100644 index 0000000..e18a430 Binary files /dev/null and b/oscardata/oscardata/Properties/start.png differ diff --git a/oscardata/oscardata/Properties/stop.png b/oscardata/oscardata/Properties/stop.png new file mode 100644 index 0000000..88e5298 Binary files /dev/null and b/oscardata/oscardata/Properties/stop.png differ diff --git a/oscardata/oscardata/Properties/text.png b/oscardata/oscardata/Properties/text.png new file mode 100644 index 0000000..62c3bc8 Binary files /dev/null and b/oscardata/oscardata/Properties/text.png differ diff --git a/oscardata/oscardata/Properties/text_big.png b/oscardata/oscardata/Properties/text_big.png new file mode 100644 index 0000000..68236da Binary files /dev/null and b/oscardata/oscardata/Properties/text_big.png differ diff --git a/oscardata/oscardata/Properties/textrx.png b/oscardata/oscardata/Properties/textrx.png new file mode 100644 index 0000000..1dc3418 Binary files /dev/null and b/oscardata/oscardata/Properties/textrx.png differ diff --git a/oscardata/oscardata/Properties/texttx.png b/oscardata/oscardata/Properties/texttx.png new file mode 100644 index 0000000..2cc6510 Binary files /dev/null and b/oscardata/oscardata/Properties/texttx.png differ diff --git a/oscardata/oscardata/Properties/transmit.png b/oscardata/oscardata/Properties/transmit.png new file mode 100644 index 0000000..98e9a0d Binary files /dev/null and b/oscardata/oscardata/Properties/transmit.png differ diff --git a/oscardata/oscardata/Properties/voice.png b/oscardata/oscardata/Properties/voice.png new file mode 100644 index 0000000..6593fe8 Binary files /dev/null and b/oscardata/oscardata/Properties/voice.png differ diff --git a/oscardata/oscardata/Properties/voice_big.png b/oscardata/oscardata/Properties/voice_big.png new file mode 100644 index 0000000..11a269a Binary files /dev/null and b/oscardata/oscardata/Properties/voice_big.png differ diff --git a/oscardata/oscardata/bin/Debug/oscardata.exe b/oscardata/oscardata/bin/Debug/oscardata.exe new file mode 100755 index 0000000..dfcc06a Binary files /dev/null and b/oscardata/oscardata/bin/Debug/oscardata.exe differ diff --git a/oscardata/oscardata/bin/Debug/oscardata.exe.config b/oscardata/oscardata/bin/Debug/oscardata.exe.config new file mode 100755 index 0000000..e743be0 --- /dev/null +++ b/oscardata/oscardata/bin/Debug/oscardata.exe.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/oscardata/oscardata/bin/Debug/oscardata.pdb b/oscardata/oscardata/bin/Debug/oscardata.pdb new file mode 100755 index 0000000..139a961 Binary files /dev/null and b/oscardata/oscardata/bin/Debug/oscardata.pdb differ diff --git a/oscardata/oscardata/bin/Release/mono_crash.90c3a3c6e.0.json b/oscardata/oscardata/bin/Release/mono_crash.90c3a3c6e.0.json new file mode 100644 index 0000000..fef7273 --- /dev/null +++ b/oscardata/oscardata/bin/Release/mono_crash.90c3a3c6e.0.json @@ -0,0 +1,1373 @@ +{ + "protocol_version" : "0.0.6", + "configuration" : { + "version" : "(6.12.0.90) (tarball)", + "tlc" : "__thread", + "sigsgev" : "altstack", + "notifications" : "epoll", + "architecture" : "amd64", + "disabled_features" : "none", + "smallconfig" : "disabled", + "bigarrays" : "disabled", + "softdebug" : "enabled", + "interpreter" : "enabled", + "llvm_support" : "610", + "suspend" : "hybrid" + }, + "memory" : { + "minor_gc_time" : "152623", + "major_gc_time" : "48634", + "minor_gc_count" : "12", + "major_gc_count" : "1", + "major_gc_time_concurrent" : "2267846" + }, + "threads" : [ + { + "is_managed" : true, + "offset_free_hash" : "0x90c3a3c6e", + "offset_rich_hash" : "0x90c3a3f7b", + "crashed" : true, + "native_thread_id" : "0x7f28f97a1f40", + "thread_info_addr" : "0x565437597310", + "thread_name" : "mono", + "ctx" : { + "IP" : "0x7f28f8079fb7", + "SP" : "0x7ffd618fef60", + "BP" : "0x4" + }, + "managed_frames" : [ + { + "is_managed" : "false", + "native_address" : "unregistered" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6004cc2", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6004ce1", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600600e", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00149" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600600d", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00085" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6006010", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0005d" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6006011", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001854", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00014" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x60015be", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00038" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x60015bd", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600059f", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0006c" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0002a" + } + + ], + "unmanaged_frames" : [ + { + "is_managed" : "false", + "native_address" : "0x565434fd7459", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351bd0f9", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351be435", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351c75fc", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543502d397", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543502d5a9", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x565434fd97c4", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543502c7c2", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7f28f8d7d980", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7f28f8079fb7", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7f28f807b921", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543528a707", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543526d7b3", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543528a688", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543528ac43", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543528ac7a", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543517c988", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351689cf", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351d9bab", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x5654351da814", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x56543514f866", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } + + ] +}, +{ + "is_managed" : true, + "offset_free_hash" : "0x6fda1dd66", + "offset_rich_hash" : "0x6fda1ded4", + "crashed" : false, + "native_thread_id" : "0x7f28e6509700", + "thread_info_addr" : "0x7f28d8000b20", + "thread_name" : "Thread: oscarda", + "ctx" : { + "IP" : "0x565435286fbb", + "SP" : "0x7f28e65086f0", + "BP" : "0xb0" + }, + "managed_frames" : [ + { + "is_managed" : "false", + "native_address" : "unregistered" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001f43", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00019" + } +, + { + "is_managed" : "true", + "guid" : "0C087C48-BFBD-48D2-BAE3-FFCD7B6D8C0C", + "token" : "0x600005f", + "native_offset" : "0x0", + "filename" : "et_Size", + "sizeofimage" : "0x1a000", + "timestamp" : "0x5fafb112", + "il_offset" : "0x00073" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001f1c", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00014" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec4", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00071" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec2", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec1", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0002b" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001f1e", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00008" + } +, + { + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0002a" + } + + ], +"unmanaged_frames" : [ +{ + "is_managed" : "false", + "native_address" : "0x565434fd7459", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351bd0f9", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351be435", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c7497", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543502c685", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7d980", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x565435286fbb", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654352803dc", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654352804f3", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543527d6fa", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c45a0", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543515b38b", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } + +] +}, +{ +"is_managed" : false, +"offset_free_hash" : "0x0", +"offset_rich_hash" : "0x0", +"crashed" : false, +"native_thread_id" : "0x7f28e57ec700", +"thread_info_addr" : "0x7f28c8000b20", +"thread_name" : "Thread Pool Wor", +"ctx" : { + "IP" : "0x7f28f8d7b9b2", + "SP" : "0x7f28e57ebc60", + "BP" : "0x5654355ecd48" +}, +"unmanaged_frames" : [ +{ + "is_managed" : "false", + "native_address" : "0x565434fd7459", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351bd0f9", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351be435", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c7497", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543502c685", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7d980", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7b9b2", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7bac3", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543521858d", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c6dac", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d726db", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f815c71f", + "native_offset" : "0x00000" + } + +] +}, +{ +"is_managed" : false, +"offset_free_hash" : "0x0", +"offset_rich_hash" : "0x0", +"crashed" : false, +"native_thread_id" : "0x7f28e5bee700", +"thread_info_addr" : "0x7f28d0000b20", +"thread_name" : "Timer-Scheduler", +"ctx" : { + "IP" : "0x7f28f8d78fb9", + "SP" : "0x7f28e5bedb60", + "BP" : "(nil)" +}, +"unmanaged_frames" : [ +{ + "is_managed" : "false", + "native_address" : "0x565434fd7459", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351bd0f9", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351be435", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c7497", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543502c685", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7d980", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d78fb9", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x565435272c6b", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543527d718", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x565435219312", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c6dac", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d726db", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f815c71f", + "native_offset" : "0x00000" + } + +] +}, +{ +"is_managed" : false, +"offset_free_hash" : "0x0", +"offset_rich_hash" : "0x0", +"crashed" : false, +"native_thread_id" : "0x7f28f5b93700", +"thread_info_addr" : "0x7f28f0000b20", +"thread_name" : "Finalizer", +"ctx" : { + "IP" : "0x7f28f8d7b7c6", + "SP" : "0x7f28f5b92d00", + "BP" : "0x5654355ec460" +}, +"unmanaged_frames" : [ +{ + "is_managed" : "false", + "native_address" : "0x565434fd7459", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351bd0f9", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351be435", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c7497", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x56543502c685", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7d980", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7b7c6", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d7b8b8", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x565435208638", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x5654351c6dac", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f8d726db", + "native_offset" : "0x00000" + } +, +{ + "is_managed" : "false", + "native_address" : "0x7f28f815c71f", + "native_offset" : "0x00000" + } + +] +}, +{ +"is_managed" : true, +"offset_free_hash" : "0x9bfc75a38", +"offset_rich_hash" : "0x9bfc75bc7", +"crashed" : false, +"native_thread_id" : "0x7f28e5def700", +"thread_info_addr" : "0x7f28dc000b20", +"thread_name" : "Timer-Scheduler", +"ctx" : { + "IP" : "0x7f28f8d78fb9", + "SP" : "0x7f28e5dedef0", + "BP" : "(nil)" +}, +"managed_frames" : [ +{ + "is_managed" : "false", + "native_address" : "unregistered" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6002051", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00044" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600203d", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00014" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600203c", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6002037", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00019" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x600203a", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x60020f6", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0003c" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001f1c", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00014" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec4", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00071" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec2", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00000" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001ec1", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0002b" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x6001f1e", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x00008" + } +, +{ + "is_managed" : "true", + "guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", + "token" : "0x00000", + "native_offset" : "0x0", + "filename" : "mscorlib.dll", + "sizeofimage" : "0x472000", + "timestamp" : "0xe43f23f1", + "il_offset" : "0x0002a" + } + +], +"unmanaged_frames" : [ +{ +"is_managed" : "false", +"native_address" : "0x565434fd7459", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351bd0f9", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351be435", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351c7497", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543502c685", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7d980", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d78fb9", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x565435272c6b", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351d18bc", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351d2f29", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351d35c0", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351c431d", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543515c013", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x00000", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x00000" +} + +] +}, +{ +"is_managed" : false, +"offset_free_hash" : "0x0", +"offset_rich_hash" : "0x0", +"crashed" : false, +"native_thread_id" : "0x7f28e59ed700", +"thread_info_addr" : "0x7f28d4000b20", +"thread_name" : "Thread Pool Wor", +"ctx" : { +"IP" : "0x7f28f8d7b9b2", +"SP" : "0x7f28e59ecc60", +"BP" : "0x5654355ecd48" +}, +"unmanaged_frames" : [ +{ +"is_managed" : "false", +"native_address" : "0x565434fd7459", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351bd0f9", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351be435", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351c7497", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543502c685", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7d980", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7b9b2", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7bac3", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543521858d", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351c6dac", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d726db", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f815c71f", +"native_offset" : "0x00000" +} + +] +}, +{ +"is_managed" : true, +"offset_free_hash" : "0x91c81a677", +"offset_rich_hash" : "0x91c81a80f", +"crashed" : false, +"native_thread_id" : "0x7f28e670a700", +"thread_info_addr" : "0x7f28e0000b20", +"thread_name" : "Thread: oscarda", +"ctx" : { +"IP" : "0x7f28f8d7c9e2", +"SP" : "0x7f28e6709410", +"BP" : "(nil)" +}, +"managed_frames" : [ +{ +"is_managed" : "false", +"native_address" : "unregistered" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x00000", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00000" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x6002696", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x0000c" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x6002690", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00024" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x600268f", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00026" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x600261e", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00000" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x6002789", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00036" +} +, +{ +"is_managed" : "true", +"guid" : "0C087C48-BFBD-48D2-BAE3-FFCD7B6D8C0C", +"token" : "0x600005d", +"native_offset" : "0x0", +"filename" : "et_Size", +"sizeofimage" : "0x1a000", +"timestamp" : "0x5fafb112", +"il_offset" : "0x0002a" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x6001f1c", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x00014" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x6001ec4", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x00071" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x6001ec2", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x00000" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x6001ec1", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x0002b" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x6001f1e", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x00008" +} +, +{ +"is_managed" : "true", +"guid" : "9F0DF102-FE6E-4CFE-A29D-2E46F585D8A5", +"token" : "0x00000", +"native_offset" : "0x0", +"filename" : "mscorlib.dll", +"sizeofimage" : "0x472000", +"timestamp" : "0xe43f23f1", +"il_offset" : "0x0002a" +} + +], +"unmanaged_frames" : [ +{ +"is_managed" : "false", +"native_address" : "0x565434fd7459", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351bd0f9", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351be435", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351c7497", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543502c685", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7d980", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x7f28f8d7c9e2", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543521593d", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x5654351ad57c", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "false", +"native_address" : "0x56543514cf8b", +"native_offset" : "0x00000" +} +, +{ +"is_managed" : "true", +"guid" : "3D97DDA7-73A5-4430-B892-E1D794E5D921", +"token" : "0x00000", +"native_offset" : "0x0", +"filename" : "System.dll", +"sizeofimage" : "0x286000", +"timestamp" : "0xff5f288c", +"il_offset" : "0x00000" +} + +] +} +] +} \ No newline at end of file diff --git a/oscardata/oscardata/bin/Release/oscardata.exe b/oscardata/oscardata/bin/Release/oscardata.exe index 33a23b4..fa8ab69 100755 Binary files a/oscardata/oscardata/bin/Release/oscardata.exe and b/oscardata/oscardata/bin/Release/oscardata.exe differ diff --git a/oscardata/oscardata/bin/Release/oscardata.exe.config b/oscardata/oscardata/bin/Release/oscardata.exe.config new file mode 100755 index 0000000..e743be0 --- /dev/null +++ b/oscardata/oscardata/bin/Release/oscardata.exe.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/oscardata/oscardata/bin/Release/oscardata.pdb b/oscardata/oscardata/bin/Release/oscardata.pdb new file mode 100755 index 0000000..70c9cb4 Binary files /dev/null and b/oscardata/oscardata/bin/Release/oscardata.pdb differ diff --git a/oscardata/oscardata/config.cs b/oscardata/oscardata/config.cs index 621e4d0..01e5797 100755 --- a/oscardata/oscardata/config.cs +++ b/oscardata/oscardata/config.cs @@ -22,6 +22,8 @@ namespace oscardata public static Byte AsciiFile = 3; public static Byte HTMLFile = 4; public static Byte BinaryFile = 5; + public static Byte Audio = 6; + // the upper values are for internal use public static Byte ResamplingRate = 16; public static Byte AutosendFile = 17; @@ -30,6 +32,10 @@ namespace oscardata public static Byte ResetModem = 20; public static Byte SetPBvolume = 21; public static Byte SetCAPvolume = 22; + public static Byte SetLSvolume = 23; + public static Byte SetMICvolume = 24; + public static Byte SetVoiceMode = 25; + public static Byte terminate = 26; // frame sequence, modem needs that for i.e. sending a preamble public static Byte FirstFrame = 0; @@ -65,6 +71,9 @@ namespace oscardata public static String[] AudioPBdevs; public static String[] AudioCAPdevs; public static int PBfifousage = 0; + public static int CAPfifousage = 0; + public static int initAudioStatus; + public static int initVoiceStatus; public static String[] getOwnIPs() @@ -198,6 +207,38 @@ namespace oscardata return home + filename; } + public static void CreateAllDirs() + { + String home = Application.UserAppDataPath; + String deli = "/"; + + if (statics.ostype == 0) + deli = "\\"; + + // create home directory + try + { + Directory.CreateDirectory(home); + } + catch { } + + // create application path + home += deli + DataStorage; + try + { + Directory.CreateDirectory(home); + } + catch { } + + // create image path + home += deli + RXimageStorage; + try + { + Directory.CreateDirectory(home); + } + catch { } + } + // Returns the file's size. public static long GetFileSize(string file_name) { @@ -305,6 +346,23 @@ namespace oscardata return true; } + // checks if a process is running + static public bool isProcRunning(String s) + { + bool running = false; + + if (ostype == 0) + { + foreach (var process in Process.GetProcessesByName(s)) + { + running = true; + break; + } + } + + return running; + } + static public void killall(String s) { if (ostype == 0) diff --git a/oscardata/oscardata/imagehandler.cs b/oscardata/oscardata/imagehandler.cs index debb729..4d5c251 100755 --- a/oscardata/oscardata/imagehandler.cs +++ b/oscardata/oscardata/imagehandler.cs @@ -107,26 +107,5 @@ namespace oscardata return destImage; } - - // gets a receive payload, reconstruct the image - // type: 2=start, 3=cont - public void receive_image(Byte[] rxdata, int minfo) - { - BinaryWriter writer = null; - - if (minfo == statics.FirstFrame) - { - // image starts, create destination file - writer = new BinaryWriter(File.Open(statics.jpg_tempfilename, FileMode.Create)); - writer.Write(rxdata); - } - else - { - // continue with image - writer = new BinaryWriter(File.Open(statics.jpg_tempfilename, FileMode.Append)); - writer.Write(rxdata); - } - writer.Close(); - } } } diff --git a/oscardata/oscardata/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs b/oscardata/oscardata/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs new file mode 100755 index 0000000..182bcf0 --- /dev/null +++ b/oscardata/oscardata/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] diff --git a/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferences.cache new file mode 100755 index 0000000..c35bce7 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100755 index 0000000..07afeec Binary files /dev/null and b/oscardata/oscardata/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/oscardata/oscardata/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/oscardata/oscardata/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll new file mode 100755 index 0000000..eb720ac Binary files /dev/null and b/oscardata/oscardata/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.Form1.resources b/oscardata/oscardata/obj/Debug/oscardata.Form1.resources new file mode 100755 index 0000000..4611945 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.Form1.resources differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.Form2_showtext.resources b/oscardata/oscardata/obj/Debug/oscardata.Form2_showtext.resources new file mode 100755 index 0000000..6c05a97 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.Form2_showtext.resources differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.Properties.Resources.resources b/oscardata/oscardata/obj/Debug/oscardata.Properties.Resources.resources new file mode 100755 index 0000000..b36fa8e Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.Properties.Resources.resources differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.csproj.CoreCompileInputs.cache b/oscardata/oscardata/obj/Debug/oscardata.csproj.CoreCompileInputs.cache new file mode 100755 index 0000000..c555a3a --- /dev/null +++ b/oscardata/oscardata/obj/Debug/oscardata.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +9e2591805e48c9de90be794d8c80dc9ff27fb5a3 diff --git a/oscardata/oscardata/obj/Debug/oscardata.csproj.FileListAbsolute.txt b/oscardata/oscardata/obj/Debug/oscardata.csproj.FileListAbsolute.txt new file mode 100755 index 0000000..43af421 --- /dev/null +++ b/oscardata/oscardata/obj/Debug/oscardata.csproj.FileListAbsolute.txt @@ -0,0 +1,11 @@ +E:\funk\hsmodem\oscardata\oscardata\bin\Debug\oscardata.exe.config +E:\funk\hsmodem\oscardata\oscardata\bin\Debug\oscardata.exe +E:\funk\hsmodem\oscardata\oscardata\bin\Debug\oscardata.pdb +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.Form1.resources +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.Properties.Resources.resources +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.csproj.GenerateResource.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.csproj.CoreCompileInputs.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.exe +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.pdb +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.csprojAssemblyReference.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Debug\oscardata.Form2_showtext.resources diff --git a/oscardata/oscardata/obj/Debug/oscardata.csproj.GenerateResource.cache b/oscardata/oscardata/obj/Debug/oscardata.csproj.GenerateResource.cache new file mode 100755 index 0000000..a36bf33 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.csproj.GenerateResource.cache differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.csprojAssemblyReference.cache b/oscardata/oscardata/obj/Debug/oscardata.csprojAssemblyReference.cache new file mode 100755 index 0000000..97b52a8 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.csprojAssemblyReference.cache differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.exe b/oscardata/oscardata/obj/Debug/oscardata.exe new file mode 100755 index 0000000..dfcc06a Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.exe differ diff --git a/oscardata/oscardata/obj/Debug/oscardata.pdb b/oscardata/oscardata/obj/Debug/oscardata.pdb new file mode 100755 index 0000000..139a961 Binary files /dev/null and b/oscardata/oscardata/obj/Debug/oscardata.pdb differ diff --git a/oscardata/oscardata/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs b/oscardata/oscardata/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs new file mode 100755 index 0000000..182bcf0 --- /dev/null +++ b/oscardata/oscardata/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] diff --git a/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferences.cache b/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferences.cache new file mode 100755 index 0000000..3141672 Binary files /dev/null and b/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100755 index 0000000..2fd34be Binary files /dev/null and b/oscardata/oscardata/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/oscardata/oscardata/obj/Release/TempPE/Properties.Resources.Designer.cs.dll b/oscardata/oscardata/obj/Release/TempPE/Properties.Resources.Designer.cs.dll new file mode 100755 index 0000000..1eceb17 Binary files /dev/null and b/oscardata/oscardata/obj/Release/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/oscardata/oscardata/obj/Release/oscardata.Form1.resources b/oscardata/oscardata/obj/Release/oscardata.Form1.resources new file mode 100755 index 0000000..4967cbb Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.Form1.resources differ diff --git a/oscardata/oscardata/obj/Release/oscardata.Form2_showtext.resources b/oscardata/oscardata/obj/Release/oscardata.Form2_showtext.resources new file mode 100755 index 0000000..6c05a97 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.Form2_showtext.resources differ diff --git a/oscardata/oscardata/obj/Release/oscardata.Properties.Resources.resources b/oscardata/oscardata/obj/Release/oscardata.Properties.Resources.resources new file mode 100755 index 0000000..4219ad8 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.Properties.Resources.resources differ diff --git a/oscardata/oscardata/obj/Release/oscardata.csproj.CoreCompileInputs.cache b/oscardata/oscardata/obj/Release/oscardata.csproj.CoreCompileInputs.cache new file mode 100755 index 0000000..90ecca0 --- /dev/null +++ b/oscardata/oscardata/obj/Release/oscardata.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +f689faaaeada03b7ced4435f518c6a73110138e7 diff --git a/oscardata/oscardata/obj/Release/oscardata.csproj.FileListAbsolute.txt b/oscardata/oscardata/obj/Release/oscardata.csproj.FileListAbsolute.txt new file mode 100755 index 0000000..20ba6df --- /dev/null +++ b/oscardata/oscardata/obj/Release/oscardata.csproj.FileListAbsolute.txt @@ -0,0 +1,11 @@ +E:\funk\hsmodem\oscardata\oscardata\bin\Release\oscardata.exe.config +E:\funk\hsmodem\oscardata\oscardata\bin\Release\oscardata.exe +E:\funk\hsmodem\oscardata\oscardata\bin\Release\oscardata.pdb +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.Form1.resources +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.Properties.Resources.resources +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.csproj.GenerateResource.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.csproj.CoreCompileInputs.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.exe +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.pdb +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.csprojAssemblyReference.cache +E:\funk\hsmodem\oscardata\oscardata\obj\Release\oscardata.Form2_showtext.resources diff --git a/oscardata/oscardata/obj/Release/oscardata.csproj.GenerateResource.cache b/oscardata/oscardata/obj/Release/oscardata.csproj.GenerateResource.cache new file mode 100755 index 0000000..5b1e288 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.csproj.GenerateResource.cache differ diff --git a/oscardata/oscardata/obj/Release/oscardata.csprojAssemblyReference.cache b/oscardata/oscardata/obj/Release/oscardata.csprojAssemblyReference.cache new file mode 100755 index 0000000..13a2654 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.csprojAssemblyReference.cache differ diff --git a/oscardata/oscardata/obj/Release/oscardata.exe b/oscardata/oscardata/obj/Release/oscardata.exe new file mode 100755 index 0000000..fa8ab69 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.exe differ diff --git a/oscardata/oscardata/obj/Release/oscardata.pdb b/oscardata/oscardata/obj/Release/oscardata.pdb new file mode 100755 index 0000000..70c9cb4 Binary files /dev/null and b/oscardata/oscardata/obj/Release/oscardata.pdb differ diff --git a/oscardata/oscardata/oscardata.csproj b/oscardata/oscardata/oscardata.csproj index 189713b..07e15ba 100755 --- a/oscardata/oscardata/oscardata.csproj +++ b/oscardata/oscardata/oscardata.csproj @@ -64,6 +64,12 @@ Form1.cs + + Form + + + Form2_showtext.cs + @@ -73,6 +79,9 @@ Form1.cs + + Form2_showtext.cs + ResXFileCodeGenerator Resources.Designer.cs @@ -96,16 +105,45 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oscardata/oscardata/receivefile.cs b/oscardata/oscardata/receivefile.cs index 565685a..561f268 100755 --- a/oscardata/oscardata/receivefile.cs +++ b/oscardata/oscardata/receivefile.cs @@ -67,6 +67,9 @@ namespace oscardata int blockidx; Byte[] firstblock; + bool[] lastblockvalid = new bool[1024]; + int lastblockidx; + bool receiving = false; public String filename = null; public String StatusText = ""; @@ -97,26 +100,6 @@ namespace oscardata filesize = 0; filename = ""; if (!StartFileRX()) return false; // invalid file - - // check if file already exists - if (fileExists()) - { - // exists already, no need to receive - filename = makeRXfilename(); - - if (rxtype == statics.Image) - { - try - { - // show existing image - Image img = Image.FromFile(filename); - pbmp = new Bitmap(img); - } - catch { pbmp = null; } - } - receiving = false; - return true; - } } if (minfo != statics.FirstFrame) @@ -281,9 +264,21 @@ namespace oscardata result[0] = blockidx+1; // +1 because we start with block 0 result[1] = ok; + Array.Copy(blockvalid, lastblockvalid, blockvalid.Length); + lastblockidx = blockidx; + return true; } + public void oldblockinfo(int[] result) + { + int ok = 0; + for (int i = 0; i <= lastblockidx; i++) + if (lastblockvalid[i]) ok++; + result[0] = lastblockidx + 1; // +1 because we start with block 0 + result[1] = ok; + } + void saveBlocks() { try @@ -390,20 +385,6 @@ namespace oscardata return fn; } - bool fileExists() - { - String fn = makeRXfilename(); - if (!File.Exists(fn)) return false; - - // File exists, but is the ID the same ? - Byte[] ba = File.ReadAllBytes(fn); - if (ba == null) return false; - Crc c = new Crc(); - int fncrc = c.crc16_messagecalc(ba, ba.Length); - if (ArraySend.FileID != fncrc) return false; - return true; - } - bool SaveFile() { Console.WriteLine("save file"); @@ -492,42 +473,49 @@ namespace oscardata return; } - // filename has the received data, but maybe too long (multiple of payload length) - // reduce for the real file length - Byte[] fc = File.ReadAllBytes(filename); - Byte[] fdst = new byte[ArraySend.FileSize]; - if (fc.Length < ArraySend.FileSize) + try { - Console.WriteLine("file not complete: got len=" + fc.Length + " expected len=" + ArraySend.FileSize); - return; - } - Array.Copy(fc, 0, fdst, 0, ArraySend.FileSize); - File.WriteAllBytes(statics.zip_RXtempfilename, fdst); // the received file (still zipped) is here + // filename has the received data, but maybe too long (multiple of payload length) + // reduce for the real file length + Byte[] fc = File.ReadAllBytes(filename); + Byte[] fdst = new byte[ArraySend.FileSize]; + if (fc.Length < ArraySend.FileSize) + { + Console.WriteLine("file not complete: got len=" + fc.Length + " expected len=" + ArraySend.FileSize); + return; + } + Array.Copy(fc, 0, fdst, 0, ArraySend.FileSize); + File.WriteAllBytes(statics.zip_RXtempfilename, fdst); // the received file (still zipped) is here - // unzip received data and store result in file: unzipped_RXtempfilename - ZipStorer zs = new ZipStorer(); - String fl = zs.unzipFile(statics.zip_RXtempfilename); - if (fl != null) - { - // save file - // fl is the filename of the file inside the zip file, so the originally zipped file - // remove path to get just the filename - int idx = fl.LastIndexOf('/'); - if (idx == -1) idx = fl.LastIndexOf('\\'); - String fdest = fl.Substring(idx + 1); - fdest = statics.getHomePath("", fdest); - // fdest is the file in the oscardata's user home directoty - // remove old file with same name - try { File.Delete(fdest); } catch { } - // move the unzipped file to the final location - File.Move(fl, fdest); - filesize = statics.GetFileSize(fdest); - StatusText = "unzip OK"; + // unzip received data and store result in file: unzipped_RXtempfilename + ZipStorer zs = new ZipStorer(); + String fl = zs.unzipFile(statics.zip_RXtempfilename); + if (fl != null) + { + // save file + // fl is the filename of the file inside the zip file, so the originally zipped file + // remove path to get just the filename + int idx = fl.LastIndexOf('/'); + if (idx == -1) idx = fl.LastIndexOf('\\'); + String fdest = fl.Substring(idx + 1); + fdest = statics.getHomePath("", fdest); + // fdest is the file in the oscardata's user home directoty + // remove old file with same name + try { File.Delete(fdest); } catch { } + // move the unzipped file to the final location + File.Move(fl, fdest); + filesize = statics.GetFileSize(fdest); + StatusText = "unzip OK"; + } + else + StatusText = "unzip failed"; + + File.Delete(statics.zip_RXtempfilename); } - else + catch + { StatusText = "unzip failed"; - - File.Delete(statics.zip_RXtempfilename); + } } } } diff --git a/oscardata/oscardata/udp.cs b/oscardata/oscardata/udp.cs index 653adb5..dcda98c 100755 --- a/oscardata/oscardata/udp.cs +++ b/oscardata/oscardata/udp.cs @@ -33,6 +33,7 @@ namespace oscardata static UdpQueue uq_iq = new UdpQueue(); public static int searchtimeout = 0; + static String last_audiodevstring = ""; // Constructor // called when Udp is created by the main program @@ -96,11 +97,22 @@ namespace oscardata { statics.ModemIP = RemoteEndpoint.Address.ToString(); searchtimeout = 0; - // message b contains audio devices - String s = statics.ByteArrayToString(b); + // message b contains audio devices and init status + statics.initAudioStatus = b[0]; + statics.initVoiceStatus = b[1]; + + String s = statics.ByteArrayToString(b,2); String[] sa1 = s.Split(new char[] { '^' }); statics.AudioPBdevs = sa1[0].Split(new char[] { '~' }); statics.AudioCAPdevs = sa1[1].Split(new char[] { '~' }); + + // has the device list changed ? + if(s != last_audiodevstring) + { + statics.GotAudioDevices = 1; + last_audiodevstring = s; + } + if(statics.GotAudioDevices == 0) statics.GotAudioDevices = 1; } @@ -109,8 +121,9 @@ namespace oscardata if (rxtype == statics.udp_fft) { statics.PBfifousage = b[0]; - Byte[] b1 = new byte[b.Length - 1]; - Array.Copy(b, 1, b1, 0, b1.Length); + statics.CAPfifousage = b[1]; + Byte[] b1 = new byte[b.Length - 2]; + Array.Copy(b, 2, b1, 0, b1.Length); uq_fft.Add(b1); }