moin!
schön, dass du weitergekommen bist!
Leider kann ich unmöglich auf meinem Pi z.Zt programmieren, ich habe hier nur einen 7" Miniscreen zur Verfügung -
ich habe die Funktionen daher auf dem PC ein wenig "offline" umgearbeitet.
Zu den Editor-Einrückungen:
könntest du sie bitte immer auf 3 setzen? sonst passen große Funktions- und Loop-Verschachtelungen nicht mehr in 1 Zeile, da zu weit eingerückt.
zur Plot-Funktion - die musste abgeändert werden.
zuerst, dieser ganze Teil zur Initialisierung von OpenVG gehört in eine Funktion mit fester Fenstergröße, z.B. 1024x600
dabei müssen
int _width_=1024, _height_=600;
globale Variablen werden;
Ich habe sie jetzt mit Unterstrichen im Namen definiert, damit sie besser als globale Variablen erkennbar sind.
Code:
int _width_=1024, _height_=600;
initOpenVG() {
initWindowSize(0, 0, _width_, _height_);
init(&_width_, &_height_);
Start(_width_, _height_);
Background(0, 0, 0);
StrokeWidth(1.0);
WindowOpacity(200);
WindowClear();
}
initOpenVG() wird in main() oder dem Task aufgerufen, der später für den Screen zuständig ist - in unserem Fall also z.Zt. noch main().
StrokeWidth(1.0);
braucht dann nie mehr neu aufgerufen werden, außer man ändert es
dasselbe gilt für alle anderen Variablen hier in initOpenVG().
finish() gehört als letzter Befehl in die aufrufende Graph-Init-Funktion,
d.h. z.Zt in main() also kurz for exit(0).
Weiter schlage ich vor, in den Funktionen nicht die Bezeichner der globalen Arrays oder anderer Funktionen zu verwenden, das verwirrt -
stattdessen einfach * array, samt Übergabe der Länge.
Denn später ändert sich ja auch noch die Plot-Länge aufs doppelte.
Auch darf die Plot-Funktion immer nur den übergebenen Array plotten, nicht 2 auf einmal.
Deine plot Funktion lautet dann fürs erste:
Code:
// **SNIP**
for(i=0;i<arrlength;i++)
{
Line((VGfloat) schritt*i, (VGfloat) input[i], (VGfloat) schritt*(i+1), (VGfloat) input[i+1]); // <<<< Fehler ????
}
Hier verstehe ich aber dein 3. + 4. Argument von Line() nicht: wieso i+1 ?
das Koordinatensystem hat die x-Achse an der Basislinie y0 im Fenster,
die Linien werden also gezeichnet von
xi, y0
nach
xi, (y0 + array[i])
(xi ist der i-te Schritt auf der x-Achse;
der Skalierungsfaktor xscale für die Schritte der xi-Werte kann von plotArray an Hand der array-Länge ausgerechnet werden.
Willst du 2 Koordinatensysteme untereinander malen, kannst du noch eine y0-Postion als Basislinie mit übergeben an plotArray
Code:
void plotArray((int32_t *array, int32_t arrlength, int y0) {
float xscale=1.0, border=100.0; // border anpassen !
xscale = (float) (arrlength-border)/_width_; // Ausschöpfung der gesamten openVG-Window-Breite width samt Rand!
Fill(0, 255, 255, 1);
for(i=0;i<arrlength;i++)
{
Line((VGfloat)xscale*i, (VGfloat) y0, (VGfloat)xscale*i, (VGfloat)(y0+input[i]) );
}
End();
}
die Steuerung mit getch() dagegen gehört in die aufrufende Funktion, also analyse, da wo man einen array gerade fertig gerechnet hat.
WindowClear();
muss dann ggf. direkt vor den plotArray-Aufruf.
Auch in analyse solle nicht input oder wavebuffer stehen, sondern nur allgemein array.
analyse wird dann wiederum allgemein von main() oder einer anderen Funktion aufgerufen, ebenfalls mit arrlength als allgemeinen Längenparameter, damit man flexibel bleibt für verschieden lange arrays zum Analysieren:
Code:
void analyse(int32_t *array, int32_t arrlength) // leicht verändert !!
{
int32_t sbuf[128];
int32_t bias, minr, maxr, baseline,
signalstart, signalend;
int32_t maximum = array[0];
int32_t minimum = array[0];
int32_t maxpos, minpos;
int32_t i;
char s[3];
for(i=0;i<arrlength;i++)
{
if(array[i] > maximum)
{
maximum = array[i];
maxpos = i;
}
if(array[i] < minimum)
{
minimum = array[i];
minpos = i;
}
}
maximum = array[0];
minimum = array[0];
for(i=0;i<arrlength; ++i)
{
if(array[i] > maximum)
{
maximum = array[i];
maxpos = i;
}
if(array[i] < minimum)
{
minimum = array[i];
minpos = i;
}
}
// calculate baseline from last 100 array cells:
// init vars
baseline=(array[minpos] + array[maxpos]) / 2; // init baseline by (min+max)/2
minr=baseline - 1;
maxr=baseline + 1;
// auto-adjust:
for(i=arrlength-100; i<arrlength; ++i)
{
// mean baseline
baseline = round((0.5*(float)array[i] + 0.5*(float)baseline)) ;
// smoothed out max noise
if(array[i] >= baseline) maxr = round((0.6*(float)array[i] + 0.4*(float)maxr)) +1 ;
// smoothed out min noise
if(array[i] <= baseline) minr = round((0.6*(float)array[i] + 0.4*(float)minr)) -1 ;
}
bias = max(baseline-minr, maxr-baseline) +1;
// noise reduction start/end
// drop small noise
for(i=0;i<arrlength;++i)
{
if((array[i]>baseline) && (array[i] <= baseline + bias)) array[i] = baseline ; // little higher value => drop to baseline
else
if((array[i]<baseline) && (array[i] >= baseline - bias)) array[i] = baseline ; // little lower value => rise to baseline
}
// signalstart, signalend: threshold = bias + (bias/2)
signalstart = 0;
i = 0;
while((array[i]<=baseline + 4 * bias/3) && (i<arrlength-1)) ++i;
signalstart = i;
if(i > 0) signalstart -= 1;
signalend=arrlength-1;
i=arrlength-1;
while((array[i]<=baseline + + 4*bias/3) && (i>signalstart)) --i;
signalend = i;
if(i<arrlength-1) signalstart +=1;
sStart = signalstart;
sEnde = signalend;
WindowClear();
plotArray(array, arrlength, 30); // 30 = baseline ordinate // <<<<<<<<<<< neu
// >>>> Tabelle stattdessen ins Graphic window ?
cout << "Bias: " << bias << endl;
cout << "Maximal: " << maximum << endl;
cout << "Minimal: " << minimum << endl;
cout << "Signalstart: " << signalstart << endl;
cout << "Signalende: " << signalend << endl;
}
ich habe auch noch openVG-Hilfsfunktionen für Farbe und zur Textausgabe im Grafikfenster eingearbeitet (z.B. zur Beschriftung der Charts oder weiterer Tabellenwete), das kann dann anstelle der obigen initOpenVG komplett folgendermaßen in das Spracherkennungsprogramm übernommen werden:
Code:
#include "VG/openvg.h"
#include "VG/vgu.h"
#include "fontinfo.h"
#include "shapes.h"
//*************************************************************
// openVG
//*************************************************************
// color name constants
#define BLACK 0, 0, 0
#define WHITE 255, 255, 255
#define MAGENTA 255, 0, 255
#define RED 255, 0, 0
#define YELLOW 255, 255, 0
#define LIME 0, 255, 0
#define GREEN 0, 128, 0
#define CYAN 0, 255, 255
#define AQUA 102, 204, 204
#define BLUE 0, 0, 255
int _width_=1024, _height_=600;
int _fontsize_ = 10;
#define cls() WindowClear()
//*************************************************************
inline void lcdprintxy( VGfloat x, VGfloat y, char * buf ) {
Text( (x+_fontsize_), (y+_fontsize_*1.2), buf, MonoTypeface , _fontsize_);
}
//*************************************************************
void initOpenVG() {
initWindowSize(0, 0 , _width_ , _height_ );
init(&_width_, &_height_);
Start(_width_, _height_);
Background(BLACK);
Stroke(WHITE, 1);
StrokeWidth(1.0);
Fill(WHITE, 1);
WindowOpacity(200);
cls();
}
//*************************************************************
void plotArray((int32_t *array, int32_t arrlength, int y0) {
float xscale=1.0, border=100.0; // border anpassen !
xscale = (float) (arrlength-border)/_width_; // Ausschöpfung der gesamten openVG-Window-Breite width samt Rand!
Fill(0, 255, 255, 1);
for(i=0;i<arrlength;i++)
{
Line((VGfloat)xscale*i, (VGfloat) y0, (VGfloat)xscale*i, (VGfloat)(y0+input[i]) );
}
End();
}
//*************************************************************
Lesezeichen