mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-09-27 15:56:48 -04:00
Merge ui panel code and refactoring
This commit is contained in:
commit
5033d6f5d8
@ -228,6 +228,8 @@ SET (cubicsdr_sources
|
|||||||
src/AppFrame.cpp
|
src/AppFrame.cpp
|
||||||
src/AppConfig.cpp
|
src/AppConfig.cpp
|
||||||
src/FrequencyDialog.cpp
|
src/FrequencyDialog.cpp
|
||||||
|
src/IOThread.cpp
|
||||||
|
src/sdr/SDRDeviceInfo.cpp
|
||||||
src/sdr/SDRThread.cpp
|
src/sdr/SDRThread.cpp
|
||||||
src/sdr/SDRPostThread.cpp
|
src/sdr/SDRPostThread.cpp
|
||||||
src/demod/DemodulatorPreThread.cpp
|
src/demod/DemodulatorPreThread.cpp
|
||||||
@ -257,12 +259,18 @@ SET (cubicsdr_sources
|
|||||||
src/visual/SpectrumContext.cpp
|
src/visual/SpectrumContext.cpp
|
||||||
src/visual/WaterfallCanvas.cpp
|
src/visual/WaterfallCanvas.cpp
|
||||||
src/visual/WaterfallContext.cpp
|
src/visual/WaterfallContext.cpp
|
||||||
|
src/process/VisualProcessor.cpp
|
||||||
|
src/process/ScopeVisualProcessor.cpp
|
||||||
|
src/process/SpectrumVisualProcessor.cpp
|
||||||
|
src/process/WaterfallVisualProcessor.cpp
|
||||||
|
src/ui/GLPanel.cpp
|
||||||
external/rtaudio/RtAudio.cpp
|
external/rtaudio/RtAudio.cpp
|
||||||
external/lodepng/lodepng.cpp
|
external/lodepng/lodepng.cpp
|
||||||
external/tinyxml/tinyxml.cpp
|
external/tinyxml/tinyxml.cpp
|
||||||
external/tinyxml/tinystr.cpp
|
external/tinyxml/tinystr.cpp
|
||||||
external/tinyxml/tinyxmlparser.cpp
|
external/tinyxml/tinyxmlparser.cpp
|
||||||
external/tinyxml/tinyxmlerror.cpp
|
external/tinyxml/tinyxmlerror.cpp
|
||||||
|
external/cubicvr2/math/cubic_math.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET (cubicsdr_headers
|
SET (cubicsdr_headers
|
||||||
@ -271,6 +279,8 @@ SET (cubicsdr_headers
|
|||||||
src/AppFrame.h
|
src/AppFrame.h
|
||||||
src/AppConfig.h
|
src/AppConfig.h
|
||||||
src/FrequencyDialog.h
|
src/FrequencyDialog.h
|
||||||
|
src/IOThread.h
|
||||||
|
src/sdr/SDRDeviceInfo.h
|
||||||
src/sdr/SDRThread.h
|
src/sdr/SDRThread.h
|
||||||
src/sdr/SDRPostThread.h
|
src/sdr/SDRPostThread.h
|
||||||
src/demod/DemodulatorPreThread.h
|
src/demod/DemodulatorPreThread.h
|
||||||
@ -302,10 +312,33 @@ SET (cubicsdr_headers
|
|||||||
src/visual/SpectrumContext.h
|
src/visual/SpectrumContext.h
|
||||||
src/visual/WaterfallCanvas.h
|
src/visual/WaterfallCanvas.h
|
||||||
src/visual/WaterfallContext.h
|
src/visual/WaterfallContext.h
|
||||||
|
src/process/VisualProcessor.h
|
||||||
|
src/process/ScopeVisualProcessor.h
|
||||||
|
src/process/SpectrumVisualProcessor.h
|
||||||
|
src/process/WaterfallVisualProcessor.h
|
||||||
|
src/ui/GLPanel.h
|
||||||
|
src/ui/UITestCanvas.cpp
|
||||||
|
src/ui/UITestCanvas.h
|
||||||
|
src/ui/UITestContext.cpp
|
||||||
|
src/ui/UITestContext.h
|
||||||
external/rtaudio/RtAudio.h
|
external/rtaudio/RtAudio.h
|
||||||
external/lodepng/lodepng.h
|
external/lodepng/lodepng.h
|
||||||
external/tinyxml/tinyxml.h
|
external/tinyxml/tinyxml.h
|
||||||
external/tinyxml/tinystr.h
|
external/tinyxml/tinystr.h
|
||||||
|
external/cubicvr2/math/aabb.h
|
||||||
|
external/cubicvr2/math/cubic_math.h
|
||||||
|
external/cubicvr2/math/cubic_types.h
|
||||||
|
external/cubicvr2/math/frustum.h
|
||||||
|
external/cubicvr2/math/mat3.h
|
||||||
|
external/cubicvr2/math/mat4.h
|
||||||
|
external/cubicvr2/math/plane.h
|
||||||
|
external/cubicvr2/math/quaternion.h
|
||||||
|
external/cubicvr2/math/sphere.h
|
||||||
|
external/cubicvr2/math/transform.h
|
||||||
|
external/cubicvr2/math/triangle.h
|
||||||
|
external/cubicvr2/math/vec2.h
|
||||||
|
external/cubicvr2/math/vec3.h
|
||||||
|
external/cubicvr2/math/vec4.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories (
|
include_directories (
|
||||||
@ -314,10 +347,13 @@ include_directories (
|
|||||||
${PROJECT_SOURCE_DIR}/src/audio
|
${PROJECT_SOURCE_DIR}/src/audio
|
||||||
${PROJECT_SOURCE_DIR}/src/util
|
${PROJECT_SOURCE_DIR}/src/util
|
||||||
${PROJECT_SOURCE_DIR}/src/visual
|
${PROJECT_SOURCE_DIR}/src/visual
|
||||||
|
${PROJECT_SOURCE_DIR}/src/process
|
||||||
|
${PROJECT_SOURCE_DIR}/src/ui
|
||||||
${PROJECT_SOURCE_DIR}/src
|
${PROJECT_SOURCE_DIR}/src
|
||||||
${PROJECT_SOURCE_DIR}/external/rtaudio
|
${PROJECT_SOURCE_DIR}/external/rtaudio
|
||||||
${PROJECT_SOURCE_DIR}/external/lodepng
|
${PROJECT_SOURCE_DIR}/external/lodepng
|
||||||
${PROJECT_SOURCE_DIR}/external/tinyxml
|
${PROJECT_SOURCE_DIR}/external/tinyxml
|
||||||
|
${PROJECT_SOURCE_DIR}/external/cubicvr2/math
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
|
110
external/cubicvr2/math/aabb.h
vendored
Normal file
110
external/cubicvr2/math/aabb.h
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// aabb.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__aabb__
|
||||||
|
#define __CubicVR2__aabb__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
enum aabb_enum { AABB_DISJOINT, AABB_A_INSIDE_B, AABB_B_INSIDE_A, AABB_INTERSECT };
|
||||||
|
|
||||||
|
struct aabb {
|
||||||
|
vec3 min, max;
|
||||||
|
|
||||||
|
aabb(vec3 min_in, vec3 max_in) {
|
||||||
|
min=min_in;
|
||||||
|
max=max_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
aabb() {
|
||||||
|
min=max=vec3(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
aabb engulf(aabb aabb, vec3 point) {
|
||||||
|
if (aabb.min[0] > point[0]) {
|
||||||
|
aabb.min[0] = point[0];
|
||||||
|
}
|
||||||
|
if (aabb.min[1] > point[1]) {
|
||||||
|
aabb.min[1] = point[1];
|
||||||
|
}
|
||||||
|
if (aabb.min[2] > point[2]) {
|
||||||
|
aabb.min[2] = point[2];
|
||||||
|
}
|
||||||
|
if (aabb.max[0] < point[0]) {
|
||||||
|
aabb.max[0] = point[0];
|
||||||
|
}
|
||||||
|
if (aabb.max[1] < point[1]) {
|
||||||
|
aabb.max[1] = point[1];
|
||||||
|
}
|
||||||
|
if (aabb.max[2] < point[2]) {
|
||||||
|
aabb.max[2] = point[2];
|
||||||
|
}
|
||||||
|
return aabb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static aabb reset(aabb aabb, vec3 point=vec3(0.0f,0.0f,0.0f)) {
|
||||||
|
|
||||||
|
aabb.min[0] = point[0];
|
||||||
|
aabb.min[1] = point[1];
|
||||||
|
aabb.min[2] = point[2];
|
||||||
|
aabb.max[0] = point[0];
|
||||||
|
aabb.max[1] = point[1];
|
||||||
|
aabb.max[2] = point[2];
|
||||||
|
|
||||||
|
return aabb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 size(aabb aabb) {
|
||||||
|
__float x = aabb.min[0] < aabb.max[0] ? aabb.max[0] - aabb.min[0] : aabb.min[0] - aabb.max[0];
|
||||||
|
__float y = aabb.min[1] < aabb.max[1] ? aabb.max[1] - aabb.min[1] : aabb.min[1] - aabb.max[1];
|
||||||
|
__float z = aabb.min[2] < aabb.max[2] ? aabb.max[2] - aabb.min[2] : aabb.min[2] - aabb.max[2];
|
||||||
|
return vec3(x,y,z);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
Returns positive integer if intersect between A and B, 0 otherwise.
|
||||||
|
For more detailed intersect result check value:
|
||||||
|
CubicVR.enums.aabb.INTERSECT if AABBs intersect
|
||||||
|
CubicVR.enums.aabb.A_INSIDE_B if boxA is inside boxB
|
||||||
|
CubicVR.enums.aabb.B_INSIDE_A if boxB is inside boxA
|
||||||
|
CubicVR.enums.aabb.DISJOINT if AABBs are disjoint (do not intersect)
|
||||||
|
*/
|
||||||
|
aabb_enum intersects(aabb boxA, aabb boxB) {
|
||||||
|
// Disjoint
|
||||||
|
if( boxA.min[0] > boxB.max[0] || boxA.max[0] < boxB.min[0] ){
|
||||||
|
return AABB_DISJOINT;
|
||||||
|
}
|
||||||
|
if( boxA.min[1] > boxB.max[1] || boxA.max[1] < boxB.min[1] ){
|
||||||
|
return AABB_DISJOINT;
|
||||||
|
}
|
||||||
|
if( boxA.min[2] > boxB.max[2] || boxA.max[2] < boxB.min[2] ){
|
||||||
|
return AABB_DISJOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// boxA is inside boxB.
|
||||||
|
if( boxA.min[0] >= boxB.min[0] && boxA.max[0] <= boxB.max[0] &&
|
||||||
|
boxA.min[1] >= boxB.min[1] && boxA.max[1] <= boxB.max[1] &&
|
||||||
|
boxA.min[2] >= boxB.min[2] && boxA.max[2] <= boxB.max[2]) {
|
||||||
|
return AABB_A_INSIDE_B;
|
||||||
|
}
|
||||||
|
// boxB is inside boxA.
|
||||||
|
if( boxB.min[0] >= boxA.min[0] && boxB.max[0] <= boxA.max[0] &&
|
||||||
|
boxB.min[1] >= boxA.min[1] && boxB.max[1] <= boxA.max[1] &&
|
||||||
|
boxB.min[2] >= boxA.min[2] && boxB.max[2] <= boxA.max[2]) {
|
||||||
|
return AABB_B_INSIDE_A;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise AABB's intersect.
|
||||||
|
return AABB_INTERSECT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__aabb__) */
|
27
external/cubicvr2/math/cubic_math.cpp
vendored
Normal file
27
external/cubicvr2/math/cubic_math.cpp
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// math.cpp
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "cubic_math.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec4 &v) {
|
||||||
|
return strm << "{" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "}";
|
||||||
|
}
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec3 &v) {
|
||||||
|
return strm << "{" << v.x << ", " << v.y << ", " << v.z << "}";
|
||||||
|
}
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec2 &v) {
|
||||||
|
return strm << "{" << v.x << ", " << v.y << "}";
|
||||||
|
}
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const mat4 &m) {
|
||||||
|
return strm << "{ " << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << endl
|
||||||
|
<< " " << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << endl
|
||||||
|
<< " " << m[8] << ", " << m[9] << ", " << m[10] << ", " << m[11] << endl
|
||||||
|
<< " " << m[12] << ", " << m[13] << ", " << m[14] << ", " << m[15] << " }" << endl;
|
||||||
|
}
|
||||||
|
}
|
35
external/cubicvr2/math/cubic_math.h
vendored
Normal file
35
external/cubicvr2/math/cubic_math.h
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// math.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__math__
|
||||||
|
#define __CubicVR2__math__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "aabb.h"
|
||||||
|
#include "mat3.h"
|
||||||
|
#include "mat4.h"
|
||||||
|
#include "quaternion.h"
|
||||||
|
#include "transform.h"
|
||||||
|
#include "triangle.h"
|
||||||
|
#include "vec2.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
#include "vec4.h"
|
||||||
|
#include "plane.h"
|
||||||
|
#include "sphere.h"
|
||||||
|
#include "frustum.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec4 &v);
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec3 &v);
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const vec2 &v);
|
||||||
|
std::ostream& operator<<(std::ostream &strm, const mat4 &m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__math__) */
|
41
external/cubicvr2/math/cubic_types.h
vendored
Normal file
41
external/cubicvr2/math/cubic_types.h
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// types.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-21.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CubicVR2_types_h
|
||||||
|
#define CubicVR2_types_h
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
typedef double __float64;
|
||||||
|
typedef float __float32;
|
||||||
|
|
||||||
|
typedef __float32 __float;
|
||||||
|
|
||||||
|
#define COMBINE(x,y) x ## y
|
||||||
|
#define floatSG(c, x,y) \
|
||||||
|
__float COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(__float value) { y = value; return *this; }
|
||||||
|
#define intSG(c, x,y) \
|
||||||
|
int COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(int value) { y = value; return *this; }
|
||||||
|
#define uintSG(c, x,y) \
|
||||||
|
unsigned int COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(unsigned int value) { y = value; return *this; }
|
||||||
|
#define boolSG(c,x,y) \
|
||||||
|
bool COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(bool value) { y = value; return *this; }
|
||||||
|
#define stringSG(c,x,y) \
|
||||||
|
string COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(string value) { y = value; return *this; }
|
||||||
|
#define isBoolSG(c,x,y) \
|
||||||
|
bool COMBINE(is,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(bool value) { y = value; return *this; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
166
external/cubicvr2/math/frustum.h
vendored
Normal file
166
external/cubicvr2/math/frustum.h
vendored
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
//
|
||||||
|
// frustum.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CubicVR2_frustum_h
|
||||||
|
#define CubicVR2_frustum_h
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "mat4.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
#include "vec4.h"
|
||||||
|
#include "plane.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
enum frustum_plane { PLANE_LEFT, PLANE_RIGHT, PLANE_TOP, PLANE_BOTTOM, PLANE_NEAR, PLANE_FAR };
|
||||||
|
|
||||||
|
struct frustum {
|
||||||
|
std::vector<vec4> planes;
|
||||||
|
vec4 sphere;
|
||||||
|
|
||||||
|
frustum() {
|
||||||
|
planes.resize(6);
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
planes[i] = vec4(0, 0, 0, 0);
|
||||||
|
} //for
|
||||||
|
} //Frustum::Constructor
|
||||||
|
|
||||||
|
void extract(vec3 position, mat4 mvMatrix, mat4 pMatrix) {
|
||||||
|
mat4 comboMatrix = mat4::multiply(pMatrix, mvMatrix, true);
|
||||||
|
|
||||||
|
// Left clipping plane
|
||||||
|
planes[PLANE_LEFT][0] = comboMatrix[3] + comboMatrix[0];
|
||||||
|
planes[PLANE_LEFT][1] = comboMatrix[7] + comboMatrix[4];
|
||||||
|
planes[PLANE_LEFT][2] = comboMatrix[11] + comboMatrix[8];
|
||||||
|
planes[PLANE_LEFT][3] = comboMatrix[15] + comboMatrix[12];
|
||||||
|
|
||||||
|
// Right clipping plane
|
||||||
|
planes[PLANE_RIGHT][0] = comboMatrix[3] - comboMatrix[0];
|
||||||
|
planes[PLANE_RIGHT][1] = comboMatrix[7] - comboMatrix[4];
|
||||||
|
planes[PLANE_RIGHT][2] = comboMatrix[11] - comboMatrix[8];
|
||||||
|
planes[PLANE_RIGHT][3] = comboMatrix[15] - comboMatrix[12];
|
||||||
|
|
||||||
|
// Top clipping plane
|
||||||
|
planes[PLANE_TOP][0] = comboMatrix[3] - comboMatrix[1];
|
||||||
|
planes[PLANE_TOP][1] = comboMatrix[7] - comboMatrix[5];
|
||||||
|
planes[PLANE_TOP][2] = comboMatrix[11] - comboMatrix[9];
|
||||||
|
planes[PLANE_TOP][3] = comboMatrix[15] - comboMatrix[13];
|
||||||
|
|
||||||
|
// Bottom clipping plane
|
||||||
|
planes[PLANE_BOTTOM][0] = comboMatrix[3] + comboMatrix[1];
|
||||||
|
planes[PLANE_BOTTOM][1] = comboMatrix[7] + comboMatrix[5];
|
||||||
|
planes[PLANE_BOTTOM][2] = comboMatrix[11] + comboMatrix[9];
|
||||||
|
planes[PLANE_BOTTOM][3] = comboMatrix[15] + comboMatrix[13];
|
||||||
|
|
||||||
|
// Near clipping plane
|
||||||
|
planes[PLANE_NEAR][0] = comboMatrix[3] + comboMatrix[2];
|
||||||
|
planes[PLANE_NEAR][1] = comboMatrix[7] + comboMatrix[6];
|
||||||
|
planes[PLANE_NEAR][2] = comboMatrix[11] + comboMatrix[10];
|
||||||
|
planes[PLANE_NEAR][3] = comboMatrix[15] + comboMatrix[14];
|
||||||
|
|
||||||
|
// Far clipping plane
|
||||||
|
planes[PLANE_FAR][0] = comboMatrix[3] - comboMatrix[2];
|
||||||
|
planes[PLANE_FAR][1] = comboMatrix[7] - comboMatrix[6];
|
||||||
|
planes[PLANE_FAR][2] = comboMatrix[11] - comboMatrix[10];
|
||||||
|
planes[PLANE_FAR][3] = comboMatrix[15] - comboMatrix[14];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 6; ++i) {
|
||||||
|
planes[i] = vec4::normalize(planes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sphere
|
||||||
|
__float fov = 1 / pMatrix[5];
|
||||||
|
__float near = -planes[PLANE_NEAR][3];
|
||||||
|
__float far = planes[PLANE_FAR][3];
|
||||||
|
__float view_length = far - near;
|
||||||
|
__float height = view_length * fov;
|
||||||
|
__float width = height;
|
||||||
|
|
||||||
|
vec3 P(0, 0, near + view_length * 0.5f);
|
||||||
|
vec3 Q(width, height, near + view_length);
|
||||||
|
vec3 diff = vec3::subtract(P, Q);
|
||||||
|
__float diff_mag = vec3::length(diff);
|
||||||
|
|
||||||
|
vec3 look_v = vec3(comboMatrix[3], comboMatrix[9], comboMatrix[10]);
|
||||||
|
__float look_mag = vec3::length(look_v);
|
||||||
|
look_v = vec3::multiply(look_v, 1 / look_mag);
|
||||||
|
|
||||||
|
vec3 pos = vec3(position[0], position[1], position[2]);
|
||||||
|
pos = vec3::add(pos, vec3::multiply(look_v, view_length * 0.5f));
|
||||||
|
pos = vec3::add(pos, vec3::multiply(look_v, 1));
|
||||||
|
|
||||||
|
sphere = vec4(pos[0], pos[1], pos[2], diff_mag);
|
||||||
|
|
||||||
|
}; //Frustum::extract
|
||||||
|
|
||||||
|
int contains_sphere(vec4 sphere) {
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 6; ++i) {
|
||||||
|
vec4 &p = planes[i];
|
||||||
|
vec3 normal = vec3(p[0], p[1], p[2]);
|
||||||
|
__float distance = vec3::dot(normal, vec3(sphere[0],sphere[1],sphere[2])) + p[3];
|
||||||
|
|
||||||
|
//OUT
|
||||||
|
if (distance < -sphere[3]) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//INTERSECT
|
||||||
|
if (fabs(distance) < sphere[3]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //for
|
||||||
|
//IN
|
||||||
|
return 1;
|
||||||
|
}; //Frustum::contains_sphere
|
||||||
|
|
||||||
|
int contains_box(aabb bbox) {
|
||||||
|
int total_in = 0;
|
||||||
|
|
||||||
|
vec3 points[8];
|
||||||
|
|
||||||
|
points[0] = bbox.min;
|
||||||
|
points[1] = vec3(bbox.min[0], bbox.min[1], bbox.max[2]);
|
||||||
|
points[2] = vec3(bbox.min[0], bbox.max[1], bbox.min[2]);
|
||||||
|
points[3] = vec3(bbox.min[0], bbox.max[1], bbox.max[2]);
|
||||||
|
points[4] = vec3(bbox.max[0], bbox.min[1], bbox.min[2]);
|
||||||
|
points[5] = vec3(bbox.max[0], bbox.min[1], bbox.max[2]);
|
||||||
|
points[6] = vec3(bbox.max[0], bbox.max[1], bbox.min[2]);
|
||||||
|
points[7] = bbox.max;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 6; ++i) {
|
||||||
|
unsigned int in_count = 8;
|
||||||
|
unsigned int point_in = 1;
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < 8; ++j) {
|
||||||
|
if (plane::classifyPoint(planes[i], points[j]) == -1) {
|
||||||
|
point_in = 0;
|
||||||
|
--in_count;
|
||||||
|
} //if
|
||||||
|
} //for j
|
||||||
|
|
||||||
|
//OUT
|
||||||
|
if (in_count == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_in += point_in;
|
||||||
|
} //for i
|
||||||
|
//IN
|
||||||
|
if (total_in == 6) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}; //Frustum::contains_box
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
83
external/cubicvr2/math/mat3.h
vendored
Normal file
83
external/cubicvr2/math/mat3.h
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// mat3.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__mat3__
|
||||||
|
#define __CubicVR2__mat3__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
#define mat3SG(c,x,y) \
|
||||||
|
mat3 COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(mat3 value) { y = value; return *this; }
|
||||||
|
|
||||||
|
struct mat3 {
|
||||||
|
__float a,b,c,d,e,f,g,h,i;
|
||||||
|
|
||||||
|
// __float operator [] (unsigned i) const { return ((__float *)this)[i]; }
|
||||||
|
__float& operator [] (unsigned i) { return ((__float *)this)[i]; }
|
||||||
|
operator __float*() const { return (__float *)this; }
|
||||||
|
|
||||||
|
mat3(__float ai,__float bi,__float ci,__float di,__float ei,__float fi,__float gi,__float hi,__float ii) {
|
||||||
|
a = ai; b = bi; c = ci; d = di; e = ei; f = fi; g = gi; h = hi; i = ii;
|
||||||
|
};
|
||||||
|
|
||||||
|
mat3() { memset((__float *)this, 0, sizeof(mat3)); }
|
||||||
|
// mat3 operator* (mat4 m) { return mat3::multiply(*this,m); };
|
||||||
|
// void operator*= (mat4 m) { *this = mat3::multiply(*this,m); };
|
||||||
|
|
||||||
|
|
||||||
|
static mat3 identity() {
|
||||||
|
return mat3(1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transpose_inline(mat3 &mat) {
|
||||||
|
__float a01 = mat[1], a02 = mat[2], a12 = mat[5];
|
||||||
|
|
||||||
|
mat[1] = mat[3];
|
||||||
|
mat[2] = mat[6];
|
||||||
|
mat[3] = a01;
|
||||||
|
mat[5] = mat[7];
|
||||||
|
mat[6] = a02;
|
||||||
|
mat[7] = a12;
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat3 transpose(mat3 mat_in) {
|
||||||
|
__float a01 = mat_in[1], a02 = mat_in[2], a12 = mat_in[5];
|
||||||
|
|
||||||
|
mat3 mat;
|
||||||
|
|
||||||
|
mat[1] = mat_in[3];
|
||||||
|
mat[2] = mat_in[6];
|
||||||
|
mat[3] = a01;
|
||||||
|
mat[5] = mat_in[7];
|
||||||
|
mat[6] = a02;
|
||||||
|
mat[7] = a12;
|
||||||
|
|
||||||
|
return mat;
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 multiply(mat3 m1, vec3 m2) {
|
||||||
|
vec3 mOut;
|
||||||
|
|
||||||
|
mOut[0] = m2[0] * m1[0] + m2[3] * m1[1] + m2[6] * m1[2] ;
|
||||||
|
mOut[1] = m2[1] * m1[0] + m2[4] * m1[1] + m2[7] * m1[2] ;
|
||||||
|
mOut[2] = m2[2] * m1[0] + m2[5] * m1[1] + m2[8] * m1[2];
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__mat3__) */
|
304
external/cubicvr2/math/mat4.h
vendored
Normal file
304
external/cubicvr2/math/mat4.h
vendored
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
//
|
||||||
|
// mat4.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-21.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__mat4__
|
||||||
|
#define __CubicVR2__mat4__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "cubic_types.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
#include "vec4.h"
|
||||||
|
#include "mat3.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
using namespace std;
|
||||||
|
#define mat4SG(c,x,y) \
|
||||||
|
mat4 COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(mat4 value) { y = value; return *this; }
|
||||||
|
struct mat4 {
|
||||||
|
__float a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;
|
||||||
|
|
||||||
|
// __float operator [] (unsigned i) const { return ((__float *)this)[i]; }
|
||||||
|
__float& operator [] (unsigned i) { return ((__float *)this)[i]; }
|
||||||
|
operator __float*() const { return (__float *)this; }
|
||||||
|
mat4(__float ai,__float bi,__float ci,__float di,__float ei,__float fi,__float gi,__float hi,__float ii,__float ji,__float ki,__float li,__float mi,__float ni,__float oi,__float pi) {
|
||||||
|
a = ai; b = bi; c = ci; d = di; e = ei; f = fi; g = gi; h = hi; i = ii; j = ji; k = ki; l = li; m = mi; n = ni; o = oi; p = pi;
|
||||||
|
}
|
||||||
|
mat4() { memset(this,0,sizeof(mat4)); }
|
||||||
|
mat4 operator* (mat4 m) { return mat4::multiply(*this, m, true); };
|
||||||
|
void operator*= (mat4 m) { *this = mat4::multiply(*this, m, true); };
|
||||||
|
// mat4 &operator= (const mat4 &m) { memcpy(this,(__float *)m,sizeof(__float)*16); return *this; };
|
||||||
|
|
||||||
|
static mat4 identity() {
|
||||||
|
return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mat4 multiply(mat4 mLeft, mat4 mRight, bool updated) {
|
||||||
|
mat4 mOut;
|
||||||
|
|
||||||
|
mOut[0] = mLeft[0] * mRight[0] + mLeft[4] * mRight[1] + mLeft[8] * mRight[2] + mLeft[12] * mRight[3];
|
||||||
|
mOut[1] = mLeft[1] * mRight[0] + mLeft[5] * mRight[1] + mLeft[9] * mRight[2] + mLeft[13] * mRight[3];
|
||||||
|
mOut[2] = mLeft[2] * mRight[0] + mLeft[6] * mRight[1] + mLeft[10] * mRight[2] + mLeft[14] * mRight[3];
|
||||||
|
mOut[3] = mLeft[3] * mRight[0] + mLeft[7] * mRight[1] + mLeft[11] * mRight[2] + mLeft[15] * mRight[3];
|
||||||
|
mOut[4] = mLeft[0] * mRight[4] + mLeft[4] * mRight[5] + mLeft[8] * mRight[6] + mLeft[12] * mRight[7];
|
||||||
|
mOut[5] = mLeft[1] * mRight[4] + mLeft[5] * mRight[5] + mLeft[9] * mRight[6] + mLeft[13] * mRight[7];
|
||||||
|
mOut[6] = mLeft[2] * mRight[4] + mLeft[6] * mRight[5] + mLeft[10] * mRight[6] + mLeft[14] * mRight[7];
|
||||||
|
mOut[7] = mLeft[3] * mRight[4] + mLeft[7] * mRight[5] + mLeft[11] * mRight[6] + mLeft[15] * mRight[7];
|
||||||
|
mOut[8] = mLeft[0] * mRight[8] + mLeft[4] * mRight[9] + mLeft[8] * mRight[10] + mLeft[12] * mRight[11];
|
||||||
|
mOut[9] = mLeft[1] * mRight[8] + mLeft[5] * mRight[9] + mLeft[9] * mRight[10] + mLeft[13] * mRight[11];
|
||||||
|
mOut[10] = mLeft[2] * mRight[8] + mLeft[6] * mRight[9] + mLeft[10] * mRight[10] + mLeft[14] * mRight[11];
|
||||||
|
mOut[11] = mLeft[3] * mRight[8] + mLeft[7] * mRight[9] + mLeft[11] * mRight[10] + mLeft[15] * mRight[11];
|
||||||
|
mOut[12] = mLeft[0] * mRight[12] + mLeft[4] * mRight[13] + mLeft[8] * mRight[14] + mLeft[12] * mRight[15];
|
||||||
|
mOut[13] = mLeft[1] * mRight[12] + mLeft[5] * mRight[13] + mLeft[9] * mRight[14] + mLeft[13] * mRight[15];
|
||||||
|
mOut[14] = mLeft[2] * mRight[12] + mLeft[6] * mRight[13] + mLeft[10] * mRight[14] + mLeft[14] * mRight[15];
|
||||||
|
mOut[15] = mLeft[3] * mRight[12] + mLeft[7] * mRight[13] + mLeft[11] * mRight[14] + mLeft[15] * mRight[15];
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 multiply(mat4 m1, vec3 m2, bool updated) {
|
||||||
|
vec3 mOut;
|
||||||
|
|
||||||
|
mOut[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12];
|
||||||
|
mOut[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13];
|
||||||
|
mOut[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14];
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mat4 perspective(__float fovy, __float aspect, __float near, __float far) {
|
||||||
|
__float yFac = tan(fovy * (float)M_PI / 360.0f);
|
||||||
|
__float xFac = yFac * aspect;
|
||||||
|
|
||||||
|
return mat4(
|
||||||
|
1.0f / xFac, 0, 0, 0, 0, 1.0f / yFac, 0, 0, 0, 0, -(far + near) / (far - near), -1, 0, 0, -(2.0f * far * near) / (far - near), 0);
|
||||||
|
};
|
||||||
|
static mat4 ortho(__float left,__float right,__float bottom,__float top,__float near,__float far) {
|
||||||
|
return mat4(2.0f / (right - left), 0, 0, 0, 0, 2.0f / (top - bottom), 0, 0, 0, 0, -2.0f / (far - near), 0, -(left + right) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1);
|
||||||
|
};
|
||||||
|
static __float determinant(mat4 m) {
|
||||||
|
|
||||||
|
__float a0 = m[0] * m[5] - m[1] * m[4];
|
||||||
|
__float a1 = m[0] * m[6] - m[2] * m[4];
|
||||||
|
__float a2 = m[0] * m[7] - m[3] * m[4];
|
||||||
|
__float a3 = m[1] * m[6] - m[2] * m[5];
|
||||||
|
__float a4 = m[1] * m[7] - m[3] * m[5];
|
||||||
|
__float a5 = m[2] * m[7] - m[3] * m[6];
|
||||||
|
__float b0 = m[8] * m[13] - m[9] * m[12];
|
||||||
|
__float b1 = m[8] * m[14] - m[10] * m[12];
|
||||||
|
__float b2 = m[8] * m[15] - m[11] * m[12];
|
||||||
|
__float b3 = m[9] * m[14] - m[10] * m[13];
|
||||||
|
__float b4 = m[9] * m[15] - m[11] * m[13];
|
||||||
|
__float b5 = m[10] * m[15] - m[11] * m[14];
|
||||||
|
|
||||||
|
__float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
|
||||||
|
|
||||||
|
return det;
|
||||||
|
};
|
||||||
|
// coFactor: function (m, n, out) {
|
||||||
|
// // .. todo..
|
||||||
|
// },
|
||||||
|
|
||||||
|
static mat4 transpose(mat4 m) {
|
||||||
|
return mat4(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat3 inverse_mat3(mat4 mat) {
|
||||||
|
mat3 dest;
|
||||||
|
|
||||||
|
__float a00 = mat[0], a01 = mat[1], a02 = mat[2],
|
||||||
|
a10 = mat[4], a11 = mat[5], a12 = mat[6],
|
||||||
|
a20 = mat[8], a21 = mat[9], a22 = mat[10];
|
||||||
|
|
||||||
|
__float b01 = a22*a11-a12*a21,
|
||||||
|
b11 = -a22*a10+a12*a20,
|
||||||
|
b21 = a21*a10-a11*a20;
|
||||||
|
|
||||||
|
__float d = a00*b01 + a01*b11 + a02*b21;
|
||||||
|
if (!d) { return dest; }
|
||||||
|
__float id = 1/d;
|
||||||
|
|
||||||
|
dest[0] = b01*id;
|
||||||
|
dest[1] = (-a22*a01 + a02*a21)*id;
|
||||||
|
dest[2] = (a12*a01 - a02*a11)*id;
|
||||||
|
dest[3] = b11*id;
|
||||||
|
dest[4] = (a22*a00 - a02*a20)*id;
|
||||||
|
dest[5] = (-a12*a00 + a02*a10)*id;
|
||||||
|
dest[6] = b21*id;
|
||||||
|
dest[7] = (-a21*a00 + a01*a20)*id;
|
||||||
|
dest[8] = (a11*a00 - a01*a10)*id;
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 inverse(mat4 m) {
|
||||||
|
mat4 m_inv;
|
||||||
|
|
||||||
|
__float a0 = m[0] * m[5] - m[1] * m[4];
|
||||||
|
__float a1 = m[0] * m[6] - m[2] * m[4];
|
||||||
|
__float a2 = m[0] * m[7] - m[3] * m[4];
|
||||||
|
__float a3 = m[1] * m[6] - m[2] * m[5];
|
||||||
|
__float a4 = m[1] * m[7] - m[3] * m[5];
|
||||||
|
__float a5 = m[2] * m[7] - m[3] * m[6];
|
||||||
|
__float b0 = m[8] * m[13] - m[9] * m[12];
|
||||||
|
__float b1 = m[8] * m[14] - m[10] * m[12];
|
||||||
|
__float b2 = m[8] * m[15] - m[11] * m[12];
|
||||||
|
__float b3 = m[9] * m[14] - m[10] * m[13];
|
||||||
|
__float b4 = m[9] * m[15] - m[11] * m[13];
|
||||||
|
__float b5 = m[10] * m[15] - m[11] * m[14];
|
||||||
|
|
||||||
|
__float determinant = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
|
||||||
|
|
||||||
|
if (determinant != 0) {
|
||||||
|
m_inv[0] = 0 + m[5] * b5 - m[6] * b4 + m[7] * b3;
|
||||||
|
m_inv[4] = 0 - m[4] * b5 + m[6] * b2 - m[7] * b1;
|
||||||
|
m_inv[8] = 0 + m[4] * b4 - m[5] * b2 + m[7] * b0;
|
||||||
|
m_inv[12] = 0 - m[4] * b3 + m[5] * b1 - m[6] * b0;
|
||||||
|
m_inv[1] = 0 - m[1] * b5 + m[2] * b4 - m[3] * b3;
|
||||||
|
m_inv[5] = 0 + m[0] * b5 - m[2] * b2 + m[3] * b1;
|
||||||
|
m_inv[9] = 0 - m[0] * b4 + m[1] * b2 - m[3] * b0;
|
||||||
|
m_inv[13] = 0 + m[0] * b3 - m[1] * b1 + m[2] * b0;
|
||||||
|
m_inv[2] = 0 + m[13] * a5 - m[14] * a4 + m[15] * a3;
|
||||||
|
m_inv[6] = 0 - m[12] * a5 + m[14] * a2 - m[15] * a1;
|
||||||
|
m_inv[10] = 0 + m[12] * a4 - m[13] * a2 + m[15] * a0;
|
||||||
|
m_inv[14] = 0 - m[12] * a3 + m[13] * a1 - m[14] * a0;
|
||||||
|
m_inv[3] = 0 - m[9] * a5 + m[10] * a4 - m[11] * a3;
|
||||||
|
m_inv[7] = 0 + m[8] * a5 - m[10] * a2 + m[11] * a1;
|
||||||
|
m_inv[11] = 0 - m[8] * a4 + m[9] * a2 - m[11] * a0;
|
||||||
|
m_inv[15] = 0 + m[8] * a3 - m[9] * a1 + m[10] * a0;
|
||||||
|
|
||||||
|
__float inverse_det = 1.0f / determinant;
|
||||||
|
|
||||||
|
m_inv[0] *= inverse_det;
|
||||||
|
m_inv[1] *= inverse_det;
|
||||||
|
m_inv[2] *= inverse_det;
|
||||||
|
m_inv[3] *= inverse_det;
|
||||||
|
m_inv[4] *= inverse_det;
|
||||||
|
m_inv[5] *= inverse_det;
|
||||||
|
m_inv[6] *= inverse_det;
|
||||||
|
m_inv[7] *= inverse_det;
|
||||||
|
m_inv[8] *= inverse_det;
|
||||||
|
m_inv[9] *= inverse_det;
|
||||||
|
m_inv[10] *= inverse_det;
|
||||||
|
m_inv[11] *= inverse_det;
|
||||||
|
m_inv[12] *= inverse_det;
|
||||||
|
m_inv[13] *= inverse_det;
|
||||||
|
m_inv[14] *= inverse_det;
|
||||||
|
m_inv[15] *= inverse_det;
|
||||||
|
|
||||||
|
return m_inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mat4::identity();
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 translate(__float x, __float y, __float z) {
|
||||||
|
mat4 m = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, x, y, z, 1.0f);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 rotateAxis(__float r, __float x, __float y, __float z) { // rotate r about axis x,y,z
|
||||||
|
__float sAng = sinf(r*((float)M_PI/180.0f));
|
||||||
|
__float cAng = cosf(r*((float)M_PI/180.0f));
|
||||||
|
|
||||||
|
return mat4( cAng+(x*x)*(1.0f-cAng), x*y*(1.0f-cAng) - z*sAng, x*z*(1.0f-cAng) + y*sAng, 0,
|
||||||
|
y*x*(1.0f-cAng)+z*sAng, cAng + y*y*(1.0f-cAng), y*z*(1.0f-cAng)-x*sAng, 0,
|
||||||
|
z*x*(1.0f-cAng)-y*sAng, z*y*(1.0f-cAng)+x*sAng, cAng+(z*z)*(1.0f-cAng), 0,
|
||||||
|
0, 0, 0, 1 );
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 rotate(__float x, __float y, __float z) { // rotate each axis, angles x, y, z in turn
|
||||||
|
__float sAng,cAng;
|
||||||
|
mat4 mOut = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
if (z!=0) {
|
||||||
|
sAng = sinf(z*((float)M_PI/180.0f));
|
||||||
|
cAng = cosf(z*((float)M_PI/180.0f));
|
||||||
|
|
||||||
|
mOut *= mat4(cAng, sAng, 0.0f, 0.0f, -sAng, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y!=0) {
|
||||||
|
sAng = sinf(y*((float)M_PI/180.0f));
|
||||||
|
cAng = cosf(y*((float)M_PI/180.0f));
|
||||||
|
|
||||||
|
mOut *= mat4(cAng, 0.0f, -sAng, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, sAng, 0.0f, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x!=0) {
|
||||||
|
sAng = sinf(x*((float)M_PI/180.0f));
|
||||||
|
cAng = cosf(x*((float)M_PI/180.0f));
|
||||||
|
|
||||||
|
mOut *= mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, cAng, sAng, 0.0f, 0.0f, -sAng, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 scale(__float x, __float y, __float z) {
|
||||||
|
return mat4(x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
};
|
||||||
|
|
||||||
|
static mat4 transform(vec3 position, vec3 rotation, vec3 scale) {
|
||||||
|
mat4 m = mat4::identity();
|
||||||
|
|
||||||
|
if (position!=NULL) {
|
||||||
|
m *= mat4::translate(position[0],position[1],position[2]);
|
||||||
|
}
|
||||||
|
if (rotation!=NULL) {
|
||||||
|
if (!(rotation[0] == 0 && rotation[1] == 0 && rotation[2] == 0)) {
|
||||||
|
m *= mat4::rotate(rotation[0],rotation[1],rotation[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scale!=NULL) {
|
||||||
|
if (!(scale[0] == 1 && scale[1] == 1 && scale[2] == 1)) {
|
||||||
|
m *= mat4::scale(scale[0],scale[1],scale[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
static vec4 vec4_multiply(vec4 m1, mat4 m2) {
|
||||||
|
vec4 mOut;
|
||||||
|
|
||||||
|
mOut[0] = m2[0] * m1[0] + m2[4] * m1[1] + m2[8] * m1[2] + m2[12] * m1[3];
|
||||||
|
mOut[1] = m2[1] * m1[0] + m2[5] * m1[1] + m2[9] * m1[2] + m2[13] * m1[3];
|
||||||
|
mOut[2] = m2[2] * m1[0] + m2[6] * m1[1] + m2[10] * m1[2] + m2[14] * m1[3];
|
||||||
|
mOut[3] = m2[3] * m1[0] + m2[7] * m1[1] + m2[11] * m1[2] + m2[15] * m1[3];
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
static mat4 lookat(__float eyex, __float eyey, __float eyez, __float centerx, __float centery, __float centerz, __float upx, __float upy, __float upz) {
|
||||||
|
vec3 forward, side, up;
|
||||||
|
|
||||||
|
forward[0] = centerx - eyex;
|
||||||
|
forward[1] = centery - eyey;
|
||||||
|
forward[2] = centerz - eyez;
|
||||||
|
|
||||||
|
up[0] = upx;
|
||||||
|
up[1] = upy;
|
||||||
|
up[2] = upz;
|
||||||
|
|
||||||
|
forward = vec3::normalize(forward);
|
||||||
|
|
||||||
|
/* Side = forward x up */
|
||||||
|
side = vec3::cross(forward, up);
|
||||||
|
side = vec3::normalize(side);
|
||||||
|
|
||||||
|
/* Recompute up as: up = side x forward */
|
||||||
|
up = vec3::cross(side, forward);
|
||||||
|
|
||||||
|
return mat4::translate(-eyex,-eyey,-eyez) * mat4( side[0], up[0], -forward[0], 0, side[1], up[1], -forward[1], 0, side[2], up[2], -forward[2], 0, 0, 0, 0, 1);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__mat4__) */
|
32
external/cubicvr2/math/plane.h
vendored
Normal file
32
external/cubicvr2/math/plane.h
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// plane.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CubicVR2_plane_h
|
||||||
|
#define CubicVR2_plane_h
|
||||||
|
|
||||||
|
#include "vec4.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
struct plane : vec4 {
|
||||||
|
static int classifyPoint(vec4 plane, vec3 pt) {
|
||||||
|
__float dist = (plane[0] * pt[0]) + (plane[1] * pt[1]) + (plane[2] * pt[2]) + (plane[3]);
|
||||||
|
if (dist < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (dist > 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
100
external/cubicvr2/math/quaternion.h
vendored
Normal file
100
external/cubicvr2/math/quaternion.h
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
//
|
||||||
|
// quaternion.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__quaternion__
|
||||||
|
#define __CubicVR2__quaternion__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "vec4.h"
|
||||||
|
#include "mat4.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
struct quaternion : vec4 {
|
||||||
|
|
||||||
|
static vec4 fromMatrix(mat4 mat) {
|
||||||
|
__float t = 1 + mat[0] + mat[5] + mat[10];
|
||||||
|
__float S,X,Y,Z,W;
|
||||||
|
|
||||||
|
if ( t > 0.00000001 ) {
|
||||||
|
S = sqrtf(t) * 2;
|
||||||
|
X = ( mat[9] - mat[6] ) / S;
|
||||||
|
Y = ( mat[2] - mat[8] ) / S;
|
||||||
|
Z = ( mat[4] - mat[1] ) / S;
|
||||||
|
W = 0.25f * S;
|
||||||
|
} else {
|
||||||
|
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
|
||||||
|
S = sqrtf( 1.0f + mat[0] - mat[5] - mat[10] ) * 2.0f;
|
||||||
|
X = 0.25f * S;
|
||||||
|
Y = (mat[4] + mat[1] ) / S;
|
||||||
|
Z = (mat[2] + mat[8] ) / S;
|
||||||
|
W = (mat[9] - mat[6] ) / S;
|
||||||
|
} else if ( mat[5] > mat[10] ) { // Column 1:
|
||||||
|
S = sqrtf( 1.0f + mat[5] - mat[0] - mat[10] ) * 2.0f;
|
||||||
|
X = (mat[4] + mat[1] ) / S;
|
||||||
|
Y = 0.25f * S;
|
||||||
|
Z = (mat[9] + mat[6] ) / S;
|
||||||
|
W = (mat[2] - mat[8] ) / S;
|
||||||
|
} else { // Column 2:
|
||||||
|
S = sqrtf( 1.0f + mat[10] - mat[0] - mat[5] ) * 2.0f;
|
||||||
|
X = (mat[2] + mat[8] ) / S;
|
||||||
|
Y = (mat[9] + mat[6] ) / S;
|
||||||
|
Z = 0.25f * S;
|
||||||
|
W = (mat[4] - mat[1] ) / S;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(X,Y,Z,W);
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec4 fromEuler(__float bank, __float heading, __float pitch) { // x,y,z
|
||||||
|
__float c1 = cosf(((float)M_PI / 180.0f) * heading / 2.0f);
|
||||||
|
__float s1 = sinf(((float)M_PI / 180.0f) * heading / 2.0f);
|
||||||
|
__float c2 = cosf(((float)M_PI / 180.0f) * pitch / 2.0f);
|
||||||
|
__float s2 = sinf(((float)M_PI / 180.0f) * pitch / 2.0f);
|
||||||
|
__float c3 = cosf(((float)M_PI / 180.0f) * bank / 2.0f);
|
||||||
|
__float s3 = sinf(((float)M_PI / 180.0f) * bank / 2.0f);
|
||||||
|
__float c1c2 = c1 * c2;
|
||||||
|
__float s1s2 = s1 * s2;
|
||||||
|
|
||||||
|
vec4 mOut;
|
||||||
|
|
||||||
|
mOut[0] = c1c2 * c3 - s1s2 * s3;
|
||||||
|
mOut[1] = c1c2 * s3 + s1s2 * c3;
|
||||||
|
mOut[2] = s1 * c2 * c3 + c1 * s2 * s3;
|
||||||
|
mOut[3] = c1 * s2 * c3 - s1 * c2 * s3;
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 toEuler(vec4 q) {
|
||||||
|
__float sqx = q[0] * q[0];
|
||||||
|
__float sqy = q[1] * q[1];
|
||||||
|
__float sqz = q[2] * q[2];
|
||||||
|
__float sqw = q[3] * q[3];
|
||||||
|
|
||||||
|
__float x = (180.0f / (float)M_PI) * ((atan2f(2.0f * (q[1] * q[2] + q[0] * q[3]), (-sqx - sqy + sqz + sqw))));
|
||||||
|
__float y = (180.0f / (float)M_PI) * ((asinf(-2.0f * (q[0] * q[2] - q[1] * q[3]))));
|
||||||
|
__float z = (180.0f / (float)M_PI) * ((atan2f(2.0f * (q[0] * q[1] + q[2] * q[3]), (sqx - sqy - sqz + sqw))));
|
||||||
|
|
||||||
|
return vec3(x, y, z);
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec4 multiply(vec4 q1, vec4 q2) {
|
||||||
|
__float x = q1[0] * q2[3] + q1[3] * q2[0] + q1[1] * q2[2] - q1[2] * q2[1];
|
||||||
|
__float y = q1[1] * q2[3] + q1[3] * q2[1] + q1[2] * q2[0] - q1[0] * q2[2];
|
||||||
|
__float z = q1[2] * q2[3] + q1[3] * q2[2] + q1[0] * q2[1] - q1[1] * q2[0];
|
||||||
|
__float w = q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2];
|
||||||
|
|
||||||
|
return vec4(x,y,z,w);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__quaternion__) */
|
34
external/cubicvr2/math/sphere.h
vendored
Normal file
34
external/cubicvr2/math/sphere.h
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// sphere.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CubicVR2_sphere_h
|
||||||
|
#define CubicVR2_sphere_h
|
||||||
|
|
||||||
|
#include "vec3.h"
|
||||||
|
#include "vec4.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
struct sphere {
|
||||||
|
bool intersects(vec4 sphere, vec4 other) {
|
||||||
|
vec3 spherePos(sphere[0], sphere[1], sphere[2]);
|
||||||
|
vec3 otherPos(other[0], other[1], other[2]);
|
||||||
|
vec3 diff = vec3::subtract(spherePos, otherPos);
|
||||||
|
|
||||||
|
__float mag = sqrtf(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]);
|
||||||
|
__float sum_radii = sphere[3] + other[3];
|
||||||
|
|
||||||
|
if (mag * mag < sum_radii * sum_radii) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
175
external/cubicvr2/math/transform.h
vendored
Normal file
175
external/cubicvr2/math/transform.h
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
//
|
||||||
|
// Transform.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__Transform__
|
||||||
|
#define __CubicVR2__Transform__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "cubic_types.h"
|
||||||
|
#include "mat4.h"
|
||||||
|
#include "vec3.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
class transform {
|
||||||
|
std::vector<mat4> m_stack;
|
||||||
|
std::vector<mat4> m_cache;
|
||||||
|
int c_stack;
|
||||||
|
int valid;
|
||||||
|
mat4 result;
|
||||||
|
|
||||||
|
transform() {
|
||||||
|
c_stack = 0;
|
||||||
|
valid = false;
|
||||||
|
result = mat4::identity();
|
||||||
|
};
|
||||||
|
|
||||||
|
transform(mat4 init_mat) {
|
||||||
|
clearStack(init_mat);
|
||||||
|
};
|
||||||
|
|
||||||
|
void setIdentity() {
|
||||||
|
m_stack[c_stack] = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
if (valid == c_stack && c_stack) {
|
||||||
|
valid--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 getIdentity() {
|
||||||
|
return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate() {
|
||||||
|
valid = 0;
|
||||||
|
result = mat4::identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 getResult() {
|
||||||
|
if (!c_stack) {
|
||||||
|
return m_stack[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 m = getIdentity();
|
||||||
|
|
||||||
|
if (valid > c_stack-1) valid = c_stack-1;
|
||||||
|
|
||||||
|
for (int i = valid; i < c_stack+1; i++) {
|
||||||
|
m = mat4::multiply(m, m_stack[i], true);
|
||||||
|
m_cache[i] = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
valid = c_stack-1;
|
||||||
|
|
||||||
|
result = m_cache[c_stack];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushMatrix(mat4 m) {
|
||||||
|
c_stack++;
|
||||||
|
m_stack[c_stack] = (m ? m : getIdentity());
|
||||||
|
}
|
||||||
|
|
||||||
|
void popMatrix() {
|
||||||
|
if (c_stack == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c_stack--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearStack(mat4 init_mat) {
|
||||||
|
m_stack.clear();
|
||||||
|
m_cache.clear();
|
||||||
|
c_stack = 0;
|
||||||
|
valid = 0;
|
||||||
|
delete result;
|
||||||
|
result = mat4::identity();
|
||||||
|
|
||||||
|
if (init_mat != NULL) {
|
||||||
|
m_stack[0] = init_mat;
|
||||||
|
} else {
|
||||||
|
setIdentity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(__float x, __float y, __float z) {
|
||||||
|
mat4 m = getIdentity();
|
||||||
|
|
||||||
|
m[12] = x;
|
||||||
|
m[13] = y;
|
||||||
|
m[14] = z;
|
||||||
|
|
||||||
|
m_stack[c_stack] = mat4::multiply(m, m_stack[c_stack], true);
|
||||||
|
if (valid == c_stack && c_stack) {
|
||||||
|
valid--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scale(__float x, __float y, __float z) {
|
||||||
|
mat4 m = getIdentity();
|
||||||
|
|
||||||
|
m[0] = x;
|
||||||
|
m[5] = y;
|
||||||
|
m[10] = z;
|
||||||
|
|
||||||
|
m_stack[c_stack] = mat4::multiply(m, m_stack[c_stack], true);
|
||||||
|
if (valid == c_stack && c_stack) {
|
||||||
|
valid--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotate(__float ang, __float x, __float y, __float z) {
|
||||||
|
__float sAng, cAng;
|
||||||
|
|
||||||
|
if (x || y || z) {
|
||||||
|
sAng = sin(-ang * ((float)M_PI / 180.0f));
|
||||||
|
cAng = cos(-ang * ((float)M_PI / 180.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x) {
|
||||||
|
mat4 X_ROT = getIdentity();
|
||||||
|
|
||||||
|
X_ROT[5] = cAng * x;
|
||||||
|
X_ROT[9] = sAng * x;
|
||||||
|
X_ROT[6] = -sAng * x;
|
||||||
|
X_ROT[10] = cAng * x;
|
||||||
|
|
||||||
|
m_stack[c_stack] = mat4::multiply(m_stack[c_stack], X_ROT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y) {
|
||||||
|
mat4 Y_ROT = getIdentity();
|
||||||
|
|
||||||
|
Y_ROT[0] = cAng * y;
|
||||||
|
Y_ROT[8] = -sAng * y;
|
||||||
|
Y_ROT[2] = sAng * y;
|
||||||
|
Y_ROT[10] = cAng * y;
|
||||||
|
|
||||||
|
m_stack[c_stack] = mat4::multiply(m_stack[c_stack], Y_ROT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z) {
|
||||||
|
mat4 Z_ROT = getIdentity();
|
||||||
|
|
||||||
|
Z_ROT[0] = cAng * z;
|
||||||
|
Z_ROT[4] = sAng * z;
|
||||||
|
Z_ROT[1] = -sAng * z;
|
||||||
|
Z_ROT[5] = cAng * z;
|
||||||
|
|
||||||
|
m_stack[c_stack] = mat4::multiply(m_stack[c_stack], Z_ROT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid == c_stack && c_stack) {
|
||||||
|
valid--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__Transform__) */
|
40
external/cubicvr2/math/triangle.h
vendored
Normal file
40
external/cubicvr2/math/triangle.h
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// triangle.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__triangle__
|
||||||
|
#define __CubicVR2__triangle__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
struct triangle {
|
||||||
|
static vec3 normal(vec3 pt1, vec3 pt2, vec3 pt3) {
|
||||||
|
|
||||||
|
__float v10 = pt1[0] - pt2[0];
|
||||||
|
__float v11 = pt1[1] - pt2[1];
|
||||||
|
__float v12 = pt1[2] - pt2[2];
|
||||||
|
__float v20 = pt2[0] - pt3[0];
|
||||||
|
__float v21 = pt2[1] - pt3[1];
|
||||||
|
__float v22 = pt2[2] - pt3[2];
|
||||||
|
|
||||||
|
vec3 mOut;
|
||||||
|
|
||||||
|
mOut[0] = v11 * v22 - v12 * v21;
|
||||||
|
mOut[1] = v12 * v20 - v10 * v22;
|
||||||
|
mOut[2] = v10 * v21 - v11 * v20;
|
||||||
|
|
||||||
|
return mOut;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__triangle__) */
|
92
external/cubicvr2/math/vec2.h
vendored
Normal file
92
external/cubicvr2/math/vec2.h
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// vec2.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__vec2__
|
||||||
|
#define __CubicVR2__vec2__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
#include "cubic_types.h"
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
#define vec2SG(c,x,y) \
|
||||||
|
vec2 COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(vec2 value) { y = value; return *this; }
|
||||||
|
|
||||||
|
struct vec2 {
|
||||||
|
__float x, y;
|
||||||
|
public:
|
||||||
|
__float& u() { return x; }
|
||||||
|
__float& v() { return y; }
|
||||||
|
|
||||||
|
// __float operator [] (unsigned i) const { return ((__float *)this)[i]; }
|
||||||
|
__float& operator [] (unsigned i) { return ((__float *)this)[i]; }
|
||||||
|
|
||||||
|
vec2 (__float xi,__float yi) { x = xi; y = yi; }
|
||||||
|
vec2 () { x = y = 0.0f; }
|
||||||
|
|
||||||
|
operator __float*() const { return (__float *)this; }
|
||||||
|
|
||||||
|
vec2 operator*(__float v) { return vec2( x*v, y*v ); }
|
||||||
|
// vec2 operator*(vec2 v) { return vec2::cross(*this,v); }
|
||||||
|
vec2 operator+(vec2 v) { return vec2::add(*this,v); }
|
||||||
|
vec2 operator-(vec2 v) { return vec2::subtract(*this,v); }
|
||||||
|
|
||||||
|
|
||||||
|
static bool equal(vec2 a, vec2 b, __float epsilon = 0.00000001) {
|
||||||
|
return (fabs(a[0] - b[0]) < epsilon && fabs(a[1] - b[1]) < epsilon);
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool onLine(vec2 a, vec2 b,vec2 c) {
|
||||||
|
__float minx = (a[0]<b[0])?a[0]:b[0];
|
||||||
|
__float miny = (a[1]<b[1])?a[1]:b[1];
|
||||||
|
__float maxx = (a[0]>b[0])?a[0]:b[0];
|
||||||
|
__float maxy = (a[1]>b[1])?a[1]:b[1];
|
||||||
|
|
||||||
|
if ((minx <= c[0] && c[0] <= maxx) && (miny <= c[1] && c[1] <= maxy)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec2 lineIntersect(vec2 a1, vec2 a2, vec2 b1, vec2 b2) {
|
||||||
|
__float x1 = a1[0], y1 = a1[1], x2 = a2[0], y2 = a2[1];
|
||||||
|
__float x3 = b1[0], y3 = b1[1], x4 = b2[0], y4 = b2[1];
|
||||||
|
|
||||||
|
__float d = ((x1-x2) * (y3-y4)) - ((y1-y2) * (x3-x4));
|
||||||
|
if (d == 0) return vec2(INFINITY,INFINITY);
|
||||||
|
|
||||||
|
__float xi = (((x3-x4) * ((x1*y2)-(y1*x2))) - ((x1-x2) *((x3*y4)-(y3*x4))))/d;
|
||||||
|
__float yi = (((y3-y4) * ((x1*y2)-(y1*x2))) - ((y1-y2) *((x3*y4)-(y3*x4))))/d;
|
||||||
|
|
||||||
|
return vec2( xi,yi );
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec2 add(vec2 a,vec2 b) {
|
||||||
|
return vec2(a[0]+b[0],a[1]+b[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec2 subtract(vec2 a, vec2 b) {
|
||||||
|
return vec2(a[0]-b[0],a[1]-b[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static __float length(vec2 a,vec2 b) {
|
||||||
|
vec2 s(a[0]-b[0],a[1]-b[1]);
|
||||||
|
|
||||||
|
return sqrtf(s[0]*s[0]+s[1]*s[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static __float length(vec2 a) {
|
||||||
|
return sqrtf(a[0]*a[0]+a[1]*a[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* defined(__CubicVR2__vec2__) */
|
170
external/cubicvr2/math/vec3.h
vendored
Normal file
170
external/cubicvr2/math/vec3.h
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
//
|
||||||
|
// vec3.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-21.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__vec3__
|
||||||
|
#define __CubicVR2__vec3__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "cubic_types.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
#define vec3SG(c,x,y) \
|
||||||
|
vec3 COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(vec3 value) { y = value; return *this; }
|
||||||
|
|
||||||
|
|
||||||
|
struct vec3 {
|
||||||
|
__float x,y,z;
|
||||||
|
|
||||||
|
operator __float*() const { return (__float *)this; }
|
||||||
|
|
||||||
|
__float& r() { return x; }
|
||||||
|
__float& g() { return y; }
|
||||||
|
__float& b() { return z; }
|
||||||
|
|
||||||
|
__float& operator [] (unsigned i) { return ((__float *)this)[i]; }
|
||||||
|
vec3 (__float xi,__float yi,__float zi) { x = xi; y = yi; z = zi; }
|
||||||
|
vec3 () { x = y = z = 0.0f; }
|
||||||
|
|
||||||
|
|
||||||
|
vec3 operator*(__float v) { return vec3(x*v, y*v, z*v); }
|
||||||
|
vec3 operator*(vec3 v) { return vec3::cross(*this,v); }
|
||||||
|
vec3 operator+(vec3 v) { return vec3::add(*this,v); }
|
||||||
|
vec3 operator-(vec3 v) { return vec3::subtract(*this,v); }
|
||||||
|
|
||||||
|
|
||||||
|
static __float length(vec3 pta, vec3 ptb) {
|
||||||
|
__float a,b,c;
|
||||||
|
a = ptb[0]-pta[0];
|
||||||
|
b = ptb[1]-pta[1];
|
||||||
|
c = ptb[2]-pta[2];
|
||||||
|
return sqrtf((a*a) + (b*b) + (c*c));
|
||||||
|
};
|
||||||
|
static __float length(vec3 pta) {
|
||||||
|
__float a,b,c;
|
||||||
|
a = pta[0];
|
||||||
|
b = pta[1];
|
||||||
|
c = pta[2];
|
||||||
|
return sqrtf((a*a) + (b*b) + (c*c));
|
||||||
|
};
|
||||||
|
static vec3 normalize(vec3 pt) {
|
||||||
|
__float a = pt[0], b = pt[1], c = pt[2],
|
||||||
|
d = sqrtf((a*a) + (b*b) + (c*c));
|
||||||
|
if (d) {
|
||||||
|
pt[0] = pt[0]/d;
|
||||||
|
pt[1] = pt[1]/d;
|
||||||
|
pt[2] = pt[2]/d;
|
||||||
|
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt = vec3(0.0f,0.0f,0.0f);
|
||||||
|
|
||||||
|
return pt;
|
||||||
|
};
|
||||||
|
static __float dot(vec3 v1, vec3 v2) {
|
||||||
|
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||||
|
};
|
||||||
|
static __float angle(vec3 v1, vec3 v2) {
|
||||||
|
__float a = acosf((v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) / (sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]) * sqrtf(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2])));
|
||||||
|
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
static vec3 cross(vec3 vectA, vec3 vectB) {
|
||||||
|
return vec3(
|
||||||
|
vectA[1] * vectB[2] - vectB[1] * vectA[2], vectA[2] * vectB[0] - vectB[2] * vectA[0], vectA[0] * vectB[1] - vectB[0] * vectA[1]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
static vec3 multiply(vec3 vectA, __float constB) {
|
||||||
|
return vec3(vectA[0] * constB, vectA[1] * constB, vectA[2] * constB);
|
||||||
|
};
|
||||||
|
static vec3 add(vec3 vectA, vec3 vectB) {
|
||||||
|
return vec3(vectA[0] + vectB[0], vectA[1] + vectB[1], vectA[2] + vectB[2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 subtract(vec3 vectA, vec3 vectB) {
|
||||||
|
return vec3(vectA[0] - vectB[0], vectA[1] - vectB[1], vectA[2] - vectB[2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool equal(vec3 a, vec3 b, __float epsilon = 0.0000001f) {
|
||||||
|
return ((fabs(a[0] - b[0]) < epsilon) && (fabs(a[1] - b[1]) < epsilon) && (fabs(a[2] - b[2]) < epsilon));
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 moveViewRelative(vec3 position, vec3 target, __float xdelta, __float zdelta) {
|
||||||
|
__float ang = atan2f(zdelta, xdelta);
|
||||||
|
__float cam_ang = atan2f(target[2] - position[2], target[0] - position[0]);
|
||||||
|
__float mag = sqrtf(xdelta * xdelta + zdelta * zdelta);
|
||||||
|
|
||||||
|
__float move_ang = cam_ang + ang + (float)M_PI/2.0f;
|
||||||
|
|
||||||
|
// if (typeof(alt_source) === 'object') {
|
||||||
|
// return [alt_source[0] + mag * Math.cos(move_ang), alt_source[1], alt_source[2] + mag * Math.sin(move_ang)];
|
||||||
|
// }
|
||||||
|
|
||||||
|
return vec3(position[0] + mag * cosf(move_ang), position[1], position[2] + mag * sinf(move_ang));
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 trackTarget(vec3 position, vec3 target, __float trackingSpeed, __float safeDistance) {
|
||||||
|
vec3 camv = vec3::subtract(target, position);
|
||||||
|
vec3 dist = camv;
|
||||||
|
__float fdist = vec3::length(dist);
|
||||||
|
vec3 motionv = camv;
|
||||||
|
|
||||||
|
motionv = vec3::normalize(motionv);
|
||||||
|
motionv = vec3::multiply(motionv, trackingSpeed * (1.0f / (1.0f / (fdist - safeDistance))));
|
||||||
|
|
||||||
|
vec3 ret_pos;
|
||||||
|
|
||||||
|
if (fdist > safeDistance) {
|
||||||
|
ret_pos = vec3::add(position, motionv);
|
||||||
|
} else if (fdist < safeDistance) {
|
||||||
|
motionv = camv;
|
||||||
|
motionv = vec3::normalize(motionv);
|
||||||
|
motionv = vec3::multiply(motionv, trackingSpeed * (1.0f / (1.0f / (fabsf(fdist - safeDistance)))));
|
||||||
|
ret_pos = vec3::subtract(position, motionv);
|
||||||
|
} else {
|
||||||
|
ret_pos = vec3(position[0], position[1] + motionv[2], position[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec3 getClosestTo(vec3 ptA, vec3 ptB, vec3 ptTest) {
|
||||||
|
vec3 S, T, U;
|
||||||
|
|
||||||
|
S = vec3::subtract(ptB, ptA);
|
||||||
|
T = vec3::subtract(ptTest, ptA);
|
||||||
|
U = vec3::add(vec3::multiply(S, vec3::dot(S, T) / vec3::dot(S, S)), ptA);
|
||||||
|
|
||||||
|
return U;
|
||||||
|
};
|
||||||
|
|
||||||
|
// linePlaneIntersect: function(normal, point_on_plane, segment_start, segment_end)
|
||||||
|
// {
|
||||||
|
// // form a plane from normal and point_on_plane and test segment start->end to find intersect point
|
||||||
|
// var denom,mu;
|
||||||
|
//
|
||||||
|
// var d = - normal[0] * point_on_plane[0] - normal[1] * point_on_plane[1] - normal[2] * point_on_plane[2];
|
||||||
|
//
|
||||||
|
// // calculate position where the plane intersects the segment
|
||||||
|
// denom = normal[0] * (segment_end[0] - segment_start[0]) + normal[1] * (segment_end[1] - segment_start[1]) + normal[2] * (segment_end[2] - segment_start[2]);
|
||||||
|
// if (Math.fabs(denom) < 0.001) return false;
|
||||||
|
//
|
||||||
|
// mu = - (d + normal[0] * segment_start[0] + normal[1] * segment_start[1] + normal[2] * segment_start[2]) / denom;
|
||||||
|
// return [
|
||||||
|
// (segment_start[0] + mu * (segment_end[0] - segment_start[0])),
|
||||||
|
// (segment_start[1] + mu * (segment_end[1] - segment_start[1])),
|
||||||
|
// (segment_start[2] + mu * (segment_end[2] - segment_start[2]))
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* defined(__CubicVR2__vec3__) */
|
71
external/cubicvr2/math/vec4.h
vendored
Normal file
71
external/cubicvr2/math/vec4.h
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// vec4.h
|
||||||
|
// CubicVR2
|
||||||
|
//
|
||||||
|
// Created by Charles J. Cliffe on 2013-02-22.
|
||||||
|
// Copyright (c) 2013 Charles J. Cliffe. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CubicVR2__vec4__
|
||||||
|
#define __CubicVR2__vec4__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "cubic_types.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace CubicVR {
|
||||||
|
|
||||||
|
#define vec4SG(c,x,y) \
|
||||||
|
vec3 COMBINE(get,x)() { return y; } \
|
||||||
|
c & COMBINE(set,x)(vec3 value) { y = value; return *this; }
|
||||||
|
|
||||||
|
struct vec4 {
|
||||||
|
__float x,y,z,w;
|
||||||
|
public:
|
||||||
|
__float& r() { return x; }
|
||||||
|
__float& g() { return y; }
|
||||||
|
__float& b() { return z; }
|
||||||
|
__float& a() { return w; }
|
||||||
|
|
||||||
|
// __float operator [] (unsigned i) const { return ((__float *)this)[i]; }
|
||||||
|
__float& operator [] (unsigned i) { return ((__float *)this)[i]; }
|
||||||
|
|
||||||
|
vec4 (__float xi,__float yi,__float zi,__float wi) { x = xi; y = yi; z = zi; w = wi; }
|
||||||
|
vec4 () { x = y = z = w = 0.0f; }
|
||||||
|
|
||||||
|
operator __float*() const { return (__float *)this; }
|
||||||
|
|
||||||
|
vec4 operator*(__float v) { return vec4(x*v, y*v, z*v, w*v); }
|
||||||
|
// vec4 operator*(vec4 v) { return vec4::cross(*this,v); }
|
||||||
|
// vec4 operator+(vec4 v) { return vec4::add(*this,v); }
|
||||||
|
// vec4 operator-(vec4 v) { return vec4::subtract(*this,v); }
|
||||||
|
|
||||||
|
static __float length(vec4 a, vec4 b) {
|
||||||
|
__float v[4] = {a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]};
|
||||||
|
return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static __float length(vec4 v) {
|
||||||
|
return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static vec4 normalize(vec4 v) {
|
||||||
|
__float n = sqrtf(vec4::length(v));
|
||||||
|
|
||||||
|
v[0] /= n;
|
||||||
|
v[1] /= n;
|
||||||
|
v[2] /= n;
|
||||||
|
v[3] /= n;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
static __float dot(vec4 v1, vec4 v2) {
|
||||||
|
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(__CubicVR2__vec4__) */
|
4
external/rtaudio/RtAudio.cpp
vendored
4
external/rtaudio/RtAudio.cpp
vendored
@ -10051,8 +10051,8 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
|
|||||||
|
|
||||||
void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
|
void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
|
||||||
{
|
{
|
||||||
register char val;
|
char val;
|
||||||
register char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
if ( format == RTAUDIO_SINT16 ) {
|
if ( format == RTAUDIO_SINT16 ) {
|
||||||
|
@ -147,6 +147,12 @@ AppFrame::AppFrame() :
|
|||||||
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
|
spectrumCanvas->attachWaterfallCanvas(waterfallCanvas);
|
||||||
vbox->Add(waterfallCanvas, 20, wxEXPAND | wxALL, 0);
|
vbox->Add(waterfallCanvas, 20, wxEXPAND | wxALL, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
vbox->AddSpacer(1);
|
||||||
|
testCanvas = new UITestCanvas(this, attribList);
|
||||||
|
vbox->Add(testCanvas, 20, wxEXPAND | wxALL, 0);
|
||||||
|
// */
|
||||||
|
|
||||||
this->SetSizer(vbox);
|
this->SetSizer(vbox);
|
||||||
|
|
||||||
// waterfallCanvas->SetFocusFromKbd();
|
// waterfallCanvas->SetFocusFromKbd();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "MeterCanvas.h"
|
#include "MeterCanvas.h"
|
||||||
#include "TuningCanvas.h"
|
#include "TuningCanvas.h"
|
||||||
#include "ModeSelectorCanvas.h"
|
#include "ModeSelectorCanvas.h"
|
||||||
|
#include "UITestCanvas.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -81,6 +82,7 @@ private:
|
|||||||
MeterCanvas *demodSignalMeter;
|
MeterCanvas *demodSignalMeter;
|
||||||
MeterCanvas *demodGainMeter;
|
MeterCanvas *demodGainMeter;
|
||||||
TuningCanvas *demodTuner;
|
TuningCanvas *demodTuner;
|
||||||
|
UITestCanvas *testCanvas;
|
||||||
|
|
||||||
DemodulatorInstance *activeDemodulator;
|
DemodulatorInstance *activeDemodulator;
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ class outbuf : public std::streambuf {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), directSamplingMode(0),
|
||||||
|
sdrThread(NULL), sdrPostThread(NULL), pipeSDRCommand(NULL), pipeSDRIQData(NULL), pipeIQVisualData(NULL), pipeAudioVisualData(NULL), t_SDR(NULL), t_PostSDR(NULL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool CubicSDR::OnInit() {
|
bool CubicSDR::OnInit() {
|
||||||
#ifdef _OSX_APP_
|
#ifdef _OSX_APP_
|
||||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||||
@ -68,22 +74,25 @@ bool CubicSDR::OnInit() {
|
|||||||
ppm = 0;
|
ppm = 0;
|
||||||
directSamplingMode = 0;
|
directSamplingMode = 0;
|
||||||
|
|
||||||
audioVisualQueue = new DemodulatorThreadOutputQueue();
|
// Visual Data
|
||||||
audioVisualQueue->set_max_num_items(1);
|
pipeIQVisualData = new DemodulatorThreadInputQueue();
|
||||||
|
pipeIQVisualData->set_max_num_items(1);
|
||||||
|
|
||||||
threadCmdQueueSDR = new SDRThreadCommandQueue;
|
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
||||||
sdrThread = new SDRThread(threadCmdQueueSDR);
|
pipeAudioVisualData->set_max_num_items(1);
|
||||||
|
|
||||||
|
// I/Q Data
|
||||||
|
pipeSDRIQData = new SDRThreadIQDataQueue;
|
||||||
|
pipeSDRCommand = new SDRThreadCommandQueue();
|
||||||
|
|
||||||
|
sdrThread = new SDRThread();
|
||||||
|
sdrThread->setInputQueue("SDRCommandQueue",pipeSDRCommand);
|
||||||
|
sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData);
|
||||||
|
|
||||||
sdrPostThread = new SDRPostThread();
|
sdrPostThread = new SDRPostThread();
|
||||||
sdrPostThread->setNumVisSamples(16384 * 2);
|
sdrPostThread->setNumVisSamples(16384 * 2);
|
||||||
|
sdrPostThread->setInputQueue("IQDataInput", pipeSDRIQData);
|
||||||
iqPostDataQueue = new SDRThreadIQDataQueue;
|
sdrPostThread->setOutputQueue("IQVisualDataOut", pipeIQVisualData);
|
||||||
iqVisualQueue = new DemodulatorThreadInputQueue;
|
|
||||||
iqVisualQueue->set_max_num_items(1);
|
|
||||||
|
|
||||||
sdrThread->setIQDataOutQueue(iqPostDataQueue);
|
|
||||||
sdrPostThread->setIQDataInQueue(iqPostDataQueue);
|
|
||||||
sdrPostThread->setIQVisualQueue(iqVisualQueue);
|
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
std::vector<SDRDeviceInfo *>::iterator devs_i;
|
||||||
|
|
||||||
@ -167,11 +176,11 @@ int CubicSDR::OnExit() {
|
|||||||
delete sdrPostThread;
|
delete sdrPostThread;
|
||||||
delete t_PostSDR;
|
delete t_PostSDR;
|
||||||
|
|
||||||
delete threadCmdQueueSDR;
|
delete pipeSDRCommand;
|
||||||
|
|
||||||
delete iqVisualQueue;
|
delete pipeIQVisualData;
|
||||||
delete audioVisualQueue;
|
delete pipeAudioVisualData;
|
||||||
delete iqPostDataQueue;
|
delete pipeSDRIQData;
|
||||||
|
|
||||||
delete m_glContext;
|
delete m_glContext;
|
||||||
|
|
||||||
@ -217,7 +226,7 @@ void CubicSDR::setFrequency(long long freq) {
|
|||||||
frequency = freq;
|
frequency = freq;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE);
|
||||||
command.llong_value = freq;
|
command.llong_value = freq;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
long long CubicSDR::getOffset() {
|
long long CubicSDR::getOffset() {
|
||||||
@ -228,7 +237,7 @@ void CubicSDR::setOffset(long long ofs) {
|
|||||||
offset = ofs;
|
offset = ofs;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET);
|
||||||
command.llong_value = ofs;
|
command.llong_value = ofs;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||||
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
config.getDevice(dev->getDeviceId())->setOffset(ofs);
|
||||||
@ -238,7 +247,7 @@ void CubicSDR::setDirectSampling(int mode) {
|
|||||||
directSamplingMode = mode;
|
directSamplingMode = mode;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING);
|
||||||
command.llong_value = mode;
|
command.llong_value = mode;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||||
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
|
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
|
||||||
@ -263,11 +272,11 @@ long long CubicSDR::getFrequency() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
||||||
return audioVisualQueue;
|
return pipeAudioVisualData;
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorThreadInputQueue* CubicSDR::getIQVisualQueue() {
|
DemodulatorThreadInputQueue* CubicSDR::getIQVisualQueue() {
|
||||||
return iqVisualQueue;
|
return pipeIQVisualData;
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorMgr &CubicSDR::getDemodMgr() {
|
DemodulatorMgr &CubicSDR::getDemodMgr() {
|
||||||
@ -285,7 +294,7 @@ void CubicSDR::setSampleRate(long long rate_in) {
|
|||||||
sampleRate = rate_in;
|
sampleRate = rate_in;
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE);
|
||||||
command.llong_value = rate_in;
|
command.llong_value = rate_in;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
setFrequency(frequency);
|
setFrequency(frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +318,7 @@ void CubicSDR::setDevice(int deviceId) {
|
|||||||
sdrThread->setDeviceId(deviceId);
|
sdrThread->setDeviceId(deviceId);
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE);
|
||||||
command.llong_value = deviceId;
|
command.llong_value = deviceId;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[deviceId];
|
SDRDeviceInfo *dev = (*getDevices())[deviceId];
|
||||||
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
|
||||||
@ -340,7 +349,7 @@ void CubicSDR::setPPM(int ppm_in) {
|
|||||||
|
|
||||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_PPM);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_PPM);
|
||||||
command.llong_value = ppm;
|
command.llong_value = ppm;
|
||||||
threadCmdQueueSDR->push(command);
|
pipeSDRCommand->push(command);
|
||||||
|
|
||||||
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
|
||||||
|
|
||||||
|
@ -23,10 +23,7 @@
|
|||||||
|
|
||||||
class CubicSDR: public wxApp {
|
class CubicSDR: public wxApp {
|
||||||
public:
|
public:
|
||||||
CubicSDR() :
|
CubicSDR();
|
||||||
appframe(NULL), m_glContext(NULL), frequency(0), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE), offset(0), snap(1), directSamplingMode(0), ppm(0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PrimaryGLContext &GetContext(wxGLCanvas *canvas);
|
PrimaryGLContext &GetContext(wxGLCanvas *canvas);
|
||||||
|
|
||||||
@ -90,10 +87,10 @@ private:
|
|||||||
SDRThread *sdrThread;
|
SDRThread *sdrThread;
|
||||||
SDRPostThread *sdrPostThread;
|
SDRPostThread *sdrPostThread;
|
||||||
|
|
||||||
SDRThreadCommandQueue* threadCmdQueueSDR;
|
SDRThreadCommandQueue* pipeSDRCommand;
|
||||||
SDRThreadIQDataQueue* iqPostDataQueue;
|
SDRThreadIQDataQueue* pipeSDRIQData;
|
||||||
DemodulatorThreadInputQueue* iqVisualQueue;
|
DemodulatorThreadInputQueue* pipeIQVisualData;
|
||||||
DemodulatorThreadOutputQueue* audioVisualQueue;
|
DemodulatorThreadOutputQueue* pipeAudioVisualData;
|
||||||
|
|
||||||
std::thread *t_SDR;
|
std::thread *t_SDR;
|
||||||
std::thread *t_PostSDR;
|
std::thread *t_PostSDR;
|
||||||
|
@ -33,24 +33,3 @@ const char filePathSeparator =
|
|||||||
#define DEFAULT_DEMOD_TYPE 1
|
#define DEFAULT_DEMOD_TYPE 1
|
||||||
#define DEFAULT_DEMOD_BW 200000
|
#define DEFAULT_DEMOD_BW 200000
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
class ReferenceCounter {
|
|
||||||
public:
|
|
||||||
mutable std::mutex m_mutex;
|
|
||||||
|
|
||||||
void setRefCount(int rc) {
|
|
||||||
refCount.store(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void decRefCount() {
|
|
||||||
refCount.store(refCount.load()-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getRefCount() {
|
|
||||||
return refCount.load();
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
std::atomic_int refCount;
|
|
||||||
};
|
|
||||||
|
68
src/IOThread.cpp
Normal file
68
src/IOThread.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "IOThread.h"
|
||||||
|
|
||||||
|
IOThread::IOThread() {
|
||||||
|
terminated.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOThread::~IOThread() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void *IOThread::threadMain() {
|
||||||
|
terminated.store(false);
|
||||||
|
run();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *IOThread::pthread_helper(void *context) {
|
||||||
|
return ((IOThread *) context)->threadMain();
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
void IOThread::threadMain() {
|
||||||
|
terminated.store(false);
|
||||||
|
run();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void IOThread::setup() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::run() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::terminate() {
|
||||||
|
terminated.store(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::onBindOutput(std::string name, ThreadQueueBase* threadQueue) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::onBindInput(std::string name, ThreadQueueBase* threadQueue) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) {
|
||||||
|
input_queues[qname] = threadQueue;
|
||||||
|
this->onBindInput(qname, threadQueue);
|
||||||
|
};
|
||||||
|
|
||||||
|
void *IOThread::getInputQueue(std::string qname) {
|
||||||
|
return input_queues[qname];
|
||||||
|
};
|
||||||
|
|
||||||
|
void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) {
|
||||||
|
output_queues[qname] = threadQueue;
|
||||||
|
this->onBindOutput(qname, threadQueue);
|
||||||
|
};
|
||||||
|
|
||||||
|
void *IOThread::getOutputQueue(std::string qname) {
|
||||||
|
return output_queues[qname];
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IOThread::isTerminated() {
|
||||||
|
return terminated.load();
|
||||||
|
}
|
101
src/IOThread.h
Normal file
101
src/IOThread.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
|
||||||
|
struct map_string_less : public std::binary_function<std::string,std::string,bool>
|
||||||
|
{
|
||||||
|
bool operator()(const std::string& a,const std::string& b) const
|
||||||
|
{
|
||||||
|
return a.compare(b) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ReferenceCounter {
|
||||||
|
public:
|
||||||
|
mutable std::mutex m_mutex;
|
||||||
|
|
||||||
|
void setRefCount(int rc) {
|
||||||
|
refCount.store(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void decRefCount() {
|
||||||
|
refCount.store(refCount.load()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRefCount() {
|
||||||
|
return refCount.load();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
std::atomic_int refCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class BufferType = ReferenceCounter>
|
||||||
|
class ReBuffer {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BufferType *getBuffer() {
|
||||||
|
BufferType* buf = NULL;
|
||||||
|
for (outputBuffersI = outputBuffers.begin(); outputBuffersI != outputBuffers.end(); outputBuffersI++) {
|
||||||
|
if ((*outputBuffersI)->getRefCount() <= 0) {
|
||||||
|
return (*outputBuffersI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = new BufferType();
|
||||||
|
outputBuffers.push_back(buf);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void purge() {
|
||||||
|
while (!outputBuffers.empty()) {
|
||||||
|
BufferType *ref = outputBuffers.front();
|
||||||
|
outputBuffers.pop_front();
|
||||||
|
delete ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::deque<BufferType*> outputBuffers;
|
||||||
|
typename std::deque<BufferType*>::iterator outputBuffersI;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class IOThread {
|
||||||
|
public:
|
||||||
|
IOThread();
|
||||||
|
virtual ~IOThread();
|
||||||
|
|
||||||
|
static void *pthread_helper(void *context);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
virtual void *threadMain();
|
||||||
|
#else
|
||||||
|
virtual void threadMain();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual void setup();
|
||||||
|
virtual void run();
|
||||||
|
virtual void terminate();
|
||||||
|
bool isTerminated();
|
||||||
|
virtual void onBindOutput(std::string name, ThreadQueueBase* threadQueue);
|
||||||
|
virtual void onBindInput(std::string name, ThreadQueueBase* threadQueue);
|
||||||
|
|
||||||
|
void setInputQueue(std::string qname, ThreadQueueBase *threadQueue);
|
||||||
|
void *getInputQueue(std::string qname);
|
||||||
|
void setOutputQueue(std::string qname, ThreadQueueBase *threadQueue);
|
||||||
|
void *getOutputQueue(std::string qname);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::map<std::string, ThreadQueueBase *, map_string_less> input_queues;
|
||||||
|
std::map<std::string, ThreadQueueBase *, map_string_less> output_queues;
|
||||||
|
std::atomic_bool terminated;
|
||||||
|
};
|
@ -11,13 +11,12 @@ std::map<int, AudioThread *> AudioThread::deviceController;
|
|||||||
std::map<int, int> AudioThread::deviceSampleRate;
|
std::map<int, int> AudioThread::deviceSampleRate;
|
||||||
std::map<int, std::thread *> AudioThread::deviceThread;
|
std::map<int, std::thread *> AudioThread::deviceThread;
|
||||||
|
|
||||||
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) :
|
AudioThread::AudioThread() : IOThread(),
|
||||||
currentInput(NULL), inputQueue(inputQueue), gain(
|
currentInput(NULL), inputQueue(NULL), gain(
|
||||||
1.0), threadQueueNotify(threadQueueNotify), sampleRate(0), nBufferFrames(1024) {
|
1.0), threadQueueNotify(NULL), sampleRate(0), nBufferFrames(1024) {
|
||||||
|
|
||||||
audioQueuePtr.store(0);
|
audioQueuePtr.store(0);
|
||||||
underflowCount.store(0);
|
underflowCount.store(0);
|
||||||
terminated.store(false);
|
|
||||||
active.store(false);
|
active.store(false);
|
||||||
outputDevice.store(-1);
|
outputDevice.store(-1);
|
||||||
|
|
||||||
@ -56,7 +55,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
float *out = (float*) outputBuffer;
|
float *out = (float*) outputBuffer;
|
||||||
memset(out, 0, nBufferFrames * 2 * sizeof(float));
|
memset(out, 0, nBufferFrames * 2 * sizeof(float));
|
||||||
|
|
||||||
if (src->terminated) {
|
if (src->isTerminated()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,17 +71,17 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
|
|
||||||
for (int j = 0; j < src->boundThreads.load()->size(); j++) {
|
for (int j = 0; j < src->boundThreads.load()->size(); j++) {
|
||||||
AudioThread *srcmix = (*(src->boundThreads.load()))[j];
|
AudioThread *srcmix = (*(src->boundThreads.load()))[j];
|
||||||
if (srcmix->terminated || !srcmix->inputQueue || srcmix->inputQueue->empty() || !srcmix->isActive()) {
|
if (srcmix->isTerminated() || !srcmix->inputQueue || srcmix->inputQueue->empty() || !srcmix->isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srcmix->currentInput) {
|
if (!srcmix->currentInput) {
|
||||||
srcmix->audioQueuePtr = 0;
|
srcmix->audioQueuePtr = 0;
|
||||||
if (srcmix->terminated || srcmix->inputQueue->empty()) {
|
if (srcmix->isTerminated() || srcmix->inputQueue->empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
srcmix->inputQueue->pop(srcmix->currentInput);
|
srcmix->inputQueue->pop(srcmix->currentInput);
|
||||||
if (srcmix->terminated) {
|
if (srcmix->isTerminated()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -117,11 +116,11 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
srcmix->currentInput->decRefCount();
|
srcmix->currentInput->decRefCount();
|
||||||
srcmix->currentInput = NULL;
|
srcmix->currentInput = NULL;
|
||||||
}
|
}
|
||||||
if (srcmix->terminated || srcmix->inputQueue->empty()) {
|
if (srcmix->isTerminated() || srcmix->inputQueue->empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
srcmix->inputQueue->pop(srcmix->currentInput);
|
srcmix->inputQueue->pop(srcmix->currentInput);
|
||||||
if (srcmix->terminated) {
|
if (srcmix->isTerminated()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,11 +137,11 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
srcmix->currentInput->decRefCount();
|
srcmix->currentInput->decRefCount();
|
||||||
srcmix->currentInput = NULL;
|
srcmix->currentInput = NULL;
|
||||||
}
|
}
|
||||||
if (srcmix->terminated || srcmix->inputQueue->empty()) {
|
if (srcmix->isTerminated() || srcmix->inputQueue->empty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
srcmix->inputQueue->pop(srcmix->currentInput);
|
srcmix->inputQueue->pop(srcmix->currentInput);
|
||||||
if (srcmix->terminated) {
|
if (srcmix->isTerminated()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
float srcPeak = srcmix->currentInput->peak * srcmix->gain;
|
float srcPeak = srcmix->currentInput->peak * srcmix->gain;
|
||||||
@ -165,11 +164,11 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
srcmix->currentInput->decRefCount();
|
srcmix->currentInput->decRefCount();
|
||||||
srcmix->currentInput = NULL;
|
srcmix->currentInput = NULL;
|
||||||
}
|
}
|
||||||
if (srcmix->terminated || srcmix->inputQueue->empty()) {
|
if (srcmix->isTerminated() || srcmix->inputQueue->empty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
srcmix->inputQueue->pop(srcmix->currentInput);
|
srcmix->inputQueue->pop(srcmix->currentInput);
|
||||||
if (srcmix->terminated) {
|
if (srcmix->isTerminated()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
float srcPeak = srcmix->currentInput->peak * srcmix->gain;
|
float srcPeak = srcmix->currentInput->peak * srcmix->gain;
|
||||||
@ -317,7 +316,7 @@ void AudioThread::setupDevice(int deviceId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deviceController.find(parameters.deviceId) == deviceController.end()) {
|
if (deviceController.find(parameters.deviceId) == deviceController.end()) {
|
||||||
deviceController[parameters.deviceId] = new AudioThread(NULL, NULL);
|
deviceController[parameters.deviceId] = new AudioThread();
|
||||||
|
|
||||||
deviceController[parameters.deviceId]->setInitOutputDevice(parameters.deviceId, sampleRate);
|
deviceController[parameters.deviceId]->setInitOutputDevice(parameters.deviceId, sampleRate);
|
||||||
deviceController[parameters.deviceId]->bindThread(this);
|
deviceController[parameters.deviceId]->bindThread(this);
|
||||||
@ -359,7 +358,7 @@ void AudioThread::setInitOutputDevice(int deviceId, int sampleRate) {
|
|||||||
this->sampleRate = sampleRate;
|
this->sampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioThread::threadMain() {
|
void AudioThread::run() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t tID = pthread_self(); // ID of this thread
|
pthread_t tID = pthread_self(); // ID of this thread
|
||||||
int priority = sched_get_priority_max( SCHED_RR) - 1;
|
int priority = sched_get_priority_max( SCHED_RR) - 1;
|
||||||
@ -378,7 +377,8 @@ void AudioThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "Audio thread started." << std::endl;
|
std::cout << "Audio thread started." << std::endl;
|
||||||
|
|
||||||
terminated = false;
|
inputQueue = (AudioThreadInputQueue *)getInputQueue("AudioDataInput");
|
||||||
|
threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
AudioThreadCommand command;
|
AudioThreadCommand command;
|
||||||
|
@ -47,20 +47,18 @@ public:
|
|||||||
typedef ThreadQueue<AudioThreadInput *> AudioThreadInputQueue;
|
typedef ThreadQueue<AudioThreadInput *> AudioThreadInputQueue;
|
||||||
typedef ThreadQueue<AudioThreadCommand> AudioThreadCommandQueue;
|
typedef ThreadQueue<AudioThreadCommand> AudioThreadCommandQueue;
|
||||||
|
|
||||||
class AudioThread {
|
class AudioThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AudioThreadInput *currentInput;
|
AudioThreadInput *currentInput;
|
||||||
AudioThreadInputQueue *inputQueue;
|
AudioThreadInputQueue *inputQueue;
|
||||||
std::atomic_uint audioQueuePtr;
|
std::atomic_uint audioQueuePtr;
|
||||||
std::atomic_uint underflowCount;
|
std::atomic_uint underflowCount;
|
||||||
std::atomic_bool terminated;
|
|
||||||
std::atomic_bool initialized;
|
std::atomic_bool initialized;
|
||||||
std::atomic_bool active;
|
std::atomic_bool active;
|
||||||
std::atomic_int outputDevice;
|
std::atomic_int outputDevice;
|
||||||
std::atomic<float> gain;
|
std::atomic<float> gain;
|
||||||
|
|
||||||
AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify);
|
AudioThread();
|
||||||
~AudioThread();
|
~AudioThread();
|
||||||
|
|
||||||
static void enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs);
|
static void enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs);
|
||||||
@ -70,7 +68,7 @@ public:
|
|||||||
int getOutputDevice();
|
int getOutputDevice();
|
||||||
void setSampleRate(int sampleRate);
|
void setSampleRate(int sampleRate);
|
||||||
int getSampleRate();
|
int getSampleRate();
|
||||||
void threadMain();
|
void run();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
bool isActive();
|
bool isActive();
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#define DEMOD_TYPE_QPSK 15
|
#define DEMOD_TYPE_QPSK 15
|
||||||
#define DEMOD_TYPE_RAW 16
|
#define DEMOD_TYPE_RAW 16
|
||||||
|
|
||||||
|
#include "IOThread.h"
|
||||||
|
|
||||||
class DemodulatorThread;
|
class DemodulatorThread;
|
||||||
class DemodulatorThreadCommand {
|
class DemodulatorThreadCommand {
|
||||||
public:
|
public:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "DemodulatorInstance.h"
|
#include "DemodulatorInstance.h"
|
||||||
|
|
||||||
DemodulatorInstance::DemodulatorInstance() :
|
DemodulatorInstance::DemodulatorInstance() :
|
||||||
t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), currentAudioGain(1.0) {
|
pipeIQInputData(NULL), demodulatorThread(NULL), t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) {
|
||||||
|
|
||||||
terminated.store(true);
|
terminated.store(true);
|
||||||
audioTerminated.store(true);
|
audioTerminated.store(true);
|
||||||
@ -19,20 +19,29 @@ DemodulatorInstance::DemodulatorInstance() :
|
|||||||
|
|
||||||
|
|
||||||
label = new std::string("Unnamed");
|
label = new std::string("Unnamed");
|
||||||
threadQueueDemod = new DemodulatorThreadInputQueue;
|
pipeIQInputData = new DemodulatorThreadInputQueue;
|
||||||
threadQueuePostDemod = new DemodulatorThreadPostInputQueue;
|
pipeIQDemodData = new DemodulatorThreadPostInputQueue;
|
||||||
threadQueueCommand = new DemodulatorThreadCommandQueue;
|
pipeDemodCommand = new DemodulatorThreadCommandQueue;
|
||||||
threadQueueNotify = new DemodulatorThreadCommandQueue;
|
pipeDemodNotify = new DemodulatorThreadCommandQueue;
|
||||||
threadQueueControl = new DemodulatorThreadControlCommandQueue;
|
|
||||||
|
|
||||||
demodulatorPreThread = new DemodulatorPreThread(threadQueueDemod, threadQueuePostDemod, threadQueueControl, threadQueueNotify);
|
demodulatorPreThread = new DemodulatorPreThread();
|
||||||
demodulatorPreThread->setCommandQueue(threadQueueCommand);
|
demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData);
|
||||||
demodulatorThread = new DemodulatorThread(threadQueuePostDemod, threadQueueControl, threadQueueNotify);
|
demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData);
|
||||||
|
demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
||||||
|
demodulatorPreThread->setInputQueue("CommandQueue",pipeDemodCommand);
|
||||||
|
|
||||||
audioInputQueue = new AudioThreadInputQueue;
|
audioInputQueue = new AudioThreadInputQueue;
|
||||||
audioThread = new AudioThread(audioInputQueue, threadQueueNotify);
|
threadQueueControl = new DemodulatorThreadControlCommandQueue;
|
||||||
|
|
||||||
demodulatorThread->setAudioOutputQueue(audioInputQueue);
|
demodulatorThread = new DemodulatorThread();
|
||||||
|
demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData);
|
||||||
|
demodulatorThread->setInputQueue("ControlQueue",threadQueueControl);
|
||||||
|
demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
||||||
|
demodulatorThread->setOutputQueue("AudioDataOutput", audioInputQueue);
|
||||||
|
|
||||||
|
audioThread = new AudioThread();
|
||||||
|
audioThread->setInputQueue("AudioDataInput", audioInputQueue);
|
||||||
|
audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
|
||||||
|
|
||||||
currentDemodType = demodulatorThread->getDemodulatorType();
|
currentDemodType = demodulatorThread->getDemodulatorType();
|
||||||
currentDemodCons = demodulatorThread->getDemodulatorCons();
|
currentDemodCons = demodulatorThread->getDemodulatorCons();
|
||||||
@ -42,16 +51,16 @@ DemodulatorInstance::~DemodulatorInstance() {
|
|||||||
delete audioThread;
|
delete audioThread;
|
||||||
delete demodulatorThread;
|
delete demodulatorThread;
|
||||||
delete demodulatorPreThread;
|
delete demodulatorPreThread;
|
||||||
delete threadQueueDemod;
|
delete pipeIQInputData;
|
||||||
delete threadQueuePostDemod;
|
delete pipeIQDemodData;
|
||||||
delete threadQueueCommand;
|
delete pipeDemodCommand;
|
||||||
delete threadQueueNotify;
|
delete pipeDemodNotify;
|
||||||
delete threadQueueControl;
|
delete threadQueueControl;
|
||||||
delete audioInputQueue;
|
delete audioInputQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
||||||
demodulatorThread->setVisualOutputQueue(tQueue);
|
demodulatorThread->setOutputQueue("AudioVisualOutput", tQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorInstance::run() {
|
void DemodulatorInstance::run() {
|
||||||
@ -106,7 +115,7 @@ void DemodulatorInstance::updateLabel(long long freq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorThreadCommandQueue *DemodulatorInstance::getCommandQueue() {
|
DemodulatorThreadCommandQueue *DemodulatorInstance::getCommandQueue() {
|
||||||
return threadQueueCommand;
|
return pipeDemodCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorInstance::terminate() {
|
void DemodulatorInstance::terminate() {
|
||||||
@ -132,9 +141,9 @@ void DemodulatorInstance::setLabel(std::string labelStr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DemodulatorInstance::isTerminated() {
|
bool DemodulatorInstance::isTerminated() {
|
||||||
while (!threadQueueNotify->empty()) {
|
while (!pipeDemodNotify->empty()) {
|
||||||
DemodulatorThreadCommand cmd;
|
DemodulatorThreadCommand cmd;
|
||||||
threadQueueNotify->pop(cmd);
|
pipeDemodNotify->pop(cmd);
|
||||||
|
|
||||||
switch (cmd.cmd) {
|
switch (cmd.cmd) {
|
||||||
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED:
|
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED:
|
||||||
@ -320,13 +329,13 @@ void DemodulatorInstance::setBandwidth(int bw) {
|
|||||||
currentBandwidth = bw;
|
currentBandwidth = bw;
|
||||||
checkBandwidth();
|
checkBandwidth();
|
||||||
demodulatorPreThread->getParams().bandwidth = currentBandwidth;
|
demodulatorPreThread->getParams().bandwidth = currentBandwidth;
|
||||||
} else if (demodulatorPreThread && threadQueueCommand) {
|
} else if (demodulatorPreThread && pipeDemodCommand) {
|
||||||
DemodulatorThreadCommand command;
|
DemodulatorThreadCommand command;
|
||||||
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH;
|
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH;
|
||||||
currentBandwidth = bw;
|
currentBandwidth = bw;
|
||||||
checkBandwidth();
|
checkBandwidth();
|
||||||
command.llong_value = currentBandwidth;
|
command.llong_value = currentBandwidth;
|
||||||
threadQueueCommand->push(command);
|
pipeDemodCommand->push(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,12 +353,12 @@ void DemodulatorInstance::setFrequency(long long freq) {
|
|||||||
if (!active) {
|
if (!active) {
|
||||||
currentFrequency = freq;
|
currentFrequency = freq;
|
||||||
demodulatorPreThread->getParams().frequency = currentFrequency;
|
demodulatorPreThread->getParams().frequency = currentFrequency;
|
||||||
} else if (demodulatorPreThread && threadQueueCommand) {
|
} else if (demodulatorPreThread && pipeDemodCommand) {
|
||||||
DemodulatorThreadCommand command;
|
DemodulatorThreadCommand command;
|
||||||
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY;
|
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY;
|
||||||
currentFrequency = freq;
|
currentFrequency = freq;
|
||||||
command.llong_value = freq;
|
command.llong_value = freq;
|
||||||
threadQueueCommand->push(command);
|
pipeDemodCommand->push(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,12 +374,12 @@ void DemodulatorInstance::setAudioSampleRate(int sampleRate) {
|
|||||||
if (terminated) {
|
if (terminated) {
|
||||||
currentAudioSampleRate = sampleRate;
|
currentAudioSampleRate = sampleRate;
|
||||||
demodulatorPreThread->getParams().audioSampleRate = sampleRate;
|
demodulatorPreThread->getParams().audioSampleRate = sampleRate;
|
||||||
} else if (demodulatorPreThread && threadQueueCommand) {
|
} else if (demodulatorPreThread && pipeDemodCommand) {
|
||||||
DemodulatorThreadCommand command;
|
DemodulatorThreadCommand command;
|
||||||
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_AUDIO_RATE;
|
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_AUDIO_RATE;
|
||||||
currentAudioSampleRate = sampleRate;
|
currentAudioSampleRate = sampleRate;
|
||||||
command.llong_value = sampleRate;
|
command.llong_value = sampleRate;
|
||||||
threadQueueCommand->push(command);
|
pipeDemodCommand->push(command);
|
||||||
}
|
}
|
||||||
if (currentDemodType == DEMOD_TYPE_RAW) {
|
if (currentDemodType == DEMOD_TYPE_RAW) {
|
||||||
setBandwidth(currentAudioSampleRate);
|
setBandwidth(currentAudioSampleRate);
|
||||||
@ -420,3 +429,7 @@ bool DemodulatorInstance::isTracking() {
|
|||||||
void DemodulatorInstance::setTracking(bool tracking) {
|
void DemodulatorInstance::setTracking(bool tracking) {
|
||||||
this->tracking = tracking;
|
this->tracking = tracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DemodulatorThreadInputQueue *DemodulatorInstance::getIQInputDataPipe() {
|
||||||
|
return pipeIQInputData;
|
||||||
|
}
|
||||||
|
@ -10,14 +10,6 @@
|
|||||||
class DemodulatorInstance {
|
class DemodulatorInstance {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DemodulatorThreadInputQueue* threadQueueDemod;
|
|
||||||
DemodulatorThreadPostInputQueue* threadQueuePostDemod;
|
|
||||||
DemodulatorThreadCommandQueue* threadQueueCommand;
|
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify;
|
|
||||||
DemodulatorPreThread *demodulatorPreThread;
|
|
||||||
DemodulatorThread *demodulatorThread;
|
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t t_PreDemod;
|
pthread_t t_PreDemod;
|
||||||
pthread_t t_Demod;
|
pthread_t t_Demod;
|
||||||
@ -88,6 +80,18 @@ public:
|
|||||||
|
|
||||||
bool isTracking();
|
bool isTracking();
|
||||||
void setTracking(bool tracking);
|
void setTracking(bool tracking);
|
||||||
|
|
||||||
|
DemodulatorThreadInputQueue *getIQInputDataPipe();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DemodulatorThreadInputQueue* pipeIQInputData;
|
||||||
|
DemodulatorThreadPostInputQueue* pipeIQDemodData;
|
||||||
|
DemodulatorThreadCommandQueue* pipeDemodCommand;
|
||||||
|
DemodulatorThreadCommandQueue* pipeDemodNotify;
|
||||||
|
DemodulatorPreThread *demodulatorPreThread;
|
||||||
|
DemodulatorThread *demodulatorThread;
|
||||||
|
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void checkBandwidth();
|
void checkBandwidth();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
DemodulatorMgr::DemodulatorMgr() :
|
DemodulatorMgr::DemodulatorMgr() :
|
||||||
activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL), lastBandwidth(DEFAULT_DEMOD_BW), lastDemodType(
|
activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL), lastBandwidth(DEFAULT_DEMOD_BW), lastDemodType(
|
||||||
DEFAULT_DEMOD_TYPE), lastGain(1.0), lastSquelch(0), lastSquelchEnabled(false), lastStereo(false) {
|
DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(0), lastGain(1.0), lastStereo(false) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,12 +8,8 @@
|
|||||||
#include "DemodulatorPreThread.h"
|
#include "DemodulatorPreThread.h"
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQueue, DemodulatorThreadPostInputQueue* iqOutputQueue,
|
DemodulatorPreThread::DemodulatorPreThread() : IOThread(), iqResampler(NULL), iqResampleRatio(1), audioResampler(NULL), stereoResampler(NULL), audioResampleRatio(1), firStereoLeft(NULL), firStereoRight(NULL), iirStereoPilot(NULL), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL), commandQueue(NULL)
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) :
|
{
|
||||||
iqInputQueue(iqInputQueue), iqOutputQueue(iqOutputQueue), audioResampler(NULL), stereoResampler(NULL), iqResampleRatio(
|
|
||||||
1), audioResampleRatio(1), firStereoRight(NULL), firStereoLeft(NULL), iirStereoPilot(NULL), iqResampler(NULL), commandQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(
|
|
||||||
threadQueueControl) {
|
|
||||||
terminated.store(false);
|
|
||||||
initialized.store(false);
|
initialized.store(false);
|
||||||
|
|
||||||
freqShifter = nco_crcf_create(LIQUID_VCO);
|
freqShifter = nco_crcf_create(LIQUID_VCO);
|
||||||
@ -21,9 +17,10 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQ
|
|||||||
|
|
||||||
workerQueue = new DemodulatorThreadWorkerCommandQueue;
|
workerQueue = new DemodulatorThreadWorkerCommandQueue;
|
||||||
workerResults = new DemodulatorThreadWorkerResultQueue;
|
workerResults = new DemodulatorThreadWorkerResultQueue;
|
||||||
workerThread = new DemodulatorWorkerThread(workerQueue, workerResults);
|
|
||||||
|
|
||||||
t_Worker = new std::thread(&DemodulatorWorkerThread::threadMain, workerThread);
|
workerThread = new DemodulatorWorkerThread();
|
||||||
|
workerThread->setInputQueue("WorkerCommandQueue",workerQueue);
|
||||||
|
workerThread->setOutputQueue("WorkerResultQueue",workerResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorPreThread::initialize() {
|
void DemodulatorPreThread::initialize() {
|
||||||
@ -80,11 +77,7 @@ DemodulatorPreThread::~DemodulatorPreThread() {
|
|||||||
delete workerResults;
|
delete workerResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
void DemodulatorPreThread::run() {
|
||||||
void *DemodulatorPreThread::threadMain() {
|
|
||||||
#else
|
|
||||||
void DemodulatorPreThread::threadMain() {
|
|
||||||
#endif
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t tID = pthread_self(); // ID of this thread
|
pthread_t tID = pthread_self(); // ID of this thread
|
||||||
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
||||||
@ -98,16 +91,20 @@ void DemodulatorPreThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "Demodulator preprocessor thread started.." << std::endl;
|
std::cout << "Demodulator preprocessor thread started.." << std::endl;
|
||||||
|
|
||||||
std::deque<DemodulatorThreadPostIQData *> buffers;
|
t_Worker = new std::thread(&DemodulatorWorkerThread::threadMain, workerThread);
|
||||||
std::deque<DemodulatorThreadPostIQData *>::iterator buffers_i;
|
|
||||||
|
ReBuffer<DemodulatorThreadPostIQData> buffers;
|
||||||
|
|
||||||
|
iqInputQueue = (DemodulatorThreadInputQueue*)getInputQueue("IQDataInput");
|
||||||
|
iqOutputQueue = (DemodulatorThreadPostInputQueue*)getOutputQueue("IQDataOutput");
|
||||||
|
threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
|
||||||
|
commandQueue = ( DemodulatorThreadCommandQueue*)getInputQueue("CommandQueue");
|
||||||
|
|
||||||
std::vector<liquid_float_complex> in_buf_data;
|
std::vector<liquid_float_complex> in_buf_data;
|
||||||
std::vector<liquid_float_complex> out_buf_data;
|
std::vector<liquid_float_complex> out_buf_data;
|
||||||
// liquid_float_complex carrySample; // Keep the stream count even to simplify some demod operations
|
// liquid_float_complex carrySample; // Keep the stream count even to simplify some demod operations
|
||||||
// bool carrySampleFlag = false;
|
// bool carrySampleFlag = false;
|
||||||
|
|
||||||
terminated = false;
|
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
DemodulatorThreadIQData *inp;
|
DemodulatorThreadIQData *inp;
|
||||||
iqInputQueue->pop(inp);
|
iqInputQueue->pop(inp);
|
||||||
@ -207,19 +204,7 @@ void DemodulatorPreThread::threadMain() {
|
|||||||
out_buf = temp_buf;
|
out_buf = temp_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorThreadPostIQData *resamp = NULL;
|
DemodulatorThreadPostIQData *resamp = buffers.getBuffer();
|
||||||
|
|
||||||
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
|
|
||||||
if ((*buffers_i)->getRefCount() <= 0) {
|
|
||||||
resamp = (*buffers_i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resamp == NULL) {
|
|
||||||
resamp = new DemodulatorThreadPostIQData;
|
|
||||||
buffers.push_back(resamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int out_size = ceil((double) (bufSize) * iqResampleRatio) + 512;
|
int out_size = ceil((double) (bufSize) * iqResampleRatio) + 512;
|
||||||
|
|
||||||
@ -326,20 +311,12 @@ void DemodulatorPreThread::threadMain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
buffers.purge();
|
||||||
DemodulatorThreadPostIQData *iqDataDel = buffers.front();
|
|
||||||
buffers.pop_front();
|
|
||||||
delete iqDataDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED);
|
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED);
|
||||||
tCmd.context = this;
|
tCmd.context = this;
|
||||||
threadQueueNotify->push(tCmd);
|
threadQueueNotify->push(tCmd);
|
||||||
std::cout << "Demodulator preprocessor thread done." << std::endl;
|
std::cout << "Demodulator preprocessor thread done." << std::endl;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
return this;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorPreThread::terminate() {
|
void DemodulatorPreThread::terminate() {
|
||||||
|
@ -7,26 +7,13 @@
|
|||||||
#include "DemodDefs.h"
|
#include "DemodDefs.h"
|
||||||
#include "DemodulatorWorkerThread.h"
|
#include "DemodulatorWorkerThread.h"
|
||||||
|
|
||||||
class DemodulatorPreThread {
|
class DemodulatorPreThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQueue, DemodulatorThreadPostInputQueue* iqOutputQueue,
|
DemodulatorPreThread();
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify);
|
|
||||||
~DemodulatorPreThread();
|
~DemodulatorPreThread();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
void run();
|
||||||
void *threadMain();
|
|
||||||
#else
|
|
||||||
void threadMain();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setCommandQueue(DemodulatorThreadCommandQueue *tQueue) {
|
|
||||||
commandQueue = tQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDemodulatorControlQueue(DemodulatorThreadControlCommandQueue *tQueue) {
|
|
||||||
threadQueueControl = tQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DemodulatorThreadParameters &getParams() {
|
DemodulatorThreadParameters &getParams() {
|
||||||
return params;
|
return params;
|
||||||
@ -46,10 +33,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DemodulatorThreadInputQueue* iqInputQueue;
|
|
||||||
DemodulatorThreadPostInputQueue* iqOutputQueue;
|
|
||||||
DemodulatorThreadCommandQueue* commandQueue;
|
|
||||||
|
|
||||||
msresamp_crcf iqResampler;
|
msresamp_crcf iqResampler;
|
||||||
double iqResampleRatio;
|
double iqResampleRatio;
|
||||||
std::vector<liquid_float_complex> resampledData;
|
std::vector<liquid_float_complex> resampledData;
|
||||||
@ -68,7 +51,6 @@ protected:
|
|||||||
nco_crcf freqShifter;
|
nco_crcf freqShifter;
|
||||||
int shiftFrequency;
|
int shiftFrequency;
|
||||||
|
|
||||||
std::atomic_bool terminated;
|
|
||||||
std::atomic_bool initialized;
|
std::atomic_bool initialized;
|
||||||
|
|
||||||
DemodulatorWorkerThread *workerThread;
|
DemodulatorWorkerThread *workerThread;
|
||||||
@ -76,6 +58,9 @@ protected:
|
|||||||
|
|
||||||
DemodulatorThreadWorkerCommandQueue *workerQueue;
|
DemodulatorThreadWorkerCommandQueue *workerQueue;
|
||||||
DemodulatorThreadWorkerResultQueue *workerResults;
|
DemodulatorThreadWorkerResultQueue *workerResults;
|
||||||
|
|
||||||
|
DemodulatorThreadInputQueue* iqInputQueue;
|
||||||
|
DemodulatorThreadPostInputQueue* iqOutputQueue;
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify;
|
DemodulatorThreadCommandQueue* threadQueueNotify;
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
DemodulatorThreadCommandQueue* commandQueue;
|
||||||
};
|
};
|
||||||
|
@ -11,15 +11,10 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
|
DemodulatorThread::DemodulatorThread() : IOThread(), iqAutoGain(NULL), amOutputCeil(1), amOutputCeilMA(1), amOutputCeilMAA(1), audioSampleRate(0), squelchLevel(0), signalLevel(0), squelchEnabled(false), iqInputQueue(NULL), audioOutputQueue(NULL), audioVisOutputQueue(NULL), threadQueueControl(NULL), threadQueueNotify(NULL) {
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify) :
|
|
||||||
iqInputQueue(iqInputQueue), audioVisOutputQueue(NULL), audioOutputQueue(NULL), iqAutoGain(NULL), amOutputCeil(1), amOutputCeilMA(1), amOutputCeilMAA(
|
|
||||||
1), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelchLevel(0), signalLevel(
|
|
||||||
0), squelchEnabled(false), audioSampleRate(0) {
|
|
||||||
|
|
||||||
stereo.store(false);
|
stereo.store(false);
|
||||||
agcEnabled.store(false);
|
agcEnabled.store(false);
|
||||||
terminated.store(false);
|
|
||||||
demodulatorType.store(DEMOD_TYPE_FM);
|
demodulatorType.store(DEMOD_TYPE_FM);
|
||||||
|
|
||||||
demodFM = freqdem_create(0.5);
|
demodFM = freqdem_create(0.5);
|
||||||
@ -100,11 +95,13 @@ DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQue
|
|||||||
DemodulatorThread::~DemodulatorThread() {
|
DemodulatorThread::~DemodulatorThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBase *threadQueue) {
|
||||||
void *DemodulatorThread::threadMain() {
|
if (name == "AudioVisualOutput") {
|
||||||
#else
|
audioVisOutputQueue = (DemodulatorThreadOutputQueue *)threadQueue;
|
||||||
void DemodulatorThread::threadMain() {
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
void DemodulatorThread::run() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t tID = pthread_self(); // ID of this thread
|
pthread_t tID = pthread_self(); // ID of this thread
|
||||||
int priority = sched_get_priority_max( SCHED_FIFO )-1;
|
int priority = sched_get_priority_max( SCHED_FIFO )-1;
|
||||||
@ -139,6 +136,11 @@ void DemodulatorThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "Demodulator thread started.." << std::endl;
|
std::cout << "Demodulator thread started.." << std::endl;
|
||||||
|
|
||||||
|
iqInputQueue = (DemodulatorThreadPostInputQueue*)getInputQueue("IQDataInput");
|
||||||
|
audioOutputQueue = (AudioThreadInputQueue*)getOutputQueue("AudioDataOutput");
|
||||||
|
threadQueueControl = (DemodulatorThreadControlCommandQueue *)getInputQueue("ControlQueue");
|
||||||
|
threadQueueNotify = (DemodulatorThreadCommandQueue*)getOutputQueue("NotifyQueue");
|
||||||
|
|
||||||
switch (demodulatorType.load()) {
|
switch (demodulatorType.load()) {
|
||||||
case DEMOD_TYPE_FM:
|
case DEMOD_TYPE_FM:
|
||||||
break;
|
break;
|
||||||
@ -156,8 +158,6 @@ void DemodulatorThread::threadMain() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
terminated = false;
|
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
DemodulatorThreadPostIQData *inp;
|
DemodulatorThreadPostIQData *inp;
|
||||||
iqInputQueue->pop(inp);
|
iqInputQueue->pop(inp);
|
||||||
@ -683,17 +683,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
if (audioOutputQueue != NULL) {
|
if (audioOutputQueue != NULL) {
|
||||||
if (!squelchEnabled || (signalLevel >= squelchLevel)) {
|
if (!squelchEnabled || (signalLevel >= squelchLevel)) {
|
||||||
|
|
||||||
for (outputBuffersI = outputBuffers.begin(); outputBuffersI != outputBuffers.end(); outputBuffersI++) {
|
ati = outputBuffers.getBuffer();
|
||||||
if ((*outputBuffersI)->getRefCount() <= 0) {
|
|
||||||
ati = (*outputBuffersI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ati == NULL) {
|
|
||||||
ati = new AudioThreadInput;
|
|
||||||
outputBuffers.push_back(ati);
|
|
||||||
}
|
|
||||||
|
|
||||||
ati->sampleRate = audioSampleRate;
|
ati->sampleRate = audioSampleRate;
|
||||||
ati->setRefCount(1);
|
ati->setRefCount(1);
|
||||||
@ -903,11 +893,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
nco_crcf_destroy(stereoPilot);
|
nco_crcf_destroy(stereoPilot);
|
||||||
resamp2_cccf_destroy(ssbFilt);
|
resamp2_cccf_destroy(ssbFilt);
|
||||||
|
|
||||||
while (!outputBuffers.empty()) {
|
outputBuffers.purge();
|
||||||
AudioThreadInput *audioDataDel = outputBuffers.front();
|
|
||||||
outputBuffers.pop_front();
|
|
||||||
delete audioDataDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioVisOutputQueue && !audioVisOutputQueue->empty()) {
|
if (audioVisOutputQueue && !audioVisOutputQueue->empty()) {
|
||||||
AudioThreadInput *dummy_vis;
|
AudioThreadInput *dummy_vis;
|
||||||
@ -918,19 +904,8 @@ void DemodulatorThread::threadMain() {
|
|||||||
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED);
|
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED);
|
||||||
tCmd.context = this;
|
tCmd.context = this;
|
||||||
threadQueueNotify->push(tCmd);
|
threadQueueNotify->push(tCmd);
|
||||||
|
|
||||||
std::cout << "Demodulator thread done." << std::endl;
|
std::cout << "Demodulator thread done." << std::endl;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
return this;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemodulatorThread::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
|
||||||
audioVisOutputQueue = tQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemodulatorThread::setAudioOutputQueue(AudioThreadInputQueue *tQueue) {
|
|
||||||
audioOutputQueue = tQueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorThread::terminate() {
|
void DemodulatorThread::terminate() {
|
||||||
|
@ -10,22 +10,15 @@ typedef ThreadQueue<AudioThreadInput *> DemodulatorThreadOutputQueue;
|
|||||||
|
|
||||||
#define DEMOD_VIS_SIZE 1024
|
#define DEMOD_VIS_SIZE 1024
|
||||||
|
|
||||||
class DemodulatorThread {
|
class DemodulatorThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
|
DemodulatorThread();
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify);
|
|
||||||
~DemodulatorThread();
|
~DemodulatorThread();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
void onBindOutput(std::string name, ThreadQueueBase *threadQueue);
|
||||||
void *threadMain();
|
|
||||||
#else
|
|
||||||
void threadMain();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue);
|
|
||||||
void setAudioOutputQueue(AudioThreadInputQueue *tQueue);
|
|
||||||
|
|
||||||
|
void run();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void setStereo(bool state);
|
void setStereo(bool state);
|
||||||
@ -54,8 +47,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::deque<AudioThreadInput *> outputBuffers;
|
ReBuffer<AudioThreadInput> outputBuffers;
|
||||||
std::deque<AudioThreadInput *>::iterator outputBuffersI;
|
|
||||||
|
|
||||||
std::vector<liquid_float_complex> agcData;
|
std::vector<liquid_float_complex> agcData;
|
||||||
std::vector<float> agcAMData;
|
std::vector<float> agcAMData;
|
||||||
@ -63,17 +55,12 @@ protected:
|
|||||||
std::vector<float> demodStereoData;
|
std::vector<float> demodStereoData;
|
||||||
std::vector<float> resampledOutputData;
|
std::vector<float> resampledOutputData;
|
||||||
std::vector<float> resampledStereoData;
|
std::vector<float> resampledStereoData;
|
||||||
|
|
||||||
std::vector<unsigned int> demodOutputDataDigital;
|
std::vector<unsigned int> demodOutputDataDigital;
|
||||||
//std::vector<unsigned int> demodOutputDataDigitalTest;
|
//std::vector<unsigned int> demodOutputDataDigitalTest;
|
||||||
|
|
||||||
//std::vector<unsigned char> demodOutputSoftbits;
|
//std::vector<unsigned char> demodOutputSoftbits;
|
||||||
//std::vector<unsigned char> demodOutputSoftbitsTest;
|
//std::vector<unsigned char> demodOutputSoftbitsTest;
|
||||||
|
|
||||||
DemodulatorThreadPostInputQueue* iqInputQueue;
|
|
||||||
DemodulatorThreadOutputQueue* audioVisOutputQueue;
|
|
||||||
AudioThreadInputQueue *audioOutputQueue;
|
|
||||||
|
|
||||||
freqdem demodFM;
|
freqdem demodFM;
|
||||||
ampmodem demodAM;
|
ampmodem demodAM;
|
||||||
ampmodem demodAM_DSB_CSP;
|
ampmodem demodAM_DSB_CSP;
|
||||||
@ -149,13 +136,10 @@ protected:
|
|||||||
|
|
||||||
std::atomic_bool stereo;
|
std::atomic_bool stereo;
|
||||||
std::atomic_bool agcEnabled;
|
std::atomic_bool agcEnabled;
|
||||||
std::atomic_bool terminated;
|
|
||||||
std::atomic_int demodulatorType;
|
std::atomic_int demodulatorType;
|
||||||
std::atomic_int demodulatorCons;
|
std::atomic_int demodulatorCons;
|
||||||
int audioSampleRate;
|
int audioSampleRate;
|
||||||
|
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify;
|
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
|
||||||
std::atomic<float> squelchLevel;
|
std::atomic<float> squelchLevel;
|
||||||
std::atomic<float> signalLevel;
|
std::atomic<float> signalLevel;
|
||||||
bool squelchEnabled;
|
bool squelchEnabled;
|
||||||
@ -165,4 +149,10 @@ protected:
|
|||||||
|
|
||||||
void updateDemodulatorCons(int Cons);
|
void updateDemodulatorCons(int Cons);
|
||||||
void updateDemodulatorLock(modem demod, float sensitivity);
|
void updateDemodulatorLock(modem demod, float sensitivity);
|
||||||
|
|
||||||
|
DemodulatorThreadPostInputQueue* iqInputQueue;
|
||||||
|
AudioThreadInputQueue *audioOutputQueue;
|
||||||
|
DemodulatorThreadOutputQueue* audioVisOutputQueue;
|
||||||
|
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
||||||
|
DemodulatorThreadCommandQueue* threadQueueNotify;
|
||||||
};
|
};
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
#include "CubicSDRDefs.h"
|
#include "CubicSDRDefs.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
DemodulatorWorkerThread::DemodulatorWorkerThread(DemodulatorThreadWorkerCommandQueue* in, DemodulatorThreadWorkerResultQueue* out) :
|
DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(),
|
||||||
commandQueue(in), resultQueue(out) {
|
commandQueue(NULL), resultQueue(NULL) {
|
||||||
terminated.store(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorWorkerThread::~DemodulatorWorkerThread() {
|
DemodulatorWorkerThread::~DemodulatorWorkerThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorWorkerThread::threadMain() {
|
void DemodulatorWorkerThread::run() {
|
||||||
|
|
||||||
std::cout << "Demodulator worker thread started.." << std::endl;
|
std::cout << "Demodulator worker thread started.." << std::endl;
|
||||||
|
|
||||||
|
commandQueue = (DemodulatorThreadWorkerCommandQueue *)getInputQueue("WorkerCommandQueue");
|
||||||
|
resultQueue = (DemodulatorThreadWorkerResultQueue *)getOutputQueue("WorkerResultQueue");
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
bool filterChanged = false;
|
bool filterChanged = false;
|
||||||
DemodulatorWorkerThreadCommand filterCommand;
|
DemodulatorWorkerThreadCommand filterCommand;
|
||||||
|
@ -70,13 +70,13 @@ public:
|
|||||||
typedef ThreadQueue<DemodulatorWorkerThreadCommand> DemodulatorThreadWorkerCommandQueue;
|
typedef ThreadQueue<DemodulatorWorkerThreadCommand> DemodulatorThreadWorkerCommandQueue;
|
||||||
typedef ThreadQueue<DemodulatorWorkerThreadResult> DemodulatorThreadWorkerResultQueue;
|
typedef ThreadQueue<DemodulatorWorkerThreadResult> DemodulatorThreadWorkerResultQueue;
|
||||||
|
|
||||||
class DemodulatorWorkerThread {
|
class DemodulatorWorkerThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DemodulatorWorkerThread(DemodulatorThreadWorkerCommandQueue* in, DemodulatorThreadWorkerResultQueue* out);
|
DemodulatorWorkerThread();
|
||||||
~DemodulatorWorkerThread();
|
~DemodulatorWorkerThread();
|
||||||
|
|
||||||
void threadMain();
|
void run();
|
||||||
|
|
||||||
void setCommandQueue(DemodulatorThreadWorkerCommandQueue *tQueue) {
|
void setCommandQueue(DemodulatorThreadWorkerCommandQueue *tQueue) {
|
||||||
commandQueue = tQueue;
|
commandQueue = tQueue;
|
||||||
@ -92,6 +92,4 @@ protected:
|
|||||||
|
|
||||||
DemodulatorThreadWorkerCommandQueue *commandQueue;
|
DemodulatorThreadWorkerCommandQueue *commandQueue;
|
||||||
DemodulatorThreadWorkerResultQueue *resultQueue;
|
DemodulatorThreadWorkerResultQueue *resultQueue;
|
||||||
|
|
||||||
std::atomic_bool terminated;
|
|
||||||
};
|
};
|
||||||
|
1
src/process/ScopeVisualProcessor.cpp
Normal file
1
src/process/ScopeVisualProcessor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "ScopeVisualProcessor.h"
|
63
src/process/ScopeVisualProcessor.h
Normal file
63
src/process/ScopeVisualProcessor.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VisualProcessor.h"
|
||||||
|
#include "AudioThread.h"
|
||||||
|
|
||||||
|
class ScopeVisualProcessor : public VisualProcessor {
|
||||||
|
protected:
|
||||||
|
std::vector<float> waveform_points;
|
||||||
|
|
||||||
|
virtual void process() {
|
||||||
|
if (!input->empty()) {
|
||||||
|
ReferenceCounter *ati_ref;
|
||||||
|
input->pop(ati_ref);
|
||||||
|
|
||||||
|
AudioThreadInput *ati = (AudioThreadInput *)ati_ref;
|
||||||
|
if (!ati) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int iMax = ati->data.size();
|
||||||
|
if (!iMax) {
|
||||||
|
ati->decRefCount();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (waveform_points.size() != iMax * 2) {
|
||||||
|
waveform_points.resize(iMax * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < iMax; i++) {
|
||||||
|
waveform_points[i * 2 + 1] = ati->data[i] * 0.5f;
|
||||||
|
waveform_points[i * 2] = ((double) i / (double) iMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ati->channels
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (!wxGetApp().getAudioVisualQueue()->empty()) {
|
||||||
|
AudioThreadInput *demodAudioData;
|
||||||
|
wxGetApp().getAudioVisualQueue()->pop(demodAudioData);
|
||||||
|
|
||||||
|
int iMax = demodAudioData?demodAudioData->data.size():0;
|
||||||
|
|
||||||
|
if (demodAudioData && iMax) {
|
||||||
|
if (waveform_points.size() != iMax * 2) {
|
||||||
|
waveform_points.resize(iMax * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
demodAudioData->busy_update.lock();
|
||||||
|
|
||||||
|
for (int i = 0; i < iMax; i++) {
|
||||||
|
waveform_points[i * 2 + 1] = demodAudioData->data[i] * 0.5f;
|
||||||
|
waveform_points[i * 2] = ((double) i / (double) iMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
demodAudioData->busy_update.unlock();
|
||||||
|
|
||||||
|
setStereo(demodAudioData->channels == 2);
|
||||||
|
} else {
|
||||||
|
std::cout << "Incoming Demodulator data empty?" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
1
src/process/SpectrumVisualProcessor.cpp
Normal file
1
src/process/SpectrumVisualProcessor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "SpectrumVisualProcessor.h"
|
85
src/process/SpectrumVisualProcessor.h
Normal file
85
src/process/SpectrumVisualProcessor.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VisualProcessor.h"
|
||||||
|
|
||||||
|
class SpectrumVisualProcessor : public VisualProcessor {
|
||||||
|
protected:
|
||||||
|
virtual void process() {
|
||||||
|
/*
|
||||||
|
std::vector<liquid_float_complex> *data = &input->data;
|
||||||
|
if (data && data->size()) {
|
||||||
|
if (fft_size != data->size()) {
|
||||||
|
setup(data->size());
|
||||||
|
}
|
||||||
|
if (spectrum_points.size() < fft_size * 2) {
|
||||||
|
if (spectrum_points.capacity() < fft_size * 2) {
|
||||||
|
spectrum_points.reserve(fft_size * 2);
|
||||||
|
}
|
||||||
|
spectrum_points.resize(fft_size * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < fft_size; i++) {
|
||||||
|
in[i][0] = (*data)[i].real;
|
||||||
|
in[i][1] = (*data)[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
fftwf_execute(plan);
|
||||||
|
|
||||||
|
float fft_ceil = 0, fft_floor = 1;
|
||||||
|
|
||||||
|
if (fft_result.size() != fft_size) {
|
||||||
|
if (fft_result.capacity() < fft_size) {
|
||||||
|
fft_result.reserve(fft_size);
|
||||||
|
fft_result_ma.reserve(fft_size);
|
||||||
|
fft_result_maa.reserve(fft_size);
|
||||||
|
}
|
||||||
|
fft_result.resize(fft_size);
|
||||||
|
fft_result_ma.resize(fft_size);
|
||||||
|
fft_result_maa.resize(fft_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n;
|
||||||
|
for (int i = 0, iMax = fft_size / 2; i < iMax; i++) {
|
||||||
|
float a = out[i][0];
|
||||||
|
float b = out[i][1];
|
||||||
|
float c = sqrt(a * a + b * b);
|
||||||
|
|
||||||
|
float x = out[fft_size / 2 + i][0];
|
||||||
|
float y = out[fft_size / 2 + i][1];
|
||||||
|
float z = sqrt(x * x + y * y);
|
||||||
|
|
||||||
|
fft_result[i] = (z);
|
||||||
|
fft_result[fft_size / 2 + i] = (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
||||||
|
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65;
|
||||||
|
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65;
|
||||||
|
|
||||||
|
if (fft_result_maa[i] > fft_ceil) {
|
||||||
|
fft_ceil = fft_result_maa[i];
|
||||||
|
}
|
||||||
|
if (fft_result_maa[i] < fft_floor) {
|
||||||
|
fft_floor = fft_result_maa[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fft_ceil += 1;
|
||||||
|
fft_floor -= 1;
|
||||||
|
|
||||||
|
fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.01;
|
||||||
|
fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01;
|
||||||
|
|
||||||
|
fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01;
|
||||||
|
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01;
|
||||||
|
|
||||||
|
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
||||||
|
float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
|
||||||
|
spectrum_points[i * 2] = ((float) i / (float) iMax);
|
||||||
|
spectrum_points[i * 2 + 1] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
1
src/process/VisualProcessor.cpp
Normal file
1
src/process/VisualProcessor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "VisualProcessor.h"
|
75
src/process/VisualProcessor.h
Normal file
75
src/process/VisualProcessor.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CubicSDRDefs.h"
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
#include "IOThread.h"
|
||||||
|
|
||||||
|
typedef ThreadQueue<ReferenceCounter *> VisualDataQueue;
|
||||||
|
|
||||||
|
class VisualProcessor {
|
||||||
|
public:
|
||||||
|
void setInput(VisualDataQueue *vis_in) {
|
||||||
|
busy_update.lock();
|
||||||
|
input = vis_in;
|
||||||
|
busy_update.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void attachOutput(VisualDataQueue *vis_out) {
|
||||||
|
// attach an output queue
|
||||||
|
busy_update.lock();
|
||||||
|
outputs.push_back(vis_out);
|
||||||
|
busy_update.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeOutput(VisualDataQueue *vis_out) {
|
||||||
|
// remove an output queue
|
||||||
|
busy_update.lock();
|
||||||
|
std::vector<VisualDataQueue *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out);
|
||||||
|
if (i != outputs.end()) {
|
||||||
|
outputs.erase(i);
|
||||||
|
}
|
||||||
|
busy_update.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
busy_update.lock();
|
||||||
|
if (input && !input->empty()) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
busy_update.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void process() {
|
||||||
|
// process inputs to output
|
||||||
|
// distribute(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void distribute(ReferenceCounter *output) {
|
||||||
|
// distribute outputs
|
||||||
|
output->setRefCount(outputs.size());
|
||||||
|
std::vector<VisualDataQueue *>::iterator outputs_i;
|
||||||
|
for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) {
|
||||||
|
(*outputs_i)->push(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualDataQueue * input;
|
||||||
|
std::vector<VisualDataQueue *> outputs;
|
||||||
|
std::mutex busy_update;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VisualDataDistributor : public VisualProcessor {
|
||||||
|
protected:
|
||||||
|
virtual void process() {
|
||||||
|
while (!input->empty()) {
|
||||||
|
ReferenceCounter *inp;
|
||||||
|
input->pop(inp);
|
||||||
|
if (inp) {
|
||||||
|
distribute(inp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
1
src/process/WaterfallVisualProcessor.cpp
Normal file
1
src/process/WaterfallVisualProcessor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "WaterfallVisualProcessor.h"
|
281
src/process/WaterfallVisualProcessor.h
Normal file
281
src/process/WaterfallVisualProcessor.h
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VisualProcessor.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WaterfallVisualProcessor : public VisualProcessor {
|
||||||
|
protected:
|
||||||
|
virtual void process() {
|
||||||
|
/*
|
||||||
|
long double currentZoom = zoom;
|
||||||
|
|
||||||
|
if (mouseZoom != 1) {
|
||||||
|
currentZoom = mouseZoom;
|
||||||
|
mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2;
|
||||||
|
if (fabs(mouseZoom-1.0)<0.01) {
|
||||||
|
mouseZoom = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long long bw;
|
||||||
|
if (currentZoom != 1) {
|
||||||
|
long long freq = wxGetApp().getFrequency();
|
||||||
|
|
||||||
|
if (currentZoom < 1) {
|
||||||
|
centerFreq = getCenterFrequency();
|
||||||
|
bw = getBandwidth();
|
||||||
|
bw = (long long) ceil((long double) bw * currentZoom);
|
||||||
|
if (bw < 100000) {
|
||||||
|
bw = 100000;
|
||||||
|
}
|
||||||
|
if (mouseTracker.mouseInView()) {
|
||||||
|
long long mfreqA = getFrequencyAt(mouseTracker.getMouseX());
|
||||||
|
setBandwidth(bw);
|
||||||
|
long long mfreqB = getFrequencyAt(mouseTracker.getMouseX());
|
||||||
|
centerFreq += mfreqA - mfreqB;
|
||||||
|
}
|
||||||
|
|
||||||
|
setView(centerFreq, bw);
|
||||||
|
if (spectrumCanvas) {
|
||||||
|
spectrumCanvas->setView(centerFreq, bw);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isView) {
|
||||||
|
bw = getBandwidth();
|
||||||
|
bw = (long long) ceil((long double) bw * currentZoom);
|
||||||
|
if (bw >= wxGetApp().getSampleRate()) {
|
||||||
|
disableView();
|
||||||
|
if (spectrumCanvas) {
|
||||||
|
spectrumCanvas->disableView();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mouseTracker.mouseInView()) {
|
||||||
|
long long mfreqA = getFrequencyAt(mouseTracker.getMouseX());
|
||||||
|
setBandwidth(bw);
|
||||||
|
long long mfreqB = getFrequencyAt(mouseTracker.getMouseX());
|
||||||
|
centerFreq += mfreqA - mfreqB;
|
||||||
|
}
|
||||||
|
|
||||||
|
setView(getCenterFrequency(), bw);
|
||||||
|
if (spectrumCanvas) {
|
||||||
|
spectrumCanvas->setView(centerFreq, bw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) {
|
||||||
|
centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2;
|
||||||
|
}
|
||||||
|
if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) {
|
||||||
|
centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<liquid_float_complex> *data = &input->data;
|
||||||
|
|
||||||
|
if (data && data->size()) {
|
||||||
|
// if (fft_size != data->size() && !isView) {
|
||||||
|
// Setup(data->size(), waterfall_lines);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (last_bandwidth != bandwidth && !isView) {
|
||||||
|
// Setup(bandwidth, waterfall_lines);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (spectrum_points.size() < fft_size * 2) {
|
||||||
|
spectrum_points.resize(fft_size * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int num_written;
|
||||||
|
|
||||||
|
if (isView) {
|
||||||
|
if (!input->frequency || !input->sampleRate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resamplerRatio = (double) (bandwidth) / (double) input->sampleRate;
|
||||||
|
|
||||||
|
int desired_input_size = fft_size / resamplerRatio;
|
||||||
|
|
||||||
|
if (input->data.size() < desired_input_size) {
|
||||||
|
// std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl;
|
||||||
|
desired_input_size = input->data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (centerFreq != input->frequency) {
|
||||||
|
if ((centerFreq - input->frequency) != shiftFrequency || lastInputBandwidth != input->sampleRate) {
|
||||||
|
if (abs(input->frequency - centerFreq) < (wxGetApp().getSampleRate() / 2)) {
|
||||||
|
shiftFrequency = centerFreq - input->frequency;
|
||||||
|
nco_crcf_reset(freqShifter);
|
||||||
|
nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) input->sampleRate)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shiftBuffer.size() != desired_input_size) {
|
||||||
|
if (shiftBuffer.capacity() < desired_input_size) {
|
||||||
|
shiftBuffer.reserve(desired_input_size);
|
||||||
|
}
|
||||||
|
shiftBuffer.resize(desired_input_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shiftFrequency < 0) {
|
||||||
|
nco_crcf_mix_block_up(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size);
|
||||||
|
} else {
|
||||||
|
nco_crcf_mix_block_down(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shiftBuffer.assign(input->data.begin(), input->data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) {
|
||||||
|
float As = 60.0f;
|
||||||
|
|
||||||
|
if (resampler) {
|
||||||
|
msresamp_crcf_destroy(resampler);
|
||||||
|
}
|
||||||
|
resampler = msresamp_crcf_create(resamplerRatio, As);
|
||||||
|
|
||||||
|
lastBandwidth = bandwidth;
|
||||||
|
lastInputBandwidth = input->sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512;
|
||||||
|
|
||||||
|
if (resampleBuffer.size() != out_size) {
|
||||||
|
if (resampleBuffer.capacity() < out_size) {
|
||||||
|
resampleBuffer.reserve(out_size);
|
||||||
|
}
|
||||||
|
resampleBuffer.resize(out_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written);
|
||||||
|
|
||||||
|
resampleBuffer.resize(fft_size);
|
||||||
|
|
||||||
|
if (num_written < fft_size) {
|
||||||
|
for (int i = 0; i < num_written; i++) {
|
||||||
|
fft_in_data[i][0] = resampleBuffer[i].real;
|
||||||
|
fft_in_data[i][1] = resampleBuffer[i].imag;
|
||||||
|
}
|
||||||
|
for (int i = num_written; i < fft_size; i++) {
|
||||||
|
fft_in_data[i][0] = 0;
|
||||||
|
fft_in_data[i][1] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fft_size; i++) {
|
||||||
|
fft_in_data[i][0] = resampleBuffer[i].real;
|
||||||
|
fft_in_data[i][1] = resampleBuffer[i].imag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
num_written = data->size();
|
||||||
|
if (data->size() < fft_size) {
|
||||||
|
for (int i = 0, iMax = data->size(); i < iMax; i++) {
|
||||||
|
fft_in_data[i][0] = (*data)[i].real;
|
||||||
|
fft_in_data[i][1] = (*data)[i].imag;
|
||||||
|
}
|
||||||
|
for (int i = data->size(); i < fft_size; i++) {
|
||||||
|
fft_in_data[i][0] = 0;
|
||||||
|
fft_in_data[i][1] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fft_size; i++) {
|
||||||
|
fft_in_data[i][0] = (*data)[i].real;
|
||||||
|
fft_in_data[i][1] = (*data)[i].imag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute = false;
|
||||||
|
|
||||||
|
if (num_written >= fft_size) {
|
||||||
|
execute = true;
|
||||||
|
memcpy(in, fft_in_data, fft_size * sizeof(fftwf_complex));
|
||||||
|
memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (last_data_size + num_written < fft_size) { // priming
|
||||||
|
unsigned int num_copy = fft_size - last_data_size;
|
||||||
|
if (num_written > num_copy) {
|
||||||
|
num_copy = num_written;
|
||||||
|
}
|
||||||
|
memcpy(fft_last_data, fft_in_data, num_copy * sizeof(fftwf_complex));
|
||||||
|
last_data_size += num_copy;
|
||||||
|
} else {
|
||||||
|
unsigned int num_last = (fft_size - num_written);
|
||||||
|
memcpy(in, fft_last_data + (last_data_size - num_last), num_last * sizeof(fftwf_complex));
|
||||||
|
memcpy(in + num_last, fft_in_data, num_written * sizeof(fftwf_complex));
|
||||||
|
memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex));
|
||||||
|
execute = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (execute) {
|
||||||
|
fftwf_execute(plan);
|
||||||
|
|
||||||
|
float fft_ceil = 0, fft_floor = 1;
|
||||||
|
|
||||||
|
if (fft_result.size() < fft_size) {
|
||||||
|
fft_result.resize(fft_size);
|
||||||
|
fft_result_ma.resize(fft_size);
|
||||||
|
fft_result_maa.resize(fft_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n;
|
||||||
|
for (int i = 0, iMax = fft_size / 2; i < iMax; i++) {
|
||||||
|
float a = out[i][0];
|
||||||
|
float b = out[i][1];
|
||||||
|
float c = sqrt(a * a + b * b);
|
||||||
|
|
||||||
|
float x = out[fft_size / 2 + i][0];
|
||||||
|
float y = out[fft_size / 2 + i][1];
|
||||||
|
float z = sqrt(x * x + y * y);
|
||||||
|
|
||||||
|
fft_result[i] = (z);
|
||||||
|
fft_result[fft_size / 2 + i] = (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
||||||
|
if (isView) {
|
||||||
|
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65;
|
||||||
|
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65;
|
||||||
|
} else {
|
||||||
|
fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65;
|
||||||
|
fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fft_result_maa[i] > fft_ceil) {
|
||||||
|
fft_ceil = fft_result_maa[i];
|
||||||
|
}
|
||||||
|
if (fft_result_maa[i] < fft_floor) {
|
||||||
|
fft_floor = fft_result_maa[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fft_ceil += 0.25;
|
||||||
|
fft_floor -= 1;
|
||||||
|
|
||||||
|
fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05;
|
||||||
|
fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05;
|
||||||
|
|
||||||
|
fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05;
|
||||||
|
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05;
|
||||||
|
|
||||||
|
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
||||||
|
float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
|
||||||
|
spectrum_points[i * 2] = ((float) i / (float) iMax);
|
||||||
|
spectrum_points[i * 2 + 1] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spectrumCanvas) {
|
||||||
|
spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end());
|
||||||
|
spectrumCanvas->getSpectrumContext()->setCeilValue(fft_ceil_maa);
|
||||||
|
spectrumCanvas->getSpectrumContext()->setFloorValue(fft_floor_maa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
65
src/sdr/SDRDeviceInfo.cpp
Normal file
65
src/sdr/SDRDeviceInfo.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "SDRDeviceInfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SDRDeviceInfo::getDeviceId() {
|
||||||
|
std::string deviceId;
|
||||||
|
|
||||||
|
deviceId.append(getName());
|
||||||
|
deviceId.append(" :: ");
|
||||||
|
deviceId.append(getSerial());
|
||||||
|
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDRDeviceInfo::isAvailable() const {
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setAvailable(bool available) {
|
||||||
|
this->available = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& SDRDeviceInfo::getName() const {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setName(const std::string& name) {
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& SDRDeviceInfo::getSerial() const {
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setSerial(const std::string& serial) {
|
||||||
|
this->serial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& SDRDeviceInfo::getTuner() const {
|
||||||
|
return tuner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setTuner(const std::string& tuner) {
|
||||||
|
this->tuner = tuner;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& SDRDeviceInfo::getManufacturer() const {
|
||||||
|
return manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setManufacturer(const std::string& manufacturer) {
|
||||||
|
this->manufacturer = manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& SDRDeviceInfo::getProduct() const {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDeviceInfo::setProduct(const std::string& product) {
|
||||||
|
this->product = product;
|
||||||
|
}
|
||||||
|
|
36
src/sdr/SDRDeviceInfo.h
Normal file
36
src/sdr/SDRDeviceInfo.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class SDRDeviceInfo {
|
||||||
|
public:
|
||||||
|
SDRDeviceInfo();
|
||||||
|
|
||||||
|
std::string getDeviceId();
|
||||||
|
|
||||||
|
bool isAvailable() const;
|
||||||
|
void setAvailable(bool available);
|
||||||
|
|
||||||
|
const std::string& getName() const;
|
||||||
|
void setName(const std::string& name);
|
||||||
|
|
||||||
|
const std::string& getSerial() const;
|
||||||
|
void setSerial(const std::string& serial);
|
||||||
|
|
||||||
|
const std::string& getTuner() const;
|
||||||
|
void setTuner(const std::string& tuner);
|
||||||
|
|
||||||
|
const std::string& getManufacturer() const;
|
||||||
|
void setManufacturer(const std::string& manufacturer);
|
||||||
|
|
||||||
|
const std::string& getProduct() const;
|
||||||
|
void setProduct(const std::string& product);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::string serial;
|
||||||
|
std::string product;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string tuner;
|
||||||
|
bool available;
|
||||||
|
};
|
@ -5,10 +5,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
SDRPostThread::SDRPostThread() :
|
SDRPostThread::SDRPostThread() : IOThread(),
|
||||||
iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), dcFilter(NULL), num_vis_samples(16384*2) {
|
iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), dcFilter(NULL), num_vis_samples(16384*2) {
|
||||||
|
|
||||||
terminated.store(false);
|
|
||||||
swapIQ.store(false);
|
swapIQ.store(false);
|
||||||
|
|
||||||
// create a lookup table
|
// create a lookup table
|
||||||
@ -51,16 +50,6 @@ void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) {
|
|||||||
busy_demod.unlock();
|
busy_demod.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRPostThread::setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
|
||||||
iqDataInQueue = iqDataQueue;
|
|
||||||
}
|
|
||||||
void SDRPostThread::setIQDataOutQueue(DemodulatorThreadInputQueue* iqDataQueue) {
|
|
||||||
iqDataOutQueue = iqDataQueue;
|
|
||||||
}
|
|
||||||
void SDRPostThread::setIQVisualQueue(DemodulatorThreadInputQueue *iqVisQueue) {
|
|
||||||
iqVisualQueue = iqVisQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDRPostThread::setNumVisSamples(int num_vis_samples_in) {
|
void SDRPostThread::setNumVisSamples(int num_vis_samples_in) {
|
||||||
num_vis_samples = num_vis_samples_in;
|
num_vis_samples = num_vis_samples_in;
|
||||||
}
|
}
|
||||||
@ -77,10 +66,7 @@ bool SDRPostThread::getSwapIQ() {
|
|||||||
return this->swapIQ.load();
|
return this->swapIQ.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRPostThread::threadMain() {
|
void SDRPostThread::run() {
|
||||||
int n_read;
|
|
||||||
double seconds = 0.0;
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t tID = pthread_self(); // ID of this thread
|
pthread_t tID = pthread_self(); // ID of this thread
|
||||||
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
||||||
@ -94,15 +80,18 @@ void SDRPostThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "SDR post-processing thread started.." << std::endl;
|
std::cout << "SDR post-processing thread started.." << std::endl;
|
||||||
|
|
||||||
std::deque<DemodulatorThreadIQData *> buffers;
|
iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput");
|
||||||
std::deque<DemodulatorThreadIQData *>::iterator buffers_i;
|
iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput");
|
||||||
|
iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOut");
|
||||||
|
|
||||||
|
ReBuffer<DemodulatorThreadIQData> buffers;
|
||||||
std::vector<liquid_float_complex> fpData;
|
std::vector<liquid_float_complex> fpData;
|
||||||
std::vector<liquid_float_complex> dataOut;
|
std::vector<liquid_float_complex> dataOut;
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
SDRThreadIQData *data_in;
|
SDRThreadIQData *data_in;
|
||||||
|
|
||||||
iqDataInQueue.load()->pop(data_in);
|
iqDataInQueue->pop(data_in);
|
||||||
// std::lock_guard < std::mutex > lock(data_in->m_mutex);
|
// std::lock_guard < std::mutex > lock(data_in->m_mutex);
|
||||||
|
|
||||||
if (data_in && data_in->data.size()) {
|
if (data_in && data_in->data.size()) {
|
||||||
@ -128,16 +117,16 @@ void SDRPostThread::threadMain() {
|
|||||||
|
|
||||||
iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
|
iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
|
||||||
|
|
||||||
if (iqDataOutQueue.load() != NULL) {
|
if (iqDataOutQueue != NULL) {
|
||||||
DemodulatorThreadIQData *pipeDataOut = new DemodulatorThreadIQData;
|
DemodulatorThreadIQData *pipeDataOut = new DemodulatorThreadIQData;
|
||||||
|
|
||||||
pipeDataOut->frequency = data_in->frequency;
|
pipeDataOut->frequency = data_in->frequency;
|
||||||
pipeDataOut->sampleRate = data_in->sampleRate;
|
pipeDataOut->sampleRate = data_in->sampleRate;
|
||||||
pipeDataOut->data.assign(dataOut.begin(), dataOut.end());
|
pipeDataOut->data.assign(dataOut.begin(), dataOut.end());
|
||||||
iqDataOutQueue.load()->push(pipeDataOut);
|
iqDataOutQueue->push(pipeDataOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iqVisualQueue.load() != NULL && iqVisualQueue.load()->empty()) {
|
if (iqVisualQueue != NULL && iqVisualQueue->empty()) {
|
||||||
|
|
||||||
visualDataOut->busy_rw.lock();
|
visualDataOut->busy_rw.lock();
|
||||||
|
|
||||||
@ -152,7 +141,7 @@ void SDRPostThread::threadMain() {
|
|||||||
visualDataOut->sampleRate = data_in->sampleRate;
|
visualDataOut->sampleRate = data_in->sampleRate;
|
||||||
visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples);
|
visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples);
|
||||||
|
|
||||||
iqVisualQueue.load()->push(visualDataOut);
|
iqVisualQueue->push(visualDataOut);
|
||||||
|
|
||||||
visualDataOut->busy_rw.unlock();
|
visualDataOut->busy_rw.unlock();
|
||||||
}
|
}
|
||||||
@ -176,19 +165,7 @@ void SDRPostThread::threadMain() {
|
|||||||
|
|
||||||
if (demodulators.size()) {
|
if (demodulators.size()) {
|
||||||
|
|
||||||
DemodulatorThreadIQData *demodDataOut = NULL;
|
DemodulatorThreadIQData *demodDataOut = buffers.getBuffer();
|
||||||
|
|
||||||
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
|
|
||||||
if ((*buffers_i)->getRefCount() <= 0) {
|
|
||||||
demodDataOut = (*buffers_i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demodDataOut == NULL) {
|
|
||||||
demodDataOut = new DemodulatorThreadIQData;
|
|
||||||
buffers.push_back(demodDataOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
|
// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
|
||||||
demodDataOut->frequency = data_in->frequency;
|
demodDataOut->frequency = data_in->frequency;
|
||||||
@ -199,7 +176,7 @@ void SDRPostThread::threadMain() {
|
|||||||
std::vector<DemodulatorInstance *>::iterator i;
|
std::vector<DemodulatorInstance *>::iterator i;
|
||||||
for (i = demodulators.begin(); i != demodulators.end(); i++) {
|
for (i = demodulators.begin(); i != demodulators.end(); i++) {
|
||||||
DemodulatorInstance *demod = *i;
|
DemodulatorInstance *demod = *i;
|
||||||
DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod;
|
DemodulatorThreadInputQueue *demodQueue = demod->getIQInputDataPipe();
|
||||||
|
|
||||||
if (abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
|
if (abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
|
||||||
if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
|
if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
|
||||||
@ -242,15 +219,11 @@ void SDRPostThread::threadMain() {
|
|||||||
data_in->decRefCount();
|
data_in->decRefCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
buffers.purge();
|
||||||
DemodulatorThreadIQData *demodDataDel = buffers.front();
|
|
||||||
buffers.pop_front();
|
if (iqVisualQueue && !iqVisualQueue->empty()) {
|
||||||
// std::lock_guard < std::mutex > lock(demodDataDel->m_mutex);
|
|
||||||
// delete demodDataDel;
|
|
||||||
}
|
|
||||||
if (iqVisualQueue.load() && !iqVisualQueue.load()->empty()) {
|
|
||||||
DemodulatorThreadIQData *visualDataDummy;
|
DemodulatorThreadIQData *visualDataDummy;
|
||||||
iqVisualQueue.load()->pop(visualDataDummy);
|
iqVisualQueue->pop(visualDataDummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete visualDataOut;
|
delete visualDataOut;
|
||||||
@ -261,5 +234,5 @@ void SDRPostThread::threadMain() {
|
|||||||
void SDRPostThread::terminate() {
|
void SDRPostThread::terminate() {
|
||||||
terminated = true;
|
terminated = true;
|
||||||
SDRThreadIQData *dummy = new SDRThreadIQData;
|
SDRThreadIQData *dummy = new SDRThreadIQData;
|
||||||
iqDataInQueue.load()->push(dummy);
|
iqDataInQueue->push(dummy);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "SDRThread.h"
|
#include "SDRThread.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
class SDRPostThread {
|
class SDRPostThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
SDRPostThread();
|
SDRPostThread();
|
||||||
~SDRPostThread();
|
~SDRPostThread();
|
||||||
@ -11,27 +11,22 @@ public:
|
|||||||
void bindDemodulator(DemodulatorInstance *demod);
|
void bindDemodulator(DemodulatorInstance *demod);
|
||||||
void removeDemodulator(DemodulatorInstance *demod);
|
void removeDemodulator(DemodulatorInstance *demod);
|
||||||
|
|
||||||
void setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue);
|
|
||||||
void setIQDataOutQueue(DemodulatorThreadInputQueue* iqDataQueue);
|
|
||||||
void setIQVisualQueue(DemodulatorThreadInputQueue* iqVisQueue);
|
|
||||||
|
|
||||||
void setNumVisSamples(int num_vis_samples_in);
|
void setNumVisSamples(int num_vis_samples_in);
|
||||||
int getNumVisSamples();
|
int getNumVisSamples();
|
||||||
|
|
||||||
void setSwapIQ(bool swapIQ);
|
void setSwapIQ(bool swapIQ);
|
||||||
bool getSwapIQ();
|
bool getSwapIQ();
|
||||||
|
|
||||||
void threadMain();
|
void run();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::atomic<SDRThreadIQDataQueue *> iqDataInQueue;
|
SDRThreadIQDataQueue *iqDataInQueue;
|
||||||
std::atomic<DemodulatorThreadInputQueue *> iqDataOutQueue;
|
DemodulatorThreadInputQueue *iqDataOutQueue;
|
||||||
std::atomic<DemodulatorThreadInputQueue *> iqVisualQueue;
|
DemodulatorThreadInputQueue *iqVisualQueue;
|
||||||
|
|
||||||
std::mutex busy_demod;
|
std::mutex busy_demod;
|
||||||
std::vector<DemodulatorInstance *> demodulators;
|
std::vector<DemodulatorInstance *> demodulators;
|
||||||
std::atomic_bool terminated;
|
|
||||||
iirfilt_crcf dcFilter;
|
iirfilt_crcf dcFilter;
|
||||||
int num_vis_samples;
|
int num_vis_samples;
|
||||||
std::atomic_bool swapIQ;
|
std::atomic_bool swapIQ;
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
SDRThread::SDRThread() : IOThread() {
|
||||||
commandQueue(pQueue), iqDataOutQueue(NULL) {
|
|
||||||
terminated.store(false);
|
|
||||||
offset.store(0);
|
offset.store(0);
|
||||||
deviceId.store(-1);
|
deviceId.store(-1);
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
@ -114,7 +112,7 @@ int SDRThread::enumerate_rtl(std::vector<SDRDeviceInfo *> *devs) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRThread::threadMain() {
|
void SDRThread::run() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pthread_t tID = pthread_self(); // ID of this thread
|
pthread_t tID = pthread_self(); // ID of this thread
|
||||||
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
|
||||||
@ -124,8 +122,6 @@ void SDRThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "SDR thread initializing.." << std::endl;
|
std::cout << "SDR thread initializing.." << std::endl;
|
||||||
|
|
||||||
int devCount = rtlsdr_get_device_count();
|
|
||||||
|
|
||||||
std::vector<SDRDeviceInfo *> devs;
|
std::vector<SDRDeviceInfo *> devs;
|
||||||
if (deviceId == -1) {
|
if (deviceId == -1) {
|
||||||
deviceId = enumerate_rtl(&devs);
|
deviceId = enumerate_rtl(&devs);
|
||||||
@ -168,12 +164,12 @@ void SDRThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "SDR thread started.." << std::endl;
|
std::cout << "SDR thread started.." << std::endl;
|
||||||
|
|
||||||
std::deque<SDRThreadIQData *> buffers;
|
ReBuffer<SDRThreadIQData> buffers;
|
||||||
std::deque<SDRThreadIQData *>::iterator buffers_i;
|
|
||||||
|
SDRThreadIQDataQueue* iqDataOutQueue = (SDRThreadIQDataQueue*) getOutputQueue("IQDataOutput");
|
||||||
|
SDRThreadCommandQueue* cmdQueue = (SDRThreadCommandQueue*) getInputQueue("SDRCommandQueue");
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
SDRThreadCommandQueue *cmdQueue = commandQueue.load();
|
|
||||||
|
|
||||||
if (!cmdQueue->empty()) {
|
if (!cmdQueue->empty()) {
|
||||||
bool freq_changed = false;
|
bool freq_changed = false;
|
||||||
bool offset_changed = false;
|
bool offset_changed = false;
|
||||||
@ -274,19 +270,7 @@ void SDRThread::threadMain() {
|
|||||||
|
|
||||||
rtlsdr_read_sync(dev, buf, buf_size, &n_read);
|
rtlsdr_read_sync(dev, buf, buf_size, &n_read);
|
||||||
|
|
||||||
SDRThreadIQData *dataOut = NULL;
|
SDRThreadIQData *dataOut = buffers.getBuffer();
|
||||||
|
|
||||||
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
|
|
||||||
if ((*buffers_i)->getRefCount() <= 0) {
|
|
||||||
dataOut = (*buffers_i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataOut == NULL) {
|
|
||||||
dataOut = new SDRThreadIQData;
|
|
||||||
buffers.push_back(dataOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
||||||
dataOut->setRefCount(1);
|
dataOut->setRefCount(1);
|
||||||
@ -306,21 +290,21 @@ void SDRThread::threadMain() {
|
|||||||
double time_slice = (double) n_read / (double) sampleRate.load();
|
double time_slice = (double) n_read / (double) sampleRate.load();
|
||||||
seconds += time_slice;
|
seconds += time_slice;
|
||||||
|
|
||||||
if (iqDataOutQueue.load() != NULL) {
|
if (iqDataOutQueue != NULL) {
|
||||||
iqDataOutQueue.load()->push(dataOut);
|
iqDataOutQueue->push(dataOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
buffers.purge();
|
||||||
SDRThreadIQData *iqDataDel = buffers.front();
|
|
||||||
buffers.pop_front();
|
|
||||||
// std::lock_guard < std::mutex > lock(iqDataDel->m_mutex);
|
|
||||||
// delete iqDataDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "SDR thread done." << std::endl;
|
std::cout << "SDR thread done." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRThread::terminate() {
|
|
||||||
terminated = true;
|
int SDRThread::getDeviceId() const {
|
||||||
|
return deviceId.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRThread::setDeviceId(int deviceId) {
|
||||||
|
this->deviceId.store(deviceId);
|
||||||
}
|
}
|
||||||
|
@ -6,77 +6,7 @@
|
|||||||
|
|
||||||
#include "ThreadQueue.h"
|
#include "ThreadQueue.h"
|
||||||
#include "DemodulatorMgr.h"
|
#include "DemodulatorMgr.h"
|
||||||
|
#include "SDRDeviceInfo.h"
|
||||||
class SDRDeviceInfo {
|
|
||||||
public:
|
|
||||||
SDRDeviceInfo() : name(""), serial(""), available(false) { }
|
|
||||||
|
|
||||||
std::string getDeviceId() {
|
|
||||||
std::string deviceId;
|
|
||||||
|
|
||||||
deviceId.append(getName());
|
|
||||||
deviceId.append(" :: ");
|
|
||||||
deviceId.append(getSerial());
|
|
||||||
|
|
||||||
return deviceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAvailable() const {
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAvailable(bool available) {
|
|
||||||
this->available = available;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getName() const {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setName(const std::string& name) {
|
|
||||||
this->name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getSerial() const {
|
|
||||||
return serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSerial(const std::string& serial) {
|
|
||||||
this->serial = serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getTuner() const {
|
|
||||||
return tuner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTuner(const std::string& tuner) {
|
|
||||||
this->tuner = tuner;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getManufacturer() const {
|
|
||||||
return manufacturer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setManufacturer(const std::string& manufacturer) {
|
|
||||||
this->manufacturer = manufacturer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getProduct() const {
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setProduct(const std::string& product) {
|
|
||||||
this->product = product;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
std::string serial;
|
|
||||||
std::string product;
|
|
||||||
std::string manufacturer;
|
|
||||||
std::string tuner;
|
|
||||||
bool available;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SDRThreadCommand {
|
class SDRThreadCommand {
|
||||||
public:
|
public:
|
||||||
@ -122,37 +52,22 @@ public:
|
|||||||
typedef ThreadQueue<SDRThreadCommand> SDRThreadCommandQueue;
|
typedef ThreadQueue<SDRThreadCommand> SDRThreadCommandQueue;
|
||||||
typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
|
typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
|
||||||
|
|
||||||
class SDRThread {
|
class SDRThread : public IOThread {
|
||||||
public:
|
public:
|
||||||
rtlsdr_dev_t *dev;
|
rtlsdr_dev_t *dev;
|
||||||
|
|
||||||
SDRThread(SDRThreadCommandQueue* pQueue);
|
SDRThread();
|
||||||
~SDRThread();
|
~SDRThread();
|
||||||
|
|
||||||
static int enumerate_rtl(std::vector<SDRDeviceInfo *> *devs);
|
static int enumerate_rtl(std::vector<SDRDeviceInfo *> *devs);
|
||||||
|
|
||||||
void threadMain();
|
void run();
|
||||||
|
|
||||||
void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
int getDeviceId() const;
|
||||||
iqDataOutQueue = iqDataQueue;
|
void setDeviceId(int deviceId);
|
||||||
}
|
|
||||||
|
|
||||||
void terminate();
|
|
||||||
|
|
||||||
int getDeviceId() const {
|
|
||||||
return deviceId.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDeviceId(int deviceId) {
|
|
||||||
this->deviceId.store(deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::atomic<uint32_t> sampleRate;
|
std::atomic<uint32_t> sampleRate;
|
||||||
std::atomic_llong offset;
|
std::atomic_llong offset;
|
||||||
std::atomic<SDRThreadCommandQueue*> commandQueue;
|
|
||||||
std::atomic<SDRThreadIQDataQueue*> iqDataOutQueue;
|
|
||||||
|
|
||||||
std::atomic_bool terminated;
|
|
||||||
std::atomic_int deviceId;
|
std::atomic_int deviceId;
|
||||||
};
|
};
|
||||||
|
400
src/ui/GLPanel.cpp
Normal file
400
src/ui/GLPanel.cpp
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
|
||||||
|
#include "GLPanel.h"
|
||||||
|
#include "cubic_math.h"
|
||||||
|
|
||||||
|
using namespace CubicVR;
|
||||||
|
|
||||||
|
GLPanel::GLPanel() : fillType(GLPANEL_FILL_SOLID), contentsVisible(true), transform(mat4::identity()) {
|
||||||
|
pos[0] = 0.0f;
|
||||||
|
pos[1] = 0.0f;
|
||||||
|
size[0] = 1.0f;
|
||||||
|
size[1] = 1.0f;
|
||||||
|
fill[0] = RGB(0.5,0.5,0.5);
|
||||||
|
fill[1] = RGB(0.1,0.1,0.1);
|
||||||
|
borderColor = RGB(0.8, 0.8, 0.8);
|
||||||
|
setCoordinateSystem(GLPANEL_Y_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::genArrays() {
|
||||||
|
float min = -1.0, mid = 0, max = 1.0;
|
||||||
|
|
||||||
|
if (fillType == GLPANEL_FILL_SOLID || fillType == GLPANEL_FILL_GRAD_X || fillType == GLPANEL_FILL_GRAD_Y) {
|
||||||
|
glPoints.reserve(2 * 4);
|
||||||
|
glPoints.resize(2 * 4);
|
||||||
|
glColors.reserve(3 * 4);
|
||||||
|
glColors.resize(3 * 4);
|
||||||
|
|
||||||
|
float pts[2 * 4] = {
|
||||||
|
min, min,
|
||||||
|
min, max,
|
||||||
|
max, max,
|
||||||
|
max, min
|
||||||
|
};
|
||||||
|
|
||||||
|
RGB c[4];
|
||||||
|
|
||||||
|
if (fillType == GLPANEL_FILL_SOLID) {
|
||||||
|
c[0] = c[1] = c[2] = c[3] = fill[0];
|
||||||
|
} else if (fillType == GLPANEL_FILL_GRAD_X) {
|
||||||
|
c[0] = c[1] = fill[0];
|
||||||
|
c[2] = c[3] = fill[1];
|
||||||
|
} else if (fillType == GLPANEL_FILL_GRAD_Y) {
|
||||||
|
c[0] = c[3] = fill[0];
|
||||||
|
c[1] = c[2] = fill[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float clr[3 * 4] = {
|
||||||
|
c[0].r, c[0].g, c[0].b,
|
||||||
|
c[1].r, c[1].g, c[1].b,
|
||||||
|
c[2].r, c[2].g, c[2].b,
|
||||||
|
c[3].r, c[3].g, c[3].b
|
||||||
|
};
|
||||||
|
|
||||||
|
glPoints.assign(pts, pts + (2 * 4));
|
||||||
|
glColors.assign(clr, clr + (3 * 4));
|
||||||
|
} else {
|
||||||
|
glPoints.reserve(2 * 8);
|
||||||
|
glPoints.resize(2 * 8);
|
||||||
|
glColors.reserve(3 * 8);
|
||||||
|
glColors.resize(3 * 8);
|
||||||
|
|
||||||
|
RGB c[8];
|
||||||
|
|
||||||
|
if (fillType == GLPANEL_FILL_GRAD_BAR_X) {
|
||||||
|
float pts[2 * 8] = {
|
||||||
|
min, min,
|
||||||
|
min, max,
|
||||||
|
mid, max,
|
||||||
|
mid, min,
|
||||||
|
|
||||||
|
mid, min,
|
||||||
|
mid, max,
|
||||||
|
max, max,
|
||||||
|
max, min
|
||||||
|
};
|
||||||
|
glPoints.assign(pts, pts + (2 * 8));
|
||||||
|
|
||||||
|
c[0] = c[1] = fill[0];
|
||||||
|
c[2] = c[3] = fill[1];
|
||||||
|
|
||||||
|
c[4] = c[5] = fill[1];
|
||||||
|
c[6] = c[7] = fill[0];
|
||||||
|
|
||||||
|
} else if (fillType == GLPANEL_FILL_GRAD_BAR_Y) {
|
||||||
|
float pts[2 * 8] = {
|
||||||
|
min, min,
|
||||||
|
min, mid,
|
||||||
|
max, mid,
|
||||||
|
max, min,
|
||||||
|
|
||||||
|
min, mid,
|
||||||
|
min, max,
|
||||||
|
max, max,
|
||||||
|
max, mid
|
||||||
|
};
|
||||||
|
glPoints.assign(pts, pts + (2 * 8));
|
||||||
|
|
||||||
|
c[0] = c[3] = fill[0];
|
||||||
|
c[1] = c[2] = fill[1];
|
||||||
|
|
||||||
|
c[4] = c[7] = fill[1];
|
||||||
|
c[5] = c[6] = fill[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
float clr[3 * 8] = {
|
||||||
|
c[0].r, c[0].g, c[0].b,
|
||||||
|
c[1].r, c[1].g, c[1].b,
|
||||||
|
c[2].r, c[2].g, c[2].b,
|
||||||
|
c[3].r, c[3].g, c[3].b,
|
||||||
|
c[4].r, c[4].g, c[4].b,
|
||||||
|
c[5].r, c[5].g, c[5].b,
|
||||||
|
c[6].r, c[6].g, c[6].b,
|
||||||
|
c[7].r, c[7].g, c[7].b
|
||||||
|
};
|
||||||
|
|
||||||
|
glColors.assign(clr, clr + (3 * 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLPanel::setViewport() {
|
||||||
|
GLint vp[4];
|
||||||
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
|
|
||||||
|
view[0] = vp[2];
|
||||||
|
view[1] = vp[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setPosition(float x, float y) {
|
||||||
|
pos[0] = x;
|
||||||
|
pos[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setSize(float w, float h) {
|
||||||
|
size[0] = w;
|
||||||
|
size[1] = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GLPanel::getWidth() {
|
||||||
|
return size[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
float GLPanel::getHeight() {
|
||||||
|
return size[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float GLPanel::getWidthPx() {
|
||||||
|
return pdim.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GLPanel::getHeightPx() {
|
||||||
|
return pdim.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLPanel::setCoordinateSystem(GLPanelCoordinateSystem coord_in) {
|
||||||
|
coord = coord_in;
|
||||||
|
|
||||||
|
if (coord == GLPANEL_Y_DOWN || coord == GLPANEL_Y_UP) {
|
||||||
|
min = -1;
|
||||||
|
mid = 0;
|
||||||
|
max = 1;
|
||||||
|
} else {
|
||||||
|
min = 0;
|
||||||
|
mid = 0.5;
|
||||||
|
max = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
genArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setFill(GLPanelFillType fill_mode) {
|
||||||
|
fillType = fill_mode;
|
||||||
|
genArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setFillColor(RGB color1) {
|
||||||
|
fill[0] = color1;
|
||||||
|
genArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setFillColor(RGB color1, RGB color2) {
|
||||||
|
fill[0] = color1;
|
||||||
|
fill[1] = color2;
|
||||||
|
genArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setMarginPx(float marg) {
|
||||||
|
marginPx = marg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLPanel::setBorderColor(RGB clr) {
|
||||||
|
borderColor = clr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setBorderPx(float bord) {
|
||||||
|
borderPx.left = borderPx.right = borderPx.top = borderPx.bottom = bord;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::setBorderPx(float bordl, float bordr, float bordt, float bordb) {
|
||||||
|
borderPx.left = bordl;
|
||||||
|
borderPx.right = bordr;
|
||||||
|
borderPx.top = bordt;
|
||||||
|
borderPx.bottom = bordb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::addChild(GLPanel *childPanel) {
|
||||||
|
children.push_back(childPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::drawChildren() {
|
||||||
|
if (children.size()) {
|
||||||
|
std::vector<GLPanel *>::iterator panel_i;
|
||||||
|
|
||||||
|
for (panel_i = children.begin(); panel_i != children.end(); panel_i++) {
|
||||||
|
(*panel_i)->calcTransform(transform);
|
||||||
|
(*panel_i)->draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::drawPanelContents() {
|
||||||
|
drawChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::calcTransform(mat4 transform_in) {
|
||||||
|
// compute local transform
|
||||||
|
localTransform = mat4::translate(pos[0], pos[1], 0) * mat4::scale(size[0], size[1], 0);
|
||||||
|
// compute global transform
|
||||||
|
transform = transform_in * localTransform;
|
||||||
|
|
||||||
|
// init view[]
|
||||||
|
setViewport();
|
||||||
|
|
||||||
|
// get min/max transform
|
||||||
|
vec4 vmin_t = mat4::vec4_multiply(vec4(min, min, 0, 1), transform);
|
||||||
|
vec4 vmax_t = mat4::vec4_multiply(vec4(max, max, 0, 1), transform);
|
||||||
|
|
||||||
|
// screen dimensions
|
||||||
|
vmin = vec2((vmin_t.x > vmax_t.x)?vmax_t.x:vmin_t.x, (vmin_t.y > vmax_t.y)?vmax_t.y:vmin_t.y);
|
||||||
|
vmax = vec2((vmin_t.x > vmax_t.x)?vmin_t.x:vmax_t.x, (vmin_t.y > vmax_t.y)?vmin_t.y:vmax_t.y);
|
||||||
|
|
||||||
|
// unit dimensions
|
||||||
|
umin = (vmin * 0.5) + vec2(1,1);
|
||||||
|
umax = (vmax * 0.5) + vec2(1,1);
|
||||||
|
|
||||||
|
ucenter = vec2((umin + umax) * 0.5);
|
||||||
|
|
||||||
|
// pixel dimensions
|
||||||
|
pdim = vec2((vmax.x - vmin.x) / 2.0 * view[0], (vmax.y - vmin.y) / 2.0 * view[1]);
|
||||||
|
pvec = vec2(((vmax.x - vmin.x) / 2.0) / pdim.x, ((vmax.y - vmin.y) / 2.0) / pdim.y);
|
||||||
|
|
||||||
|
std::cout << umin << " :: " << ucenter << " :: " << pdim << " :: " << pvec << std::endl;
|
||||||
|
|
||||||
|
if (marginPx) {
|
||||||
|
transform *= mat4::scale(1.0 - marginPx * 2.0 * pvec.x / size[0], 1.0 - marginPx * 2.0 * pvec.y / size[1], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLPanel::draw() {
|
||||||
|
float min = -1.0, max = 1.0;
|
||||||
|
|
||||||
|
glLoadMatrixf(transform);
|
||||||
|
|
||||||
|
if (fillType != GLPANEL_FILL_NONE) {
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, &glPoints[0]);
|
||||||
|
glColorPointer(3, GL_FLOAT, 0, &glColors[0]);
|
||||||
|
|
||||||
|
glDrawArrays(GL_QUADS, 0, glPoints.size() / 2);
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
if (borderPx.left || borderPx.right || borderPx.top || borderPx.bottom) {
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
glColor3f(borderColor.r, borderColor.g, borderColor.b);
|
||||||
|
|
||||||
|
if (borderPx.left) {
|
||||||
|
glLineWidth(borderPx.left);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(min, min);
|
||||||
|
glVertex2f(min, max);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderPx.right) {
|
||||||
|
glLineWidth(borderPx.right);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(max, min);
|
||||||
|
glVertex2f(max, max);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderPx.top) {
|
||||||
|
glLineWidth(borderPx.top);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(min, min);
|
||||||
|
glVertex2f(max, min);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderPx.bottom) {
|
||||||
|
glLineWidth(borderPx.bottom);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(min, max);
|
||||||
|
glVertex2f(max, max);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentsVisible) {
|
||||||
|
mat4 mCoord = mat4::identity();
|
||||||
|
|
||||||
|
if (coord == GLPANEL_Y_DOWN_ZERO_ONE) {
|
||||||
|
mCoord *= mat4::translate(-1.0f, 1.0f, 0.0f) * mat4::scale(2.0f, -2.0f, 2.0f);
|
||||||
|
}
|
||||||
|
if (coord == GLPANEL_Y_UP_ZERO_ONE) {
|
||||||
|
mCoord = mat4::translate(-1.0f, -1.0f, 0.0f) * mat4::scale(2.0f, 2.0f, 2.0f);
|
||||||
|
}
|
||||||
|
if (coord == GLPANEL_Y_DOWN) {
|
||||||
|
mCoord = mat4::scale(1.0f, -1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
// if (coord == GLPANEL_Y_UP) {
|
||||||
|
// }
|
||||||
|
glLoadMatrixf(transform * mCoord);
|
||||||
|
drawPanelContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLTextPanel::GLTextPanel() : GLPanel() {
|
||||||
|
coord = GLPANEL_Y_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTextPanel::drawPanelContents() {
|
||||||
|
glColor4f(1, 1, 1, 1.0);
|
||||||
|
|
||||||
|
GLFont::GLFontSize sz;
|
||||||
|
float size;
|
||||||
|
|
||||||
|
|
||||||
|
if (pdim.y < 16) {
|
||||||
|
sz = GLFont::GLFONT_SIZE12;
|
||||||
|
size = 12;
|
||||||
|
} else if (pdim.y < 18) {
|
||||||
|
sz = GLFont::GLFONT_SIZE16;
|
||||||
|
size = 16;
|
||||||
|
} else if(pdim.y < 24) {
|
||||||
|
sz = GLFont::GLFONT_SIZE18;
|
||||||
|
size = 18;
|
||||||
|
} else if(pdim.y < 32) {
|
||||||
|
sz = GLFont::GLFONT_SIZE24;
|
||||||
|
size = 24;
|
||||||
|
} else if(pdim.y < 48) {
|
||||||
|
sz = GLFont::GLFONT_SIZE32;
|
||||||
|
size = 32;
|
||||||
|
} else {
|
||||||
|
sz = GLFont::GLFONT_SIZE48;
|
||||||
|
size = 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLFont::getFont(sz).drawString(textVal, mid, mid, size, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, (int)pdim.x, (int)pdim.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTextPanel::setText(std::string text) {
|
||||||
|
textVal = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GLTextPanel::getText() {
|
||||||
|
return textVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLTestPanel::drawPanelContents() {
|
||||||
|
glColor3f(1.0,1.0,1.0);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(min, mid);
|
||||||
|
glVertex2f(max, mid);
|
||||||
|
glVertex2f(mid, min);
|
||||||
|
glVertex2f(mid, max);
|
||||||
|
|
||||||
|
glVertex2f(mid, max);
|
||||||
|
glVertex2f(mid - 0.02, max - 0.2);
|
||||||
|
glVertex2f(mid, 1);
|
||||||
|
glVertex2f(mid + 0.02, max - 0.2);
|
||||||
|
|
||||||
|
glVertex2f(max, mid);
|
||||||
|
glVertex2f(max - 0.1, mid + max * 0.25);
|
||||||
|
glVertex2f(max, mid);
|
||||||
|
glVertex2f(max - 0.1, mid - max * 0.25);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
106
src/ui/GLPanel.h
Normal file
106
src/ui/GLPanel.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "GLExt.h"
|
||||||
|
#include "GLFont.h"
|
||||||
|
#include "ColorTheme.h"
|
||||||
|
#include "cubic_math.h"
|
||||||
|
|
||||||
|
class GLPanelEdges {
|
||||||
|
public:
|
||||||
|
float left;
|
||||||
|
float right;
|
||||||
|
float top;
|
||||||
|
float bottom;
|
||||||
|
|
||||||
|
GLPanelEdges(): left(0), right(0), top(0), bottom(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GLPanelEdges(float l, float r, float t, float b) {
|
||||||
|
left = l;
|
||||||
|
right = r;
|
||||||
|
top = t;
|
||||||
|
bottom = b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLPanel {
|
||||||
|
private:
|
||||||
|
std::vector<float> glPoints;
|
||||||
|
std::vector<float> glColors;
|
||||||
|
|
||||||
|
void genArrays();
|
||||||
|
void setViewport();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef enum GLPanelFillType { GLPANEL_FILL_NONE, GLPANEL_FILL_SOLID, GLPANEL_FILL_GRAD_X, GLPANEL_FILL_GRAD_Y, GLPANEL_FILL_GRAD_BAR_X, GLPANEL_FILL_GRAD_BAR_Y } GLPanelFillType;
|
||||||
|
typedef enum GLPanelCoordinateSystem { GLPANEL_Y_DOWN_ZERO_ONE, GLPANEL_Y_UP_ZERO_ONE, GLPANEL_Y_UP, GLPANEL_Y_DOWN } GLPanelCoordinateSystem;
|
||||||
|
float pos[2];
|
||||||
|
float size[2];
|
||||||
|
float view[2];
|
||||||
|
GLPanelFillType fillType;
|
||||||
|
GLPanelCoordinateSystem coord;
|
||||||
|
float marginPx;
|
||||||
|
GLPanelEdges borderPx;
|
||||||
|
RGB fill[2];
|
||||||
|
RGB borderColor;
|
||||||
|
bool contentsVisible;
|
||||||
|
CubicVR::mat4 transform;
|
||||||
|
CubicVR::mat4 localTransform;
|
||||||
|
float min, mid, max;
|
||||||
|
// screen dimensions
|
||||||
|
CubicVR::vec2 vmin, vmax;
|
||||||
|
// unit dimensions
|
||||||
|
CubicVR::vec2 umin, umax, ucenter;
|
||||||
|
// pixel dimensions
|
||||||
|
CubicVR::vec2 pdim, pvec;
|
||||||
|
|
||||||
|
std::vector<GLPanel *> children;
|
||||||
|
|
||||||
|
GLPanel();
|
||||||
|
|
||||||
|
void setPosition(float x, float y);
|
||||||
|
void setSize(float w, float h);
|
||||||
|
float getWidth();
|
||||||
|
float getHeight();
|
||||||
|
float getWidthPx();
|
||||||
|
float getHeightPx();
|
||||||
|
void setCoordinateSystem(GLPanelCoordinateSystem coord);
|
||||||
|
|
||||||
|
void setFill(GLPanelFillType fill_mode);
|
||||||
|
void setFillColor(RGB color1);
|
||||||
|
void setFillColor(RGB color1, RGB color2);
|
||||||
|
void setMarginPx(float marg);
|
||||||
|
|
||||||
|
void setBorderColor(RGB clr);
|
||||||
|
void setBorderPx(float bord);
|
||||||
|
void setBorderPx(float bordl, float bordr, float bordt, float bordb);
|
||||||
|
|
||||||
|
void addChild(GLPanel *childPanel);
|
||||||
|
|
||||||
|
void drawChildren();
|
||||||
|
virtual void drawPanelContents();
|
||||||
|
void calcTransform(CubicVR::mat4 transform);
|
||||||
|
void draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GLTextPanel : public GLPanel {
|
||||||
|
private:
|
||||||
|
std::string textVal;
|
||||||
|
public:
|
||||||
|
GLTextPanel();
|
||||||
|
|
||||||
|
void drawPanelContents();
|
||||||
|
void setText(std::string text);
|
||||||
|
std::string getText();
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLTestPanel : public GLPanel {
|
||||||
|
public:
|
||||||
|
GLTestPanel() : GLPanel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawPanelContents();
|
||||||
|
};
|
85
src/ui/UITestCanvas.cpp
Normal file
85
src/ui/UITestCanvas.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "UITestCanvas.h"
|
||||||
|
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !wxUSE_GLCANVAS
|
||||||
|
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "CubicSDR.h"
|
||||||
|
#include "CubicSDRDefs.h"
|
||||||
|
#include "AppFrame.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
wxBEGIN_EVENT_TABLE(UITestCanvas, wxGLCanvas) EVT_PAINT(UITestCanvas::OnPaint)
|
||||||
|
EVT_IDLE(UITestCanvas::OnIdle)
|
||||||
|
EVT_MOTION(UITestCanvas::OnMouseMoved)
|
||||||
|
EVT_LEFT_DOWN(UITestCanvas::OnMouseDown)
|
||||||
|
EVT_LEFT_UP(UITestCanvas::OnMouseReleased)
|
||||||
|
EVT_LEAVE_WINDOW(UITestCanvas::OnMouseLeftWindow)
|
||||||
|
EVT_ENTER_WINDOW(UITestCanvas::OnMouseEnterWindow)
|
||||||
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
|
UITestCanvas::UITestCanvas(wxWindow *parent, int *attribList) :
|
||||||
|
InteractiveCanvas(parent, attribList) {
|
||||||
|
|
||||||
|
glContext = new UITestContext(this, &wxGetApp().GetContext(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
UITestCanvas::~UITestCanvas() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||||
|
wxPaintDC dc(this);
|
||||||
|
#ifdef __APPLE__ // force half-rate?
|
||||||
|
glFinish();
|
||||||
|
#endif
|
||||||
|
const wxSize ClientSize = GetClientSize();
|
||||||
|
|
||||||
|
glContext->SetCurrent(*this);
|
||||||
|
initGLExtensions();
|
||||||
|
|
||||||
|
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||||
|
|
||||||
|
glContext->DrawBegin();
|
||||||
|
|
||||||
|
glContext->Draw();
|
||||||
|
|
||||||
|
glContext->DrawEnd();
|
||||||
|
|
||||||
|
SwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::OnMouseMoved(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseDown(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::OnMouseDown(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseWheelMoved(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::OnMouseWheelMoved(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseReleased(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::OnMouseReleased(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::OnMouseLeftWindow(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestCanvas::OnMouseEnterWindow(wxMouseEvent& event) {
|
||||||
|
InteractiveCanvas::mouseTracker.OnMouseEnterWindow(event);
|
||||||
|
}
|
36
src/ui/UITestCanvas.h
Normal file
36
src/ui/UITestCanvas.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wx/glcanvas.h"
|
||||||
|
#include "wx/timer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "InteractiveCanvas.h"
|
||||||
|
#include "UITestContext.h"
|
||||||
|
#include "MouseTracker.h"
|
||||||
|
|
||||||
|
#include "fftw3.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
|
class UITestCanvas: public InteractiveCanvas {
|
||||||
|
public:
|
||||||
|
UITestCanvas(wxWindow *parent, int *attribList = NULL);
|
||||||
|
~UITestCanvas();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
void OnIdle(wxIdleEvent &event);
|
||||||
|
|
||||||
|
void OnMouseMoved(wxMouseEvent& event);
|
||||||
|
void OnMouseDown(wxMouseEvent& event);
|
||||||
|
void OnMouseWheelMoved(wxMouseEvent& event);
|
||||||
|
void OnMouseReleased(wxMouseEvent& event);
|
||||||
|
void OnMouseEnterWindow(wxMouseEvent& event);
|
||||||
|
void OnMouseLeftWindow(wxMouseEvent& event);
|
||||||
|
|
||||||
|
UITestContext *glContext;
|
||||||
|
|
||||||
|
wxDECLARE_EVENT_TABLE();
|
||||||
|
};
|
||||||
|
|
70
src/ui/UITestContext.cpp
Normal file
70
src/ui/UITestContext.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "UITestContext.h"
|
||||||
|
#include "UITestCanvas.h"
|
||||||
|
#include "ColorTheme.h"
|
||||||
|
|
||||||
|
UITestContext::UITestContext(UITestCanvas *canvas, wxGLContext *sharedContext) :
|
||||||
|
PrimaryGLContext(canvas, sharedContext) {
|
||||||
|
|
||||||
|
testPanel.setPosition(0.0, 0.0);
|
||||||
|
testPanel.setSize(1.0, 1.0);
|
||||||
|
testPanel.setMarginPx(10);
|
||||||
|
testPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_BAR_Y);
|
||||||
|
testPanel.setFillColor(RGB(0.0,0.0,1.0), RGB(0.0,1.0,0.0));
|
||||||
|
|
||||||
|
testChildPanel.setPosition(0.0, 0.0);
|
||||||
|
testChildPanel.setMarginPx(5);
|
||||||
|
testChildPanel.setSize(1.0, 0.33);
|
||||||
|
testChildPanel.setCoordinateSystem(GLPanel::GLPANEL_Y_DOWN_ZERO_ONE);
|
||||||
|
testChildPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_BAR_X);
|
||||||
|
testChildPanel.setFillColor(RGB(0.0,0.0,1.0), RGB(0.0,1.0,0.0));
|
||||||
|
testChildPanel.setBorderPx(1);
|
||||||
|
|
||||||
|
testChildPanel2.setPosition(0.0, -0.66);
|
||||||
|
testChildPanel2.setSize(1.0, 0.33);
|
||||||
|
testChildPanel2.setMarginPx(5);
|
||||||
|
testChildPanel2.setFill(GLPanel::GLPANEL_FILL_GRAD_X);
|
||||||
|
testChildPanel2.setFillColor(RGB(0.0,0.0,1.0), RGB(0.0,1.0,0.0));
|
||||||
|
testChildPanel2.setBorderColor(RGB(1.0,0.0,0.0));
|
||||||
|
testChildPanel2.setBorderPx(1);
|
||||||
|
|
||||||
|
testChildPanel3.setPosition(0.0, 0.66);
|
||||||
|
testChildPanel3.setSize(1.0, 0.33);
|
||||||
|
testChildPanel3.setMarginPx(5);
|
||||||
|
testChildPanel3.setFill(GLPanel::GLPANEL_FILL_GRAD_X);
|
||||||
|
testChildPanel3.setFillColor(RGB(0.0,0.0,1.0), RGB(0.0,1.0,0.0));
|
||||||
|
testChildPanel3.setBorderColor(RGB(1.0,0.0,0.0));
|
||||||
|
testChildPanel3.setBorderPx(1);
|
||||||
|
|
||||||
|
testText1.setText("Testing 123..");
|
||||||
|
testText1.setFill(GLPanel::GLPANEL_FILL_NONE);
|
||||||
|
testChildPanel2.addChild(&testText1);
|
||||||
|
|
||||||
|
testPanel.addChild(&testChildPanel);
|
||||||
|
testPanel.addChild(&testChildPanel2);
|
||||||
|
testPanel.addChild(&testChildPanel3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestContext::DrawBegin() {
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glClearColor(ThemeMgr::mgr.currentTheme->generalBackground.r, ThemeMgr::mgr.currentTheme->generalBackground.g, ThemeMgr::mgr.currentTheme->generalBackground.b, 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestContext::Draw() {
|
||||||
|
testPanel.calcTransform(CubicVR::mat4::identity());
|
||||||
|
testPanel.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITestContext::DrawEnd() {
|
||||||
|
glFlush();
|
||||||
|
|
||||||
|
CheckGLError();
|
||||||
|
}
|
||||||
|
|
22
src/ui/UITestContext.h
Normal file
22
src/ui/UITestContext.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "PrimaryGLContext.h"
|
||||||
|
#include "GLPanel.h"
|
||||||
|
|
||||||
|
class UITestCanvas;
|
||||||
|
|
||||||
|
class UITestContext: public PrimaryGLContext {
|
||||||
|
public:
|
||||||
|
UITestContext(UITestCanvas *canvas, wxGLContext *sharedContext);
|
||||||
|
|
||||||
|
void DrawBegin();
|
||||||
|
void Draw();
|
||||||
|
void DrawEnd();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLPanel testPanel;
|
||||||
|
GLTestPanel testChildPanel;
|
||||||
|
GLPanel testChildPanel2;
|
||||||
|
GLPanel testChildPanel3;
|
||||||
|
GLTextPanel testText1;
|
||||||
|
};
|
@ -8,6 +8,9 @@
|
|||||||
#define RES_FOLDER ""
|
#define RES_FOLDER ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
GLFont GLFont::fonts[GLFONT_MAX];
|
||||||
|
|
||||||
GLFontChar::GLFontChar() :
|
GLFontChar::GLFontChar() :
|
||||||
id(0), x(0), y(0), width(0), height(0), xoffset(0), yoffset(0), xadvance(0), aspect(1), index(0) {
|
id(0), x(0), y(0), width(0), height(0), xoffset(0), yoffset(0), xadvance(0), aspect(1), index(0) {
|
||||||
|
|
||||||
@ -394,16 +397,20 @@ float GLFont::getStringWidth(std::string str, float size, float viewAspect) {
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign, Align vAlign) {
|
void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign, Align vAlign, int vpx, int vpy) {
|
||||||
|
|
||||||
GLint vp[4];
|
|
||||||
|
|
||||||
pxHeight *= 2;
|
pxHeight *= 2;
|
||||||
|
|
||||||
|
if (!vpx || !vpy) {
|
||||||
|
GLint vp[4];
|
||||||
glGetIntegerv( GL_VIEWPORT, vp);
|
glGetIntegerv( GL_VIEWPORT, vp);
|
||||||
|
vpx = vp[2];
|
||||||
|
vpy = vp[3];
|
||||||
|
}
|
||||||
|
|
||||||
float size = (float) pxHeight / (float) vp[3];
|
float size = (float) pxHeight / (float) vpy;
|
||||||
float viewAspect = (float) vp[2] / (float) vp[3];
|
float viewAspect = (float) vpx / (float) vpy;
|
||||||
float msgWidth = getStringWidth(str, size, viewAspect);
|
float msgWidth = getStringWidth(str, size, viewAspect);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@ -475,3 +482,38 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
|
|||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLFont &GLFont::getFont(GLFontSize esize) {
|
||||||
|
if (!fonts[esize].isLoaded()) {
|
||||||
|
|
||||||
|
std::string fontName;
|
||||||
|
switch (esize) {
|
||||||
|
case GLFONT_SIZE12:
|
||||||
|
fontName = "vera_sans_mono12.fnt";
|
||||||
|
break;
|
||||||
|
case GLFONT_SIZE16:
|
||||||
|
fontName = "vera_sans_mono16.fnt";
|
||||||
|
break;
|
||||||
|
case GLFONT_SIZE18:
|
||||||
|
fontName = "vera_sans_mono18.fnt";
|
||||||
|
break;
|
||||||
|
case GLFONT_SIZE24:
|
||||||
|
fontName = "vera_sans_mono24.fnt";
|
||||||
|
break;
|
||||||
|
case GLFONT_SIZE32:
|
||||||
|
fontName = "vera_sans_mono32.fnt";
|
||||||
|
break;
|
||||||
|
case GLFONT_SIZE48:
|
||||||
|
fontName = "vera_sans_mono48.fnt";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fontName = "vera_sans_mono12.fnt";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fonts[esize].loadFont(fontName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fonts[esize];
|
||||||
|
}
|
||||||
|
@ -56,6 +56,9 @@ public:
|
|||||||
enum Align {
|
enum Align {
|
||||||
GLFONT_ALIGN_LEFT, GLFONT_ALIGN_RIGHT, GLFONT_ALIGN_CENTER, GLFONT_ALIGN_TOP, GLFONT_ALIGN_BOTTOM
|
GLFONT_ALIGN_LEFT, GLFONT_ALIGN_RIGHT, GLFONT_ALIGN_CENTER, GLFONT_ALIGN_TOP, GLFONT_ALIGN_BOTTOM
|
||||||
};
|
};
|
||||||
|
enum GLFontSize {
|
||||||
|
GLFONT_SIZE12, GLFONT_SIZE16, GLFONT_SIZE18, GLFONT_SIZE24, GLFONT_SIZE32, GLFONT_SIZE48, GLFONT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
GLFont();
|
GLFont();
|
||||||
~GLFont();
|
~GLFont();
|
||||||
@ -63,7 +66,10 @@ public:
|
|||||||
bool isLoaded();
|
bool isLoaded();
|
||||||
|
|
||||||
float getStringWidth(std::string str, float size, float viewAspect);
|
float getStringWidth(std::string str, float size, float viewAspect);
|
||||||
void drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP);
|
void drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx=0, int vpy=0);
|
||||||
|
|
||||||
|
static GLFont fonts[GLFONT_MAX];
|
||||||
|
static GLFont &getFont(GLFontSize esize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string nextParam(std::istringstream &str);
|
std::string nextParam(std::istringstream &str);
|
||||||
|
@ -15,9 +15,13 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
|
class ThreadQueueBase {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/** A thread-safe asynchronous queue */
|
/** A thread-safe asynchronous queue */
|
||||||
template<class T, class Container = std::list<T>>
|
template<class T, class Container = std::list<T>>
|
||||||
class ThreadQueue {
|
class ThreadQueue : public ThreadQueueBase {
|
||||||
|
|
||||||
typedef typename Container::value_type value_type;
|
typedef typename Container::value_type value_type;
|
||||||
typedef typename Container::size_type size_type;
|
typedef typename Container::size_type size_type;
|
||||||
|
@ -41,27 +41,27 @@ DefaultColorTheme::DefaultColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(1.0, 1.0, 0));
|
waterfallGradient.addColor(GradientColor(1.0, 1.0, 0));
|
||||||
waterfallGradient.addColor(GradientColor(1.0, 0.2, 0.0));
|
waterfallGradient.addColor(GradientColor(1.0, 0.2, 0.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 1);
|
waterfallHighlight = RGB(1, 1, 1);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(0.9, 0.9, 0.9);
|
fftLine = RGB(0.9, 0.9, 0.9);
|
||||||
fftHighlight = RGBColor(1, 1, 1);
|
fftHighlight = RGB(1, 1, 1);
|
||||||
scopeLine = RGBColor(0.9, 0.9, 0.9);
|
scopeLine = RGB(0.9, 0.9, 0.9);
|
||||||
tuningBarLight = RGBColor(0.2, 0.2, 0.9);
|
tuningBarLight = RGB(0.2, 0.2, 0.9);
|
||||||
tuningBarDark = RGBColor(0.0, 0.0, 0.35);
|
tuningBarDark = RGB(0.0, 0.0, 0.35);
|
||||||
tuningBarUp = RGBColor(1.0, 139.0/255.0, 96.0/255.0);
|
tuningBarUp = RGB(1.0, 139.0/255.0, 96.0/255.0);
|
||||||
tuningBarDown = RGBColor(148.0/255.0, 148.0/255.0, 1.0);
|
tuningBarDown = RGB(148.0/255.0, 148.0/255.0, 1.0);
|
||||||
meterLevel = RGBColor(0.1, 0.75, 0.1);
|
meterLevel = RGB(0.1, 0.75, 0.1);
|
||||||
meterValue = RGBColor(0.75, 0.1, 0.1);
|
meterValue = RGB(0.75, 0.1, 0.1);
|
||||||
text = RGBColor(1, 1, 1);
|
text = RGB(1, 1, 1);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(0.65, 0.65, 0.65);
|
button = RGB(0.65, 0.65, 0.65);
|
||||||
buttonHighlight = RGBColor(1, 1, 0);
|
buttonHighlight = RGB(1, 1, 0);
|
||||||
|
|
||||||
scopeBackground = RGBColor(0.1, 0.1, 0.1);
|
scopeBackground = RGB(0.1, 0.1, 0.1);
|
||||||
fftBackground = RGBColor(0.1, 0.1, 0.1);
|
fftBackground = RGB(0.1, 0.1, 0.1);
|
||||||
generalBackground = RGBColor(0.1, 0.1, 0.1);
|
generalBackground = RGB(0.1, 0.1, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -72,27 +72,27 @@ RadarColorTheme::RadarColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(40.0 / 255.0, 240.0 / 255.0, 60.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(40.0 / 255.0, 240.0 / 255.0, 60.0 / 255.0));
|
||||||
waterfallGradient.addColor(GradientColor(250.0 / 255.0, 250.0 / 255.0, 250.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(250.0 / 255.0, 250.0 / 255.0, 250.0 / 255.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 1);
|
waterfallHighlight = RGB(1, 1, 1);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(0.8, 1.0, 0.8);
|
fftLine = RGB(0.8, 1.0, 0.8);
|
||||||
fftHighlight = RGBColor(1, 1, 1);
|
fftHighlight = RGB(1, 1, 1);
|
||||||
scopeLine = RGBColor(0.8, 1.0, 0.8);
|
scopeLine = RGB(0.8, 1.0, 0.8);
|
||||||
tuningBarLight = RGBColor(0.0, 0.45, 0.0);
|
tuningBarLight = RGB(0.0, 0.45, 0.0);
|
||||||
tuningBarDark = RGBColor(0.0, 0.1, 0.0);
|
tuningBarDark = RGB(0.0, 0.1, 0.0);
|
||||||
tuningBarUp = RGBColor(1.0, 139.0/255.0, 96.0/255.0);
|
tuningBarUp = RGB(1.0, 139.0/255.0, 96.0/255.0);
|
||||||
tuningBarDown = RGBColor(148.0/255.0, 0.0, 0.0);
|
tuningBarDown = RGB(148.0/255.0, 0.0, 0.0);
|
||||||
meterLevel = RGBColor(0, 0.5, 0);
|
meterLevel = RGB(0, 0.5, 0);
|
||||||
meterValue = RGBColor(0, 0.5, 0);
|
meterValue = RGB(0, 0.5, 0);
|
||||||
text = RGBColor(0.8, 1.0, 0.8);
|
text = RGB(0.8, 1.0, 0.8);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(0.65, 0.75, 0.65);
|
button = RGB(0.65, 0.75, 0.65);
|
||||||
buttonHighlight = RGBColor(0.65, 1.0, 0.65);
|
buttonHighlight = RGB(0.65, 1.0, 0.65);
|
||||||
|
|
||||||
scopeBackground = RGBColor(0.05, 0.1, 0.05);
|
scopeBackground = RGB(0.05, 0.1, 0.05);
|
||||||
fftBackground = RGBColor(0.05, 0.1, 0.05);
|
fftBackground = RGB(0.05, 0.1, 0.05);
|
||||||
generalBackground = RGBColor(0.05, 0.1, 0.05);
|
generalBackground = RGB(0.05, 0.1, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackAndWhiteColorTheme::BlackAndWhiteColorTheme() {
|
BlackAndWhiteColorTheme::BlackAndWhiteColorTheme() {
|
||||||
@ -101,27 +101,27 @@ BlackAndWhiteColorTheme::BlackAndWhiteColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(0.75, 0.75, 0.75));
|
waterfallGradient.addColor(GradientColor(0.75, 0.75, 0.75));
|
||||||
waterfallGradient.addColor(GradientColor(1.0, 1.0, 1.0));
|
waterfallGradient.addColor(GradientColor(1.0, 1.0, 1.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 0.9);
|
waterfallHighlight = RGB(1, 1, 0.9);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(0.9, 0.9, 0.9);
|
fftLine = RGB(0.9, 0.9, 0.9);
|
||||||
fftHighlight = RGBColor(1, 1, 0.9);
|
fftHighlight = RGB(1, 1, 0.9);
|
||||||
scopeLine = RGBColor(0.9, 0.9, 0.9);
|
scopeLine = RGB(0.9, 0.9, 0.9);
|
||||||
tuningBarLight = RGBColor(0.4, 0.4, 0.4);
|
tuningBarLight = RGB(0.4, 0.4, 0.4);
|
||||||
tuningBarDark = RGBColor(0.1, 0.1, 0.1);
|
tuningBarDark = RGB(0.1, 0.1, 0.1);
|
||||||
tuningBarUp = RGBColor(0.8, 0.8, 0.8);
|
tuningBarUp = RGB(0.8, 0.8, 0.8);
|
||||||
tuningBarDown = RGBColor(0.4, 0.4, 0.4);
|
tuningBarDown = RGB(0.4, 0.4, 0.4);
|
||||||
meterLevel = RGBColor(0.5, 0.5, 0.5);
|
meterLevel = RGB(0.5, 0.5, 0.5);
|
||||||
meterValue = RGBColor(0.5, 0.5, 0.5);
|
meterValue = RGB(0.5, 0.5, 0.5);
|
||||||
text = RGBColor(1, 1, 1);
|
text = RGB(1, 1, 1);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(0.65, 0.65, 0.65);
|
button = RGB(0.65, 0.65, 0.65);
|
||||||
buttonHighlight = RGBColor(1, 1, 1);
|
buttonHighlight = RGB(1, 1, 1);
|
||||||
|
|
||||||
scopeBackground = RGBColor(0.1, 0.1, 0.1);
|
scopeBackground = RGB(0.1, 0.1, 0.1);
|
||||||
fftBackground = RGBColor(0.1, 0.1, 0.1);
|
fftBackground = RGB(0.1, 0.1, 0.1);
|
||||||
generalBackground = RGBColor(0.1, 0.1, 0.1);
|
generalBackground = RGB(0.1, 0.1, 0.1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,27 +139,27 @@ SharpColorTheme::SharpColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(1.0, 0.25, 0.0));
|
waterfallGradient.addColor(GradientColor(1.0, 0.25, 0.0));
|
||||||
waterfallGradient.addColor(GradientColor(0.5, 0.1, 0.0));
|
waterfallGradient.addColor(GradientColor(0.5, 0.1, 0.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(0.9, 0.9, 1.0);
|
waterfallHighlight = RGB(0.9, 0.9, 1.0);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(0.9, 0.9, 1.0);
|
fftLine = RGB(0.9, 0.9, 1.0);
|
||||||
fftHighlight = RGBColor(0.9, 0.9, 1.0);
|
fftHighlight = RGB(0.9, 0.9, 1.0);
|
||||||
scopeLine = RGBColor(0.85, 0.85, 1.0);
|
scopeLine = RGB(0.85, 0.85, 1.0);
|
||||||
tuningBarLight = RGBColor(28.0 / 255.0, 106.0 / 255.0, 179.0 / 255.0);
|
tuningBarLight = RGB(28.0 / 255.0, 106.0 / 255.0, 179.0 / 255.0);
|
||||||
tuningBarDark = RGBColor(14.0 / 255.0, 53.0 / 255.0, 89.5 / 255.0);
|
tuningBarDark = RGB(14.0 / 255.0, 53.0 / 255.0, 89.5 / 255.0);
|
||||||
tuningBarUp = RGBColor(0.7, 0.7, 0.7);
|
tuningBarUp = RGB(0.7, 0.7, 0.7);
|
||||||
tuningBarDown = RGBColor(1.0, 0.0, 0.0);
|
tuningBarDown = RGB(1.0, 0.0, 0.0);
|
||||||
meterLevel = RGBColor(28.0 / 255.0, 106.0 / 255.0, 179.0 / 255.0);
|
meterLevel = RGB(28.0 / 255.0, 106.0 / 255.0, 179.0 / 255.0);
|
||||||
meterValue = RGBColor(190.0 / 255.0, 190.0 / 255.0, 60.0 / 255.0);
|
meterValue = RGB(190.0 / 255.0, 190.0 / 255.0, 60.0 / 255.0);
|
||||||
text = RGBColor(0.9, 0.9, 1);
|
text = RGB(0.9, 0.9, 1);
|
||||||
freqLine = RGBColor(0.85, 0.85, 1.0);
|
freqLine = RGB(0.85, 0.85, 1.0);
|
||||||
button = RGBColor(217.0 / 255.0, 218.0 / 255.0, 228.0 / 255.0);
|
button = RGB(217.0 / 255.0, 218.0 / 255.0, 228.0 / 255.0);
|
||||||
buttonHighlight = RGBColor(208.0 / 255.0, 249.0 / 255.0, 255.0 / 255.0);
|
buttonHighlight = RGB(208.0 / 255.0, 249.0 / 255.0, 255.0 / 255.0);
|
||||||
|
|
||||||
scopeBackground = RGBColor(0.05, 0.05, 0.15);
|
scopeBackground = RGB(0.05, 0.05, 0.15);
|
||||||
fftBackground = RGBColor(0.05, 0.05, 0.15);
|
fftBackground = RGB(0.05, 0.05, 0.15);
|
||||||
generalBackground = RGBColor(0.05, 0.05, 0.15);
|
generalBackground = RGB(0.05, 0.05, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
RadColorTheme::RadColorTheme() {
|
RadColorTheme::RadColorTheme() {
|
||||||
@ -170,27 +170,27 @@ RadColorTheme::RadColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(1.0, 40.0 / 255.0, 40.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(1.0, 40.0 / 255.0, 40.0 / 255.0));
|
||||||
waterfallGradient.addColor(GradientColor(1.0, 1.0, 1.0));
|
waterfallGradient.addColor(GradientColor(1.0, 1.0, 1.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 1);
|
waterfallHighlight = RGB(1, 1, 1);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(1.0, 0.9, 0.9);
|
fftLine = RGB(1.0, 0.9, 0.9);
|
||||||
fftHighlight = RGBColor(1, 1, 1);
|
fftHighlight = RGB(1, 1, 1);
|
||||||
scopeLine = RGBColor(1.0, 0.9, 0.9);
|
scopeLine = RGB(1.0, 0.9, 0.9);
|
||||||
tuningBarLight = RGBColor(0.0, 0.45, 0.0);
|
tuningBarLight = RGB(0.0, 0.45, 0.0);
|
||||||
tuningBarDark = RGBColor(0.0, 0.1, 0.0);
|
tuningBarDark = RGB(0.0, 0.1, 0.0);
|
||||||
tuningBarUp = RGBColor(1.0, 0.0, 0.0);
|
tuningBarUp = RGB(1.0, 0.0, 0.0);
|
||||||
tuningBarDown = RGBColor(0.0, 0.5, 1.0);
|
tuningBarDown = RGB(0.0, 0.5, 1.0);
|
||||||
meterLevel = RGBColor(0, 0.5, 0);
|
meterLevel = RGB(0, 0.5, 0);
|
||||||
meterValue = RGBColor(0.5, 0, 0);
|
meterValue = RGB(0.5, 0, 0);
|
||||||
text = RGBColor(1, 1, 1);
|
text = RGB(1, 1, 1);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(0.65, 0.65, 0.65);
|
button = RGB(0.65, 0.65, 0.65);
|
||||||
buttonHighlight = RGBColor(0.76, 0.65, 0);
|
buttonHighlight = RGB(0.76, 0.65, 0);
|
||||||
|
|
||||||
scopeBackground = RGBColor(13.0 / 255.0, 47.0 / 255.0, 9.0 / 255.0);
|
scopeBackground = RGB(13.0 / 255.0, 47.0 / 255.0, 9.0 / 255.0);
|
||||||
fftBackground = RGBColor(0, 0, 50.0 / 255.0);
|
fftBackground = RGB(0, 0, 50.0 / 255.0);
|
||||||
generalBackground = RGBColor(13.0 / 255.0, 47.0 / 255.0, 9.0 / 255.0);
|
generalBackground = RGB(13.0 / 255.0, 47.0 / 255.0, 9.0 / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchColorTheme::TouchColorTheme() {
|
TouchColorTheme::TouchColorTheme() {
|
||||||
@ -204,27 +204,27 @@ TouchColorTheme::TouchColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0));
|
||||||
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 255.0 / 255.0, 255.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 255.0 / 255.0, 255.0 / 255.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 1);
|
waterfallHighlight = RGB(1, 1, 1);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(234.0 / 255.0, 232.0 / 255.0, 247.0 / 255.0);
|
fftLine = RGB(234.0 / 255.0, 232.0 / 255.0, 247.0 / 255.0);
|
||||||
fftHighlight = RGBColor(1.0, 1.0, 1.0);
|
fftHighlight = RGB(1.0, 1.0, 1.0);
|
||||||
scopeLine = RGBColor(234.0 / 255.0, 232.0 / 255.0, 247.0 / 255.0);
|
scopeLine = RGB(234.0 / 255.0, 232.0 / 255.0, 247.0 / 255.0);
|
||||||
tuningBarLight = RGBColor(0.2, 0.2, 0.7);
|
tuningBarLight = RGB(0.2, 0.2, 0.7);
|
||||||
tuningBarDark = RGBColor(0.1, 0.1, 0.45);
|
tuningBarDark = RGB(0.1, 0.1, 0.45);
|
||||||
tuningBarUp = RGBColor(0.5, 139.0/255.0, 96.0/255.0);
|
tuningBarUp = RGB(0.5, 139.0/255.0, 96.0/255.0);
|
||||||
tuningBarDown = RGBColor(0.6, 108.0/255.0, 1.0);
|
tuningBarDown = RGB(0.6, 108.0/255.0, 1.0);
|
||||||
meterLevel = RGBColor(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
meterLevel = RGB(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
||||||
meterValue = RGBColor(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
meterValue = RGB(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
||||||
text = RGBColor(1, 1, 1);
|
text = RGB(1, 1, 1);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(1.0, 1.0, 1.0);
|
button = RGB(1.0, 1.0, 1.0);
|
||||||
buttonHighlight = RGBColor(208.0 / 255.0, 202.0 / 255.0, 247.0 / 255.0);
|
buttonHighlight = RGB(208.0 / 255.0, 202.0 / 255.0, 247.0 / 255.0);
|
||||||
|
|
||||||
scopeBackground = RGBColor(39.0 / 255.0, 36.0 / 255.0, 56.0 / 255.0);
|
scopeBackground = RGB(39.0 / 255.0, 36.0 / 255.0, 56.0 / 255.0);
|
||||||
fftBackground = RGBColor(39.0 / 255.0, 36.0 / 255.0, 56.0 / 255.0);
|
fftBackground = RGB(39.0 / 255.0, 36.0 / 255.0, 56.0 / 255.0);
|
||||||
generalBackground = RGBColor(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
generalBackground = RGB(61.0 / 255.0, 57.0 / 255.0, 88.0 / 255.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,27 +239,27 @@ HDColorTheme::HDColorTheme() {
|
|||||||
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 235.0 / 255.0, 100.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(255.0 / 255.0, 235.0 / 255.0, 100.0 / 255.0));
|
||||||
waterfallGradient.addColor(GradientColor(250.0 / 255.0, 250.0 / 255.0, 250.0 / 255.0));
|
waterfallGradient.addColor(GradientColor(250.0 / 255.0, 250.0 / 255.0, 250.0 / 255.0));
|
||||||
waterfallGradient.generate(256);
|
waterfallGradient.generate(256);
|
||||||
waterfallHighlight = RGBColor(1, 1, 1);
|
waterfallHighlight = RGB(1, 1, 1);
|
||||||
waterfallNew = RGBColor(0, 1, 0);
|
waterfallNew = RGB(0, 1, 0);
|
||||||
waterfallHover = RGBColor(1, 1, 0);
|
waterfallHover = RGB(1, 1, 0);
|
||||||
waterfallDestroy = RGBColor(1, 0, 0);
|
waterfallDestroy = RGB(1, 0, 0);
|
||||||
fftLine = RGBColor(0.9, 0.9, 0.9);
|
fftLine = RGB(0.9, 0.9, 0.9);
|
||||||
fftHighlight = RGBColor(1, 1, 1);
|
fftHighlight = RGB(1, 1, 1);
|
||||||
scopeLine = RGBColor(0.9, 0.9, 0.9);
|
scopeLine = RGB(0.9, 0.9, 0.9);
|
||||||
tuningBarLight = RGBColor(0.4, 0.4, 1.0);
|
tuningBarLight = RGB(0.4, 0.4, 1.0);
|
||||||
tuningBarDark = RGBColor(0.1, 0.1, 0.45);
|
tuningBarDark = RGB(0.1, 0.1, 0.45);
|
||||||
tuningBarUp = RGBColor(1.0, 139.0/255.0, 96.0/255.0);
|
tuningBarUp = RGB(1.0, 139.0/255.0, 96.0/255.0);
|
||||||
tuningBarDown = RGBColor(148.0/255.0, 148.0/255.0, 1.0);
|
tuningBarDown = RGB(148.0/255.0, 148.0/255.0, 1.0);
|
||||||
meterLevel = RGBColor(0, 0.5, 0);
|
meterLevel = RGB(0, 0.5, 0);
|
||||||
meterValue = RGBColor(0.0, 0.0, 1.0);
|
meterValue = RGB(0.0, 0.0, 1.0);
|
||||||
text = RGBColor(1, 1, 1);
|
text = RGB(1, 1, 1);
|
||||||
freqLine = RGBColor(1, 1, 1);
|
freqLine = RGB(1, 1, 1);
|
||||||
button = RGBColor(0, 0.7, 0.7);
|
button = RGB(0, 0.7, 0.7);
|
||||||
buttonHighlight = RGBColor(1, 1, 1);
|
buttonHighlight = RGB(1, 1, 1);
|
||||||
|
|
||||||
scopeBackground = RGBColor(0.0, 0.0, 48.0 / 255.0);
|
scopeBackground = RGB(0.0, 0.0, 48.0 / 255.0);
|
||||||
fftBackground = RGBColor(0.0, 0.0, 48.0 / 255.0);
|
fftBackground = RGB(0.0, 0.0, 48.0 / 255.0);
|
||||||
generalBackground = RGBColor(0.0, 0.0, 0.0);
|
generalBackground = RGB(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,21 +15,21 @@
|
|||||||
#define COLOR_THEME_RADAR 6
|
#define COLOR_THEME_RADAR 6
|
||||||
#define COLOR_THEME_MAX 7
|
#define COLOR_THEME_MAX 7
|
||||||
|
|
||||||
class RGBColor {
|
class RGB {
|
||||||
public:
|
public:
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
RGBColor(float r, float g, float b) :
|
RGB(float r, float g, float b) :
|
||||||
r(r), g(g), b(b) {
|
r(r), g(g), b(b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBColor() :
|
RGB() :
|
||||||
RGBColor(0, 0, 0) {
|
RGB(0, 0, 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~RGBColor() {
|
~RGB() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBColor & operator=(const RGBColor &other) {
|
RGB & operator=(const RGB &other) {
|
||||||
r = other.r;
|
r = other.r;
|
||||||
g = other.g;
|
g = other.g;
|
||||||
b = other.b;
|
b = other.b;
|
||||||
@ -39,28 +39,28 @@ public:
|
|||||||
|
|
||||||
class ColorTheme {
|
class ColorTheme {
|
||||||
public:
|
public:
|
||||||
RGBColor waterfallHighlight;
|
RGB waterfallHighlight;
|
||||||
RGBColor waterfallNew;
|
RGB waterfallNew;
|
||||||
RGBColor wfHighlight;
|
RGB wfHighlight;
|
||||||
RGBColor waterfallHover;
|
RGB waterfallHover;
|
||||||
RGBColor waterfallDestroy;
|
RGB waterfallDestroy;
|
||||||
RGBColor fftLine;
|
RGB fftLine;
|
||||||
RGBColor fftHighlight;
|
RGB fftHighlight;
|
||||||
RGBColor scopeLine;
|
RGB scopeLine;
|
||||||
RGBColor tuningBarLight;
|
RGB tuningBarLight;
|
||||||
RGBColor tuningBarDark;
|
RGB tuningBarDark;
|
||||||
RGBColor tuningBarUp;
|
RGB tuningBarUp;
|
||||||
RGBColor tuningBarDown;
|
RGB tuningBarDown;
|
||||||
RGBColor meterLevel;
|
RGB meterLevel;
|
||||||
RGBColor meterValue;
|
RGB meterValue;
|
||||||
RGBColor text;
|
RGB text;
|
||||||
RGBColor freqLine;
|
RGB freqLine;
|
||||||
RGBColor button;
|
RGB button;
|
||||||
RGBColor buttonHighlight;
|
RGB buttonHighlight;
|
||||||
|
|
||||||
RGBColor scopeBackground;
|
RGB scopeBackground;
|
||||||
RGBColor fftBackground;
|
RGB fftBackground;
|
||||||
RGBColor generalBackground;
|
RGB generalBackground;
|
||||||
|
|
||||||
Gradient waterfallGradient;
|
Gradient waterfallGradient;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ EVT_ENTER_WINDOW(ModeSelectorCanvas::OnMouseEnterWindow)
|
|||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
ModeSelectorCanvas::ModeSelectorCanvas(wxWindow *parent, int *attribList) :
|
ModeSelectorCanvas::ModeSelectorCanvas(wxWindow *parent, int *attribList) :
|
||||||
InteractiveCanvas(parent, attribList), currentSelection(-1), numChoices(0) {
|
InteractiveCanvas(parent, attribList), numChoices(0), currentSelection(-1) {
|
||||||
|
|
||||||
glContext = new ModeSelectorContext(this, &wxGetApp().GetContext(this));
|
glContext = new ModeSelectorContext(this, &wxGetApp().GetContext(this));
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ void ModeSelectorContext::DrawSelector(std::string label, int c, int cMax, bool
|
|||||||
float viewHeight = (float) vp[3];
|
float viewHeight = (float) vp[3];
|
||||||
float viewWidth = (float) vp[2];
|
float viewWidth = (float) vp[2];
|
||||||
|
|
||||||
PrimaryGLContext::GLFontSize fontSize = GLFONT_SIZE16;
|
GLFont::GLFontSize fontSize = GLFont::GLFONT_SIZE16;
|
||||||
|
|
||||||
int fontHeight = 16;
|
int fontHeight = 16;
|
||||||
|
|
||||||
if (viewWidth < 30) {
|
if (viewWidth < 30) {
|
||||||
fontSize = GLFONT_SIZE12;
|
fontSize = GLFont::GLFONT_SIZE12;
|
||||||
fontHeight = 12;
|
fontHeight = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ void ModeSelectorContext::DrawSelector(std::string label, int c, int cMax, bool
|
|||||||
glColor4f(0, 0, 0, a);
|
glColor4f(0, 0, 0, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFont(fontSize).drawString(label, 0.0, y + height / 2.0, fontHeight, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(fontSize).drawString(label, 0.0, y + height / 2.0, fontHeight, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModeSelectorContext::DrawEnd() {
|
void ModeSelectorContext::DrawEnd() {
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
#include "AppFrame.h"
|
#include "AppFrame.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
GLFont PrimaryGLContext::fonts[GLFONT_MAX];
|
|
||||||
|
|
||||||
wxString PrimaryGLContext::glGetwxString(GLenum name) {
|
wxString PrimaryGLContext::glGetwxString(GLenum name) {
|
||||||
const GLubyte *v = glGetString(name);
|
const GLubyte *v = glGetString(name);
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
@ -61,41 +59,7 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas, wxGLContext *sharedContex
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFont &PrimaryGLContext::getFont(GLFontSize esize) {
|
void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGB color, long long center_freq, long long srate) {
|
||||||
if (!fonts[esize].isLoaded()) {
|
|
||||||
|
|
||||||
std::string fontName;
|
|
||||||
switch (esize) {
|
|
||||||
case GLFONT_SIZE12:
|
|
||||||
fontName = "vera_sans_mono12.fnt";
|
|
||||||
break;
|
|
||||||
case GLFONT_SIZE16:
|
|
||||||
fontName = "vera_sans_mono16.fnt";
|
|
||||||
break;
|
|
||||||
case GLFONT_SIZE18:
|
|
||||||
fontName = "vera_sans_mono18.fnt";
|
|
||||||
break;
|
|
||||||
case GLFONT_SIZE24:
|
|
||||||
fontName = "vera_sans_mono24.fnt";
|
|
||||||
break;
|
|
||||||
case GLFONT_SIZE32:
|
|
||||||
fontName = "vera_sans_mono32.fnt";
|
|
||||||
break;
|
|
||||||
case GLFONT_SIZE48:
|
|
||||||
fontName = "vera_sans_mono48.fnt";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fontName = "vera_sans_mono12.fnt";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fonts[esize].loadFont(fontName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fonts[esize];
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBColor color, long long center_freq, long long srate) {
|
|
||||||
if (!demod) {
|
if (!demod) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -165,18 +129,18 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBColor color,
|
|||||||
glColor4f(1.0, 1.0, 1.0, 0.8);
|
glColor4f(1.0, 1.0, 1.0, 0.8);
|
||||||
|
|
||||||
if (demod->getDemodulatorType() == DEMOD_TYPE_USB) {
|
if (demod->getDemodulatorType() == DEMOD_TYPE_USB) {
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
} else if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) {
|
} else if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) {
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
} else {
|
} else {
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demod->getLabel(), uxPos, hPos, 16, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBColor color, long long center_freq, long long srate) {
|
void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGB color, long long center_freq, long long srate) {
|
||||||
if (!demod) {
|
if (!demod) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -317,16 +281,16 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBColor color, lon
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
glColor3f(0, 0, 0);
|
glColor3f(0, 0, 0);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5) + xOfs, -1.0 + hPos - yOfs, 16, demodAlign,
|
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5) + xOfs, -1.0 + hPos - yOfs, 16, demodAlign,
|
||||||
GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::GLFONT_ALIGN_CENTER);
|
||||||
glColor3f(0.8, 0.8, 0.8);
|
glColor3f(0.8, 0.8, 0.8);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5), -1.0 + hPos, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5), -1.0 + hPos, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBColor color, float w, long long center_freq, long long srate) {
|
void PrimaryGLContext::DrawFreqSelector(float uxPos, RGB color, float w, long long center_freq, long long srate) {
|
||||||
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||||
|
|
||||||
long long bw = 0;
|
long long bw = 0;
|
||||||
@ -377,7 +341,7 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, RGBColor color, float w, lo
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimaryGLContext::DrawRangeSelector(float uxPos1, float uxPos2, RGBColor color) {
|
void PrimaryGLContext::DrawRangeSelector(float uxPos1, float uxPos2, RGB color) {
|
||||||
if (uxPos2 < uxPos1) {
|
if (uxPos2 < uxPos1) {
|
||||||
float temp = uxPos2;
|
float temp = uxPos2;
|
||||||
uxPos2=uxPos1;
|
uxPos2=uxPos1;
|
||||||
|
@ -13,9 +13,6 @@
|
|||||||
|
|
||||||
class PrimaryGLContext: public wxGLContext {
|
class PrimaryGLContext: public wxGLContext {
|
||||||
public:
|
public:
|
||||||
enum GLFontSize {
|
|
||||||
GLFONT_SIZE12, GLFONT_SIZE16, GLFONT_SIZE18, GLFONT_SIZE24, GLFONT_SIZE32, GLFONT_SIZE48, GLFONT_MAX
|
|
||||||
};
|
|
||||||
PrimaryGLContext(wxGLCanvas *canvas, wxGLContext *sharedContext);
|
PrimaryGLContext(wxGLCanvas *canvas, wxGLContext *sharedContext);
|
||||||
|
|
||||||
static wxString glGetwxString(GLenum name);
|
static wxString glGetwxString(GLenum name);
|
||||||
@ -24,17 +21,14 @@ public:
|
|||||||
void BeginDraw(float r, float g, float b);
|
void BeginDraw(float r, float g, float b);
|
||||||
void EndDraw();
|
void EndDraw();
|
||||||
|
|
||||||
void DrawFreqSelector(float uxPos, RGBColor color, float w = 0, long long center_freq = -1, long long srate = 0);
|
void DrawFreqSelector(float uxPos, RGB color, float w = 0, long long center_freq = -1, long long srate = 0);
|
||||||
void DrawRangeSelector(float uxPos1, float uxPos2, RGBColor color);
|
void DrawRangeSelector(float uxPos1, float uxPos2, RGB color);
|
||||||
void DrawDemod(DemodulatorInstance *demod, RGBColor color, long long center_freq = -1, long long srate = 0);
|
void DrawDemod(DemodulatorInstance *demod, RGB color, long long center_freq = -1, long long srate = 0);
|
||||||
void DrawDemodInfo(DemodulatorInstance *demod, RGBColor color, long long center_freq = -1, long long srate = 0);
|
void DrawDemodInfo(DemodulatorInstance *demod, RGB color, long long center_freq = -1, long long srate = 0);
|
||||||
|
|
||||||
static GLFont &getFont(GLFontSize esize);
|
|
||||||
|
|
||||||
void setHoverAlpha(float hoverAlpha);
|
void setHoverAlpha(float hoverAlpha);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static GLFont fonts[GLFONT_MAX];
|
|
||||||
DemodulatorThreadParameters defaultDemodParams;
|
DemodulatorThreadParameters defaultDemodParams;
|
||||||
float hoverAlpha;
|
float hoverAlpha;
|
||||||
};
|
};
|
||||||
|
@ -81,9 +81,9 @@ void ScopeContext::Plot(std::vector<float> &points, bool stereo, bool ppmMode) {
|
|||||||
|
|
||||||
glColor3f(0.65, 0.65, 0.65);
|
glColor3f(0.65, 0.65, 0.65);
|
||||||
|
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
|
|
||||||
|
|
||||||
if (stereo) {
|
if (stereo) {
|
||||||
@ -151,7 +151,7 @@ void ScopeContext::DrawDeviceName(std::string deviceName) {
|
|||||||
float hPos = (float) (viewHeight - 20) / viewHeight;
|
float hPos = (float) (viewHeight - 20) / viewHeight;
|
||||||
|
|
||||||
glColor3f(0.65, 0.65, 0.65);
|
glColor3f(0.65, 0.65, 0.65);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString(deviceName.c_str(), 1.0, hPos, 12, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(deviceName.c_str(), 1.0, hPos, 12, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScopeContext::DrawEnd() {
|
void ScopeContext::DrawEnd() {
|
||||||
|
@ -147,7 +147,7 @@ void SpectrumContext::Draw(std::vector<float> &points, long long freq, int bandw
|
|||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glColor4f(ThemeMgr::mgr.currentTheme->text.r, ThemeMgr::mgr.currentTheme->text.g, ThemeMgr::mgr.currentTheme->text.b,1.0);
|
glColor4f(ThemeMgr::mgr.currentTheme->text.r, ThemeMgr::mgr.currentTheme->text.g, ThemeMgr::mgr.currentTheme->text.b,1.0);
|
||||||
getFont(PrimaryGLContext::GLFONT_SIZE12).drawString(label.str(), m, hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(label.str(), m, hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
|
|
||||||
label.str(std::string());
|
label.str(std::string());
|
||||||
|
|
||||||
|
@ -84,10 +84,10 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
0.75, mouseTracker.getOriginMouseX(), mouseTracker.getMouseX());
|
0.75, mouseTracker.getOriginMouseX(), mouseTracker.getMouseX());
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBColor clr = top ? ThemeMgr::mgr.currentTheme->tuningBarUp : ThemeMgr::mgr.currentTheme->tuningBarDown;
|
RGB clr = top ? ThemeMgr::mgr.currentTheme->tuningBarUp : ThemeMgr::mgr.currentTheme->tuningBarDown;
|
||||||
|
|
||||||
RGBColor clrDark = ThemeMgr::mgr.currentTheme->tuningBarDark;
|
RGB clrDark = ThemeMgr::mgr.currentTheme->tuningBarDark;
|
||||||
RGBColor clrMid = ThemeMgr::mgr.currentTheme->tuningBarLight;
|
RGB clrMid = ThemeMgr::mgr.currentTheme->tuningBarLight;
|
||||||
|
|
||||||
glContext->DrawTunerBarIndexed(1, 3, 11, freqDP, freqW, clrMid, 0.25, true, true); // freq
|
glContext->DrawTunerBarIndexed(1, 3, 11, freqDP, freqW, clrMid, 0.25, true, true); // freq
|
||||||
glContext->DrawTunerBarIndexed(4, 6, 11, freqDP, freqW, clrDark, 0.25, true, true);
|
glContext->DrawTunerBarIndexed(4, 6, 11, freqDP, freqW, clrDark, 0.25, true, true);
|
||||||
@ -129,7 +129,7 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
glContext->DrawTuner(freq, 11, freqDP, freqW);
|
glContext->DrawTuner(freq, 11, freqDP, freqW);
|
||||||
int snap = wxGetApp().getFrequencySnap();
|
int snap = wxGetApp().getFrequencySnap();
|
||||||
if (snap != 1) {
|
if (snap != 1) {
|
||||||
glContext->DrawTunerDigitBox((int)log10(snap), 11, freqDP, freqW, RGBColor(1.0,0.0,0.0));
|
glContext->DrawTunerDigitBox((int)log10(snap), 11, freqDP, freqW, RGB(1.0,0.0,0.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glContext->DrawTuner(bw, 7, bwDP, bwW);
|
glContext->DrawTuner(bw, 7, bwDP, bwW);
|
||||||
|
@ -74,19 +74,19 @@ void TuningContext::DrawTuner(long long freq, int count, float displayPos, float
|
|||||||
freqStr << freq;
|
freqStr << freq;
|
||||||
std::string freqChars = freqStr.str();
|
std::string freqChars = freqStr.str();
|
||||||
|
|
||||||
PrimaryGLContext::GLFontSize fontSize = GLFONT_SIZE24;
|
GLFont::GLFontSize fontSize = GLFont::GLFONT_SIZE24;
|
||||||
int fontHeight = 24;
|
int fontHeight = 24;
|
||||||
|
|
||||||
if (viewHeight < 28) {
|
if (viewHeight < 28) {
|
||||||
fontSize = GLFONT_SIZE18;
|
fontSize = GLFont::GLFONT_SIZE18;
|
||||||
fontHeight = 18;
|
fontHeight = 18;
|
||||||
}
|
}
|
||||||
if (viewHeight < 24) {
|
if (viewHeight < 24) {
|
||||||
fontSize = GLFONT_SIZE16;
|
fontSize = GLFont::GLFONT_SIZE16;
|
||||||
fontHeight = 16;
|
fontHeight = 16;
|
||||||
}
|
}
|
||||||
if (viewHeight < 18) {
|
if (viewHeight < 18) {
|
||||||
fontSize = GLFONT_SIZE12;
|
fontSize = GLFont::GLFONT_SIZE12;
|
||||||
fontHeight = 12;
|
fontHeight = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ void TuningContext::DrawTuner(long long freq, int count, float displayPos, float
|
|||||||
int ofs = count - numChars;
|
int ofs = count - numChars;
|
||||||
for (int i = ofs; i < count; i++) {
|
for (int i = ofs; i < count; i++) {
|
||||||
float xpos = displayPos + (displayWidth / (float) count) * (float) i + ((displayWidth / 2.0) / (float) count);
|
float xpos = displayPos + (displayWidth / (float) count) * (float) i + ((displayWidth / 2.0) / (float) count);
|
||||||
getFont(fontSize).drawString(freqStr.str().substr(i - ofs, 1), xpos, 0, fontHeight, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
GLFont::getFont(fontSize).drawString(freqStr.str().substr(i - ofs, 1), xpos, 0, fontHeight, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
glColor4f(0.65, 0.65, 0.65, 0.25);
|
glColor4f(0.65, 0.65, 0.65, 0.25);
|
||||||
@ -112,7 +112,7 @@ void TuningContext::DrawTuner(long long freq, int count, float displayPos, float
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TuningContext::DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGBColor c) {
|
void TuningContext::DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGB c) {
|
||||||
GLint vp[4];
|
GLint vp[4];
|
||||||
glGetIntegerv( GL_VIEWPORT, vp);
|
glGetIntegerv( GL_VIEWPORT, vp);
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ int TuningContext::GetTunerDigitIndex(float mPos, int count, float displayPos, f
|
|||||||
return count - index;
|
return count - index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TuningContext::DrawTunerBarIndexed(int start, int end, int count, float displayPos, float displayWidth, RGBColor color, float alpha, bool top,
|
void TuningContext::DrawTunerBarIndexed(int start, int end, int count, float displayPos, float displayWidth, RGB color, float alpha, bool top,
|
||||||
bool bottom) {
|
bool bottom) {
|
||||||
float ofs = (displayWidth / (float) count);
|
float ofs = (displayWidth / (float) count);
|
||||||
float p2 = displayPos + ofs * (float) (count - start + 1);
|
float p2 = displayPos + ofs * (float) (count - start + 1);
|
||||||
|
@ -14,9 +14,9 @@ public:
|
|||||||
void DrawBegin();
|
void DrawBegin();
|
||||||
void Draw(float r, float g, float b, float a, float p1, float p2);
|
void Draw(float r, float g, float b, float a, float p1, float p2);
|
||||||
void DrawTuner(long long freq, int count, float displayPos, float displayWidth);
|
void DrawTuner(long long freq, int count, float displayPos, float displayWidth);
|
||||||
void DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGBColor c);
|
void DrawTunerDigitBox(int index, int count, float displayPos, float displayWidth, RGB c);
|
||||||
int GetTunerDigitIndex(float mPos, int count, float displayPos, float displayWidth);
|
int GetTunerDigitIndex(float mPos, int count, float displayPos, float displayWidth);
|
||||||
void DrawTunerBarIndexed(int start, int end, int count, float displayPos, float displayWidth, RGBColor color, float alpha, bool top, bool bottom);
|
void DrawTunerBarIndexed(int start, int end, int count, float displayPos, float displayWidth, RGB color, float alpha, bool top, bool bottom);
|
||||||
|
|
||||||
void DrawDemodFreqBw(long long freq, unsigned int bw, long long center);
|
void DrawDemodFreqBw(long long freq, unsigned int bw, long long center);
|
||||||
void DrawEnd();
|
void DrawEnd();
|
||||||
|
Loading…
Reference in New Issue
Block a user