Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

GUISpect.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Transient spectrum GUI
00004     Copyright (C) 1999-2003 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <time.h>
00027 #include <errno.h>
00028 #include <signal.h>
00029 #ifdef USE_BACKING_STORE
00030     #include <X11/Xlib.h>
00031 #endif
00032 #include <gtk/gtk.h>
00033 #include <gdk/gdkrgb.h>
00034 #ifdef USE_BACKING_STORE
00035     #include <gdk/gdkprivate.h>
00036 #endif
00037 #include "GUISpect.hh"
00038 
00039 
00040 G_LOCK_DEFINE_STATIC(gmInputMutex);
00041 
00042 static const char *cpWindowTxt = "Spectrogram";
00043 static const char *cpLServerTxt = "Server";
00044 static const char *cpaLChannelTxt[] = { "Channel", "Direction" };
00045 static const char *cpBConnectTxt = "Connect";
00046 static const char *cpBDisconnectTxt = "Disconnect";
00047 static const char *cpCBFreezeTxt = "Freeze";
00048 static const char *cpLTypeTxt = "Type";
00049 static const char *cpaLTypeMenu[] = { "STFT", "(MR-STFT)", "(Gabor)",
00050     "(WVD)", "Hankel", "Autocorr.", "Cepstrum" };
00051 static const char *cpLWindowTxt = "Window";
00052 static const char *cpaLWindowMenu[] = { "Rectangle", "Bartlett",
00053     "Blackman", "Blackman-Harris", "Cosine tapered", "Exponential",
00054     "Flat top", "Generic cosine", "Hamming", "Hanning", "Kaiser",
00055     "Kaiser-Bessel", "Tukey" };
00056 static const char *cpLWindowParamTxt = "Window param.";
00057 static const char *cpLWindowLenTxt = "Window length";
00058 static const char *cpaLWindowLenMenu[] = { "128", "256", "512", "1024",
00059     "2048", "4096", "8192", "16384", "32768", "65536" };
00060 static const char *cpLLowFreqTxt = "Lower freq.";
00061 static const char *cpLHighFreqTxt = "Higher freq.";
00062 static const char *cpLGainTxt = "Gain dB";
00063 static const char *cpLSlopeTxt = "Gain dB/oct";
00064 static const char *cpLOverlapTxt = "Overlap (%)";
00065 static const char *cpLLinearTxt = "Linear scale";
00066 static const char *cpLNormalizeTxt = "Normalize";
00067 //static const char *cpLApplyTxt = "Apply";
00068 static const char *cpLRemoveNoiseTxt = "Remove noise";
00069 static const char *cpaLRemoveNoiseMenu[] = { "None", "TPSW", "OTA",
00070     "Diff", "InvDiff" };
00071 static const char *cpLAlphaTxt = "Alpha";
00072 static const char *cpLMeanLengthTxt = "Mean length";
00073 static const char *cpLGapLengthTxt = "Gap length";
00074 static const char *cpLDynRangeTxt = "Dynamic range (dB)";
00075 static const char *cpLPaletteTxt = "Palette";
00076 static const char *cpaLPaletteMenu[] = { "BW", "HSV", "Light", "Temp",
00077     "Dir", "Green", "Green2", "PureGreen", "WB" };
00078 static const char *cpBSaveTxt = "Save";
00079 static const char *cpFSSaveTxt = "Save to TIFF file";
00080 
00081 clSpectGUI *SpectGUI;
00082 
00083 
00084 int main(int argc, char *argv[])
00085 {
00086     int iTempRetVal;
00087     
00088     signal(SIGPIPE, SIG_IGN);
00089     signal(SIGFPE, SIG_IGN);
00090     SpectGUI = new clSpectGUI(&argc, &argv);
00091     iTempRetVal = SpectGUI->Exec();
00092     delete SpectGUI;
00093     return iTempRetVal;
00094 }
00095 
00096 
00097 gint WrapOnDelete(GtkWidget *gwSender, GdkEventAny *geaEvent)
00098 {
00099     return SpectGUI->OnDelete(gwSender, geaEvent);
00100 }
00101 
00102 
00103 void WrapOnHideToggled(GtkToggleButton *gtbSender, gpointer *gpData)
00104 {
00105     SpectGUI->OnHideToggled(gtbSender, gpData);
00106 }
00107 
00108 
00109 gint WrapOnConnectClick(GtkWidget *gwSender, gpointer gpData)
00110 {
00111     return SpectGUI->OnConnectClick(gwSender, gpData);
00112 }
00113 
00114 
00115 void WrapOnFreezeToggled(GtkToggleButton *gtbSender, gpointer *gpData)
00116 {
00117     SpectGUI->OnFreezeToggled(gtbSender, gpData);
00118 }
00119 
00120 
00121 gint WrapOnPaletteActivate(GtkWidget *gwSender, gpointer gpData)
00122 {
00123     return SpectGUI->OnPaletteActivate(gwSender, gpData);
00124 }
00125 
00126 
00127 gint WrapOnMotionSgram(GtkWidget *gwSender, GdkEventMotion *gemEvent)
00128 {
00129     return SpectGUI->OnMotionSgram(gwSender, gemEvent);
00130 }
00131 
00132 
00133 gint WrapOnMotionSpect(GtkWidget *gwSender, GdkEventMotion *gemEvent)
00134 {
00135     return SpectGUI->OnMotionSpect(gwSender, gemEvent);
00136 }
00137 
00138 
00139 gint WrapOnExposeSgram(GtkWidget *gwSender, GdkEventExpose *geeEvent)
00140 {
00141     return SpectGUI->OnExposeSgram(gwSender, geeEvent);
00142 }
00143 
00144 
00145 gint WrapOnExposeSpect(GtkWidget *gwSender, GdkEventExpose *geeEvent)
00146 {
00147     return SpectGUI->OnExposeSpect(gwSender, geeEvent);
00148 }
00149 
00150 
00151 gboolean WrapOnConfigure(GtkWidget *gwSender, GdkEventConfigure *gecEvent,
00152     gpointer gpData)
00153 {
00154     return SpectGUI->OnConfigure(gwSender, gecEvent, gpData);
00155 }
00156 
00157 
00158 void WrapOnSizeAllocate(GtkWidget *gwSender, GtkAllocation *gaAllocation,
00159     gpointer gpData)
00160 {
00161     SpectGUI->OnSizeAllocate(gwSender, gaAllocation, gpData);
00162 }
00163 
00164 
00165 void WrapGdkInput(gpointer gpData, gint giSource, 
00166     GdkInputCondition gicCondition)
00167 {
00168     SpectGUI->GdkInput(gpData, giSource, gicCondition);
00169 }
00170 
00171 
00172 void WrapOnSaveClicks(GtkButton *gbSender, gpointer gpData)
00173 {
00174     SpectGUI->OnSaveClicks(gbSender, gpData);
00175 }
00176 
00177 
00178 clSpectGUI::clSpectGUI(int *ipArgCount, char ***cpaArgVectP)
00179 {
00180     bRun = true;
00181     bConnected = false;
00182     bFreezed = false;
00183     cpRcvMsgBuf = NULL;
00184     fpSpect = NULL;
00185     glServers = NULL;
00186     g_print("%s GUI v%i.%i.%i\n", cpWindowTxt, 
00187         SGUI_VER_MAJ, SGUI_VER_MIN, SGUI_VER_PL);
00188     g_print("Copyright (C) 1999-2002 Jussi Laako\n\n");
00189     g_print("Gtk+ version %i.%i.%i\n", gtk_major_version, gtk_minor_version,
00190         gtk_micro_version);
00191     g_print("Locale set to %s\n", gtk_set_locale());
00192     gtk_init(ipArgCount, cpaArgVectP);
00193     gdk_rgb_init();
00194     gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
00195     gtk_widget_set_default_visual(gdk_rgb_get_visual());
00196     CfgFile = new clCfgFile(SGUI_CFGFILE);
00197     if (!CfgFile->GetInt("Fit", &iFit))
00198         iFit = 0;
00199     if (!CfgFile->GetInt("Palette", &iPalette))
00200         iPalette = 0;
00201     if (!CfgFile->GetInt("TIFFCompression", &iTIFFCompression))
00202         iTIFFCompression = 0;
00203     if (!CfgFile->GetInt("JPEGQuality", &iJPEGQuality))
00204         iJPEGQuality = 100;
00205     if (!CfgFile->GetInt("BeamCount", &iBeamCount))
00206         iBeamCount = 0;
00207 }
00208 
00209 
00210 clSpectGUI::~clSpectGUI()
00211 {
00212     if (bConnected) delete SockOp;
00213     delete CfgFile;
00214 }
00215 
00216 
00217 int clSpectGUI::Exec()
00218 {
00219     if (!Build())
00220     {
00221         g_print("User interface creation failed\n");
00222         return 1;
00223     }
00224     if (!ConnectSignals())
00225     {
00226         g_print("User interface signal connection failed\n");
00227         return 1;
00228     }
00229     gtk_main();
00230     FreeDrawingPrims();
00231     return 0;
00232 }
00233 
00234 
00235 gint clSpectGUI::OnDelete(GtkWidget *gwSender, GdkEventAny *geaEvent)
00236 {
00237     bRun = false;
00238     gtk_main_quit();
00239     return 0;
00240 }
00241 
00242 
00243 void clSpectGUI::OnHideToggled(GtkToggleButton *gtbSender, gpointer gpData)
00244 {
00245     if (gtk_toggle_button_get_active(gtbSender))
00246     {
00247         gtk_widget_hide(gwTable1);
00248         gtk_widget_hide(gwTable2);
00249         gtk_widget_hide(gwTable3);
00250     }
00251     else
00252     {
00253         gtk_widget_show(gwTable1);
00254         gtk_widget_show(gwTable2);
00255         gtk_widget_show(gwTable3);
00256     }
00257 }
00258 
00259 
00260 gint clSpectGUI::OnConnectClick(GtkWidget *gwSender, gpointer gpData)
00261 {
00262     char cpHost[SGUI_SERVER_MAXLEN + 1];
00263     int iPort;
00264 
00265     if (bConnected)
00266     {
00267         gdk_input_remove(giGdkTag);
00268         delete SockOp;
00269         bConnected = false;
00270     }
00271     if (gwSender == gwBConnect)
00272     {
00273         if (ParseServerStr(cpHost, &iPort,
00274             gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry))))
00275         {
00276             g_print("Connecting to host %s port %i...\n",
00277                 cpHost, iPort);
00278             if (InitConnection(cpHost, iPort))
00279             {
00280                 g_print("OK\n\n");
00281             }
00282             else
00283             {
00284                 g_print("Failed\n\n");
00285             }
00286         }
00287         else
00288         {
00289             g_print("Incorrect server entry! Format: <host>:<port>\n");
00290         }
00291     }
00292     return 0;
00293 }
00294 
00295 
00296 void clSpectGUI::OnFreezeToggled(GtkToggleButton *gtbSender, gpointer gpData)
00297 {
00298     bFreezed = (gtk_toggle_button_get_active(gtbSender)) ? true : false;
00299 }
00300 
00301 
00302 gint clSpectGUI::OnPaletteActivate(GtkWidget *gwSender, gpointer gpData)
00303 {
00304     int iPalType;
00305 
00306     if (gwSender == gwaMIPalette[SGUI_PAL_BW])
00307     {
00308         FrameBuf.PalGenBW();
00309     }
00310     else if (gwSender == gwaMIPalette[SGUI_PAL_HSV])
00311     {
00312         FrameBuf.PalGenHSV();
00313     }
00314     else if (gwSender == gwaMIPalette[SGUI_PAL_LIGHT])
00315     {
00316         FrameBuf.PalGenLight();
00317     }
00318     else if (gwSender == gwaMIPalette[SGUI_PAL_TEMP])
00319     {
00320         FrameBuf.PalGenTemp();
00321     }
00322     else if (gwSender == gwaMIPalette[SGUI_PAL_DIR])
00323     {
00324         FrameBuf.PalGenDir();
00325     }
00326     else if (gwSender == gwaMIPalette[SGUI_PAL_GREEN])
00327     {
00328         FrameBuf.PalGenGreen();
00329     }
00330     else if (gwSender == gwaMIPalette[SGUI_PAL_GREEN2])
00331     {
00332         FrameBuf.PalGenGreen2();
00333     }
00334     else if (gwSender == gwaMIPalette[SGUI_PAL_PUREGREEN])
00335     {
00336         FrameBuf.PalGenPureGreen();
00337     }
00338     else if (gwSender == gwaMIPalette[SGUI_PAL_WB])
00339     {
00340         FrameBuf.PalGenWB();
00341     }
00342     else
00343     {
00344         CfgFile->GetInt("Palette", &iPalType);
00345         switch (iPalType)
00346         {
00347             case SGUI_PAL_BW:
00348                 FrameBuf.PalGenBW();
00349                 break;
00350             case SGUI_PAL_HSV:
00351                 FrameBuf.PalGenHSV();
00352                 break;
00353             case SGUI_PAL_LIGHT:
00354                 FrameBuf.PalGenLight();
00355                 break;
00356             case SGUI_PAL_TEMP:
00357                 FrameBuf.PalGenTemp();
00358                 break;
00359             case SGUI_PAL_DIR:
00360                 FrameBuf.PalGenDir();
00361                 break;
00362             case SGUI_PAL_GREEN:
00363                 FrameBuf.PalGenGreen();
00364                 break;
00365             default:
00366                 FrameBuf.PalGenBW();
00367         }
00368     }
00369 
00370     return 0;
00371 }
00372 
00373 
00374 gint clSpectGUI::OnMotionSgram(GtkWidget *gwSender, GdkEventMotion *gemEvent)
00375 {
00376     float fBand;
00377     float fSpectTime;
00378     char cpConvStr[SGUI_CONV_MAXLEN];
00379 
00380     fBand = sSResult.iHighFreq - sSResult.iLowFreq;
00381     fSpectTime = sSResult.fLineTime;
00382     fGramX = (float) (iGramW - gemEvent->x) * fSpectTime;
00383     fGramY = fBand - (fBand / (float) iGramH * (float) gemEvent->y);
00384     PrintRealTime();
00385     g_snprintf(cpConvStr, SGUI_CONV_MAXLEN,
00386         "%.1f s, %.1f Hz / %.1f Hz, %.1f dB / %.1f dB %i clips / %s",
00387         fGramX, fGramY, fSpectX, fSpectY, sSResult.fPeakLevel, iClips,
00388         cpGramXTime);
00389     gtk_statusbar_pop(GTK_STATUSBAR(gwStatusBar), guCtxtSB);
00390     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guCtxtSB, cpConvStr);
00391 
00392     return 0;
00393 }
00394 
00395 
00396 gint clSpectGUI::OnMotionSpect(GtkWidget *gwSender, GdkEventMotion *gemEvent)
00397 {
00398     float fBand;
00399     char cpConvStr[SGUI_CONV_MAXLEN];
00400 
00401     fBand = sSResult.iHighFreq - sSResult.iLowFreq;
00402     fSpectX = fBand / (float) iSpectPoints * (float) gemEvent->x;
00403     fSpectY = -((float) sSRequest.fDynRange / (float) iSpectH * 
00404         (float) gemEvent->y);
00405     g_snprintf(cpConvStr, SGUI_CONV_MAXLEN,
00406         "%.1f s, %.1f Hz / %.1f Hz, %.1f dB / %.1f dB %i clips / %s",
00407         fGramX, fGramY, fSpectX, fSpectY, sSResult.fPeakLevel, iClips,
00408         cpGramXTime);
00409     gtk_statusbar_pop(GTK_STATUSBAR(gwStatusBar), guCtxtSB);
00410     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guCtxtSB, cpConvStr);
00411 
00412     return 0;
00413 }
00414 
00415 
00416 gint clSpectGUI::OnExposeSgram(GtkWidget *gwSender, GdkEventExpose *geeEvent)
00417 {
00418     int iWidth;
00419     int iHeight;
00420 
00421     if (!bRun) return FALSE;
00422     iWidth = ((geeEvent->area.x + geeEvent->area.width) > iGramW) ?
00423         iGramW - geeEvent->area.x : geeEvent->area.width;
00424     iHeight = ((geeEvent->area.y + geeEvent->area.height) > iGramH) ?
00425         iGramH - geeEvent->area.y : geeEvent->area.height;
00426     gdk_draw_rgb_32_image(geeEvent->window, ggcGramFG,
00427         geeEvent->area.x + 1, geeEvent->area.y,  // there should be no + 1...
00428         iWidth, iHeight,
00429         GDK_RGB_DITHER_NONE,
00430         FrameBuf.GetCurPtr(geeEvent->area.x, geeEvent->area.y),
00431         FrameBuf.GetRowStride());
00432     return TRUE;
00433 }
00434 
00435 
00436 gint clSpectGUI::OnExposeSpect(GtkWidget *gwSender, GdkEventExpose *geeEvent)
00437 {
00438     int iLineCntr;
00439     int iMaxLine;
00440     int iLineLength;
00441     
00442     if (!bRun) return FALSE;
00443     gdk_window_clear_area(geeEvent->window,
00444         geeEvent->area.x, geeEvent->area.y,
00445         geeEvent->area.width, geeEvent->area.height);
00446     // Draw visible part of spectrum
00447     if (fpSpect == NULL) return FALSE;
00448     iMaxLine = 
00449         (iSpectPoints <= (geeEvent->area.x + geeEvent->area.width)) ?
00450         iSpectPoints : geeEvent->area.x + geeEvent->area.width;
00451     for (iLineCntr = geeEvent->area.x; iLineCntr < iMaxLine; iLineCntr++)
00452     {
00453         iLineLength = (int) (fpSpect[iLineCntr] * 
00454             (GDT) (geeEvent->area.height - 1) + 0.5);
00455         if (iLineLength < 0) iLineLength = 0;
00456         if (iLineLength >= geeEvent->area.height)
00457             iLineLength = geeEvent->area.height;
00458         gdk_draw_line(geeEvent->window, ggcSpectFG,
00459             iLineCntr, geeEvent->area.height - 1,
00460             iLineCntr, geeEvent->area.height - iLineLength);
00461     }
00462     return TRUE;
00463 }
00464 
00465 
00466 gboolean clSpectGUI::OnConfigure(GtkWidget *gwSender, 
00467     GdkEventConfigure *gecEvent, gpointer gpData)
00468 {
00469     int iRealWidth;
00470     int iRealHeight;
00471 
00472     if (gwSender == gwDASpectrogram)
00473     {
00474         iRealWidth = gecEvent->width - 1;
00475         iRealHeight = gecEvent->height - 1;
00476         if (iGramW != iRealWidth || (iGramH != iRealHeight && iFit))
00477         {
00478             iGramW = iRealWidth;
00479             if (iFit)
00480                 iGramH = iRealHeight;
00481             ReConfigDisplay();
00482         }
00483     }
00484     else if (gwSender == gwDASpectrum)
00485     {
00486         if (iSpectW <= 0) iSpectW = gecEvent->width;
00487         if (iSpectH != gecEvent->height)
00488         {
00489             iSpectH = gecEvent->height;
00490             ReConfigDisplay();
00491         }
00492     }
00493     return TRUE;
00494 }
00495 
00496 
00497 void clSpectGUI::OnSizeAllocate(GtkWidget *gwSender, 
00498     GtkAllocation *gaAllocation, gpointer gpData)
00499 {
00500     int iRealWidth;
00501     int iRealHeight;
00502 
00503     if (gwSender == gwDASpectrogram)
00504     {
00505         iRealWidth = gaAllocation->width - 1;
00506         iRealHeight = gaAllocation->height - 1;
00507         if (iGramW != iRealWidth || (iGramH != iRealHeight && iFit))
00508         {
00509             iGramW = iRealWidth;
00510             if (iFit)
00511                 iGramH = iRealHeight;
00512             ReConfigDisplay();
00513         }
00514     }
00515     else if (gwSender == gwDASpectrum)
00516     {
00517         if (iSpectW <= 0) iSpectW = gaAllocation->width;
00518         if (iSpectH != gaAllocation->height)
00519         {
00520             iSpectH = gaAllocation->height;
00521             ReConfigDisplay();
00522         }
00523     }
00524     else if (gwSender == gwScrolledW2)
00525     {
00526         if (!GTK_SCROLLED_WINDOW(gwSender)->hscrollbar_visible)
00527         {
00528             iRealHeight = gaAllocation->height - gwHRFreq->requisition.height;
00529         }
00530         else
00531         {
00532             iRealHeight = gaAllocation->height - gwHRFreq->requisition.height -
00533                 GTK_SCROLLED_WINDOW(gwSender)->hscrollbar->requisition.height;
00534         }
00535         if (iSpectH != gaAllocation->height)
00536         {
00537             iSpectH = iRealHeight;
00538             ReConfigDisplay();
00539         }
00540     }
00541 }
00542 
00543 
00544 void clSpectGUI::GdkInput(gpointer gpData, gint giSource, 
00545     GdkInputCondition gicCondition)
00546 {
00547     bool bNewData = false;
00548     char cpConvStr[SGUI_CONV_MAXLEN];
00549     stSpectRes sSResNew;
00550 
00551     if (!bRun) return;
00552     G_LOCK(gmInputMutex);
00553     while (SockOp->ReadSelect(0))
00554     {
00555         if (!bFreezed) bNewData = true;
00556         if (SockOp->ReadN(cpRcvMsgBuf, iRcvMsgSize) < iRcvMsgSize)
00557         {
00558             if (SockOp->GetErrno() == EPIPE || SockOp->GetErrno() == 0) 
00559                 g_print("Server disconnected\n");
00560             else 
00561                 g_print("Receive error: %s\n", strerror(SockOp->GetErrno()));
00562             gdk_input_remove(giGdkTag);
00563             delete SockOp;
00564             bConnected = false;
00565             G_UNLOCK(gmInputMutex);
00566             return;
00567         }
00568         if (bFreezed) continue;
00569         SpectMsg.GetResult(cpRcvMsgBuf, &sSResNew, fpSpect);
00570         if (sSResNew.lLength != sSResult.lLength) bReConfig = true;
00571         if (sSResNew.iLowFreq != sSResult.iLowFreq) bReConfig = true;
00572         if (sSResNew.iHighFreq != sSResult.iHighFreq) bReConfig = true;
00573         if (sSResNew.bLinear != sSResult.bLinear) bReConfig = true;
00574         memcpy(&sSResult, &sSResNew, sizeof(stSpectRes));
00575         if (bReConfig)
00576         {
00577             g_snprintf(cpConvStr, SGUI_CONV_MAXLEN, "%i", sSResult.iLowFreq);
00578             gtk_entry_set_text(GTK_ENTRY(gwELowFreq), cpConvStr);
00579             g_snprintf(cpConvStr, SGUI_CONV_MAXLEN, "%i", sSResult.iHighFreq);
00580             gtk_entry_set_text(GTK_ENTRY(gwEHighFreq), cpConvStr);
00581             ReConfigDisplay();
00582         }
00583         if (sSResult.fPeakLevel >= 0.0F) iClips++;
00584         DrawSpectrogram();
00585         if (bReConfig) break;
00586     }
00587     if (bNewData)
00588     {
00589         DrawSpectrum();
00590         PrintRealTime();
00591         g_snprintf(cpConvStr, SGUI_CONV_MAXLEN,
00592             "%.1f s, %.1f Hz / %.1f Hz, %.1f dB / %.1f dB %i clips / %s",
00593             fGramX, fGramY, fSpectX, fSpectY, sSResult.fPeakLevel, iClips,
00594             cpGramXTime);
00595         gtk_statusbar_pop(GTK_STATUSBAR(gwStatusBar), guCtxtSB);
00596         gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guCtxtSB, cpConvStr);
00597     }
00598     G_UNLOCK(gmInputMutex);
00599 }
00600 
00601 
00602 void clSpectGUI::OnSaveClicks (GtkButton *gbSender, gpointer gpData)
00603 {
00604     int iAction = GPOINTER_TO_INT(gpData);
00605     int iCompressMode;
00606     const char *cpFileName;
00607 
00608     switch (iAction)
00609     {
00610         case 0:
00611             gtk_widget_hide(gwFSSave);
00612             break;
00613         case 1:
00614             gtk_widget_hide(gwFSSave);
00615             switch (iTIFFCompression)
00616             {
00617                 case 0:
00618                     iCompressMode = FB_TIFF_COMPRESS_NONE;
00619                     break;
00620                 case 1:
00621                     iCompressMode = FB_TIFF_COMPRESS_RLE;
00622                     break;
00623                 case 2:
00624                     iCompressMode = FB_TIFF_COMPRESS_LZW;
00625                     break;
00626                 case 3:
00627                     iCompressMode = FB_TIFF_COMPRESS_JPEG;
00628                     break;
00629                 case 4:
00630                     iCompressMode = FB_TIFF_COMPRESS_DEFLATE;
00631                     break;
00632                 default:
00633                     iCompressMode = FB_TIFF_COMPRESS_NONE;
00634             }
00635             cpFileName = 
00636                 gtk_file_selection_get_filename(GTK_FILE_SELECTION(gwFSSave));
00637             /*if (!FrameBuf.SaveToFile(cpFileName, iCompressMode, iJPEGQuality, 
00638                 "Spectrogram",
00639                 -(sSResult.fLineTime * iGramW), 0,
00640                 sSResult.iLowFreq, sSResult.iHighFreq))*/
00641             if (!FrameBuf.SaveToFile(cpFileName, iCompressMode, iJPEGQuality, 
00642                 "Spectrogram"))
00643             {
00644                 g_warning("Saving to file failed!");
00645             }
00646             SaveInfo(cpFileName);
00647             break;
00648         case 2:
00649             gtk_widget_show(gwFSSave);
00650             break;
00651     }
00652 }
00653 
00654 
00655 bool clSpectGUI::Build()
00656 {
00657     int iDefWidth;
00658     int iDefHeight;
00659     int iYCntr;
00660     int iXCntr;
00661     int iPixIdx;
00662     unsigned int *upPalPtr;
00663     unsigned int *upFBPtr;
00664     char cpConvStr[SGUI_CONV_MAXLEN];
00665 
00666     // - Main window
00667     gwWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00668     gtk_window_set_title(GTK_WINDOW(gwWindow), cpWindowTxt);
00669     // shrink, grow, auto-shrink
00670     gtk_window_set_policy(GTK_WINDOW(gwWindow), TRUE, TRUE, FALSE);
00671     if (CfgFile->GetInt("Width", &iDefWidth) && 
00672         CfgFile->GetInt("Height", &iDefHeight))
00673     {
00674         if ((iDefWidth > 0 && iDefHeight > 0) &&
00675             (iDefWidth <= gdk_screen_width() && 
00676             iDefHeight <= gdk_screen_height()))
00677         {
00678             gtk_window_set_default_size(GTK_WINDOW(gwWindow),
00679                 iDefWidth, iDefHeight);
00680         }
00681         else
00682         {
00683             gtk_window_set_default_size(GTK_WINDOW(gwWindow),
00684                 gdk_screen_width() - SGUI_PADDING * 2, 
00685                 gdk_screen_height() - SGUI_PADDING * 2);
00686         }
00687     }
00688     else
00689     {
00690         gtk_window_set_default_size(GTK_WINDOW(gwWindow),
00691             SGUI_DEF_WIDTH, SGUI_DEF_HEIGHT);
00692     }
00693 
00694     // --- Vertical box
00695     // homogenous, spacing
00696     gwVBox = gtk_vbox_new(FALSE, SGUI_PADDING);
00697     gtk_container_add(GTK_CONTAINER(gwWindow), gwVBox);
00698     gtk_widget_show(gwVBox);
00699 
00700     // --- Hide button
00701     gwCBHide = gtk_check_button_new();
00702     gtk_box_pack_start(GTK_BOX(gwVBox), gwCBHide, FALSE, FALSE, 0);
00703     gtk_widget_show(gwCBHide);
00704 
00705     // --- Table 1
00706     if (!BuildTable1()) return false;
00707 
00708     // --- Table 2
00709     if (!BuildTable2()) return false;
00710 
00711     // --- Table 3
00712     if (!BuildTable3()) return false;
00713 
00714     // --- VerticalPaned
00715     gwVPaned = gtk_vpaned_new();
00716     gtk_paned_set_gutter_size(GTK_PANED(gwVPaned), SGUI_PADDING * 2);
00717     // box, child, expand, fill, padding
00718     gtk_box_pack_start(GTK_BOX(gwVBox), gwVPaned, TRUE, TRUE, 0);
00719     gtk_widget_show(gwVPaned);
00720 
00721     // --- ScrolledWindow 1: Spectrogram (TableGram)
00722     gwScrolledW1 = gtk_scrolled_window_new(NULL, NULL);
00723     if (iFit)
00724         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gwScrolledW1),
00725             GTK_POLICY_NEVER, GTK_POLICY_NEVER);
00726     else
00727         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gwScrolledW1),
00728             GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
00729     // paned, child, resize, shrink
00730     gtk_paned_pack1(GTK_PANED(gwVPaned), gwScrolledW1, TRUE, TRUE);
00731     gtk_widget_show(gwScrolledW1);
00732 
00733     // --- ScrolledWindow 2: Spectrum (TableSpect)
00734     gwScrolledW2 = gtk_scrolled_window_new(NULL, NULL);
00735     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gwScrolledW2),
00736         GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
00737     // paned, child, resize, shrink
00738     gtk_paned_pack2(GTK_PANED(gwVPaned), gwScrolledW2, TRUE, TRUE);
00739     gtk_widget_show(gwScrolledW2);
00740 
00741     // --- Table Gram
00742     if (!BuildTableGram()) return false;
00743 
00744     // --- Table Spect
00745     if (!BuildTableSpect()) return false;
00746 
00747     gwStatusBar = gtk_statusbar_new();
00748     gtk_box_pack_start(GTK_BOX(gwVBox), gwStatusBar, FALSE, FALSE, 0);
00749     gtk_widget_show(gwStatusBar);
00750     guCtxtSB = gtk_statusbar_get_context_id(GTK_STATUSBAR(gwStatusBar),
00751         "status");
00752     g_snprintf(cpConvStr, SGUI_CONV_MAXLEN, 
00753         "%.1f s, %.1f Hz / %.1f Hz, %.1f dB / %.1f dB",
00754         fGramX, fGramY, fSpectX, fSpectY, sSResult.fPeakLevel);
00755     gtk_statusbar_push(GTK_STATUSBAR(gwStatusBar), guCtxtSB, cpConvStr);
00756 
00757     // Delayed realization of main window
00758     gtk_widget_show(gwWindow);
00759 
00760     #ifdef USE_BACKING_STORE
00761         GdkWindowPrivate *gwpWindow = 
00762             (GdkWindowPrivate *) gwDASpectrogram->window;
00763         XSetWindowAttributes xswaAttrib;
00764         xswaAttrib.backing_store = Always;
00765         XChangeWindowAttributes(gwpWindow->xdisplay, gwpWindow->xwindow,
00766             CWBackingStore, &xswaAttrib);
00767     #endif
00768 
00769     // Build drawing primitives
00770     if (!BuildDrawingPrims()) return false;
00771 
00772     // Set default position for paned adjustment
00773     gtk_paned_set_position(GTK_PANED(gwVPaned), 
00774         gwVPaned->allocation.height / 8 * 7);
00775 
00776     // Set cursors
00777     gdk_window_set_cursor(gwDASpectrogram->window, gcCrossHair);
00778     gdk_window_set_cursor(gwDASpectrum->window, gcCrossHair);
00779 
00780     // Draw specified palette to framebuffer and screen
00781     iGramW = gwDASpectrogram->allocation.width;
00782     iGramH = FrameBuf.GetNumColors();
00783     sSResult.lLength = iGramH * 2 - 1;
00784     FrameBuf.SetSize(iGramW, iGramH);
00785     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDASpectrogram),
00786         iGramW, iGramH);
00787     upPalPtr = FrameBuf.GetPalPtr();
00788     upFBPtr = FrameBuf.GetFBPtr();
00789     for (iYCntr = 0; iYCntr < iGramH; iYCntr++)
00790     {
00791         for (iXCntr = 0; iXCntr < iGramW; iXCntr++)
00792         {
00793             iPixIdx = iYCntr * iGramW + iXCntr;
00794             upFBPtr[iPixIdx] = upFBPtr[iGramW * iGramH + iPixIdx] =
00795                 upPalPtr[iYCntr];
00796         }
00797     }
00798 
00799     return true;
00800 }
00801 
00802 
00803 bool clSpectGUI::BuildTable1()
00804 {
00805     // rows, columns, homogenous
00806     gwTable1 = gtk_table_new(2, 5, FALSE);
00807     // box, child, expand, fill, padding
00808     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable1, FALSE, FALSE, 0);
00809     gtk_widget_show(gwTable1);
00810 
00811     // - Label & Combo: Server
00812     gwLServer = gtk_label_new(cpLServerTxt);
00813     gtk_label_set_justify(GTK_LABEL(gwLServer), GTK_JUSTIFY_LEFT);
00814     gtk_table_attach(GTK_TABLE(gwTable1), gwLServer,
00815         0, 1, 0, 1,
00816         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00817         (GtkAttachOptions) 0,
00818         SGUI_PADDING / 2, 0);
00819     gtk_widget_show(gwLServer);
00820     gwCServer = gtk_combo_new();
00821     gtk_entry_set_max_length(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00822         SGUI_SERVER_MAXLEN);
00823     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(gwCServer)->entry),
00824         "127.0.0.1:30001");
00825     // table, child, left attach, right attach, top attach, bottom attach,
00826     // x-options, y-options, x-padding, y-padding
00827     gtk_table_attach(GTK_TABLE(gwTable1), gwCServer,
00828         0, 1, 1, 2,
00829         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00830         (GtkAttachOptions) 0,
00831         SGUI_PADDING / 2, 0);
00832     gtk_widget_show(gwCServer);
00833     GtkUtils.ComboListFromFile(gwCServer, &glServers, SGUI_HOSTFILE);
00834 
00835     // - Label & SpinButton: Channel
00836     if (iBeamCount)
00837         gwLChannel = gtk_label_new(cpaLChannelTxt[1]);
00838     else
00839         gwLChannel = gtk_label_new(cpaLChannelTxt[0]);
00840     gtk_label_set_justify(GTK_LABEL(gwLChannel), GTK_JUSTIFY_LEFT);
00841     gtk_table_attach(GTK_TABLE(gwTable1), gwLChannel,
00842         1, 2, 0, 1,
00843         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00844         SGUI_PADDING / 2, 0);
00845     gtk_widget_show(gwLChannel);
00846     if (iBeamCount)
00847     {
00848         // value, lower limit, upper limit, step increment, page increment,
00849         // page size
00850         goAChannel = gtk_adjustment_new(0.0, -90.0, 90.0, 1.0, 1.0, 1.0);
00851         // adjustment, climb rate, digits
00852         gwSBChannel = gtk_spin_button_new(GTK_ADJUSTMENT(goAChannel), 1.0, 1);
00853     }
00854     else
00855     {
00856         // value, lower limit, upper limit, step increment, page increment,
00857         // page size
00858         goAChannel = gtk_adjustment_new(1.0, SGUI_CH_LOWER, SGUI_CH_UPPER, 1.0,
00859             1.0, 1.0);
00860         // adjustment, climb rate, digits
00861         gwSBChannel = gtk_spin_button_new(GTK_ADJUSTMENT(goAChannel), 1.0, 0);
00862     }
00863     gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(gwSBChannel), TRUE);
00864     gtk_table_attach(GTK_TABLE(gwTable1), gwSBChannel,
00865         1, 2, 1, 2,
00866         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00867         SGUI_PADDING / 2, 0);
00868     gtk_widget_show(gwSBChannel);
00869 
00870     // - Button: Connect
00871     gwBConnect = gtk_button_new_with_label(cpBConnectTxt);
00872     gtk_table_attach(GTK_TABLE(gwTable1), gwBConnect,
00873         2, 3, 1, 2,
00874         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00875         SGUI_PADDING / 2, 0);
00876     gtk_widget_show(gwBConnect);
00877 
00878     // - Button: Disconnect
00879     gwBDisconnect = gtk_button_new_with_label(cpBDisconnectTxt);
00880     gtk_table_attach(GTK_TABLE(gwTable1), gwBDisconnect,
00881         3, 4, 1, 2,
00882         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00883         SGUI_PADDING / 2, 0);
00884     gtk_widget_show(gwBDisconnect);
00885 
00886     // - CheckButton: Freeze
00887     gwCBFreeze = gtk_check_button_new_with_label(cpCBFreezeTxt);
00888     gtk_table_attach(GTK_TABLE(gwTable1), gwCBFreeze,
00889         4, 5, 1, 2,
00890         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00891         SGUI_PADDING / 2, 0);
00892     gtk_widget_show(gwCBFreeze);
00893 
00894     return true;
00895 }
00896 
00897 
00898 bool clSpectGUI::BuildTable2()
00899 {
00900     // rows, columns, homogenous
00901     gwTable2 = gtk_table_new(2, 10, FALSE);  // columns = 11 if BApply
00902     // box, child, expand, fill, padding
00903     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable2, FALSE, FALSE, 0);
00904     gtk_widget_show(gwTable2);
00905     
00906     // - Label & OptionMenu: Type
00907     gwLType = gtk_label_new(cpLTypeTxt);
00908     gtk_label_set_justify(GTK_LABEL(gwLType), GTK_JUSTIFY_LEFT);
00909     gtk_table_attach(GTK_TABLE(gwTable2), gwLType,
00910         0, 1, 0, 1,
00911         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00912         SGUI_PADDING / 2, 0);
00913     gtk_widget_show(gwLType);
00914     gwOMType = gtk_option_menu_new();
00915     gtk_table_attach(GTK_TABLE(gwTable2), gwOMType,
00916         0, 1, 1, 2,
00917         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00918         SGUI_PADDING / 2, 0);
00919     gtk_widget_show(gwOMType);
00920     GtkUtils.BuildOptionMenu(gwOMType, &gwMType, gwaMIType, cpaLTypeMenu, 
00921         SGUI_TYPE_ITEMS);
00922 
00923     // - Label & OptionMenu: Window
00924     gwLWindow = gtk_label_new(cpLWindowTxt);
00925     gtk_label_set_justify(GTK_LABEL(gwLWindow), GTK_JUSTIFY_LEFT);
00926     gtk_table_attach(GTK_TABLE(gwTable2), gwLWindow,
00927         1, 2, 0, 1,
00928         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00929         SGUI_PADDING / 2, 0);
00930     gtk_widget_show(gwLWindow);
00931     gwOMWindow = gtk_option_menu_new();
00932     gtk_table_attach(GTK_TABLE(gwTable2), gwOMWindow,
00933         1, 2, 1, 2,
00934         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00935         SGUI_PADDING / 2, 0);
00936     gtk_widget_show(gwOMWindow);
00937     GtkUtils.BuildOptionMenu(gwOMWindow, &gwMWindow, gwaMIWindow, 
00938         cpaLWindowMenu, SGUI_WINDOW_ITEMS);
00939 
00940     // - Label & Entry: Window parameter
00941     gwLWindowParam = gtk_label_new(cpLWindowParamTxt);
00942     gtk_label_set_justify(GTK_LABEL(gwLWindowParam), GTK_JUSTIFY_LEFT);
00943     gtk_table_attach(GTK_TABLE(gwTable2), gwLWindowParam,
00944         2, 3, 0, 1,
00945         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
00946         (GtkAttachOptions) 0,
00947         SGUI_PADDING / 2, 0);
00948     gtk_widget_show(gwLWindowParam);
00949     gwEWindowParam = gtk_entry_new();
00950     gtk_table_attach(GTK_TABLE(gwTable2), gwEWindowParam,
00951         2, 3, 1, 2,
00952         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00953         (GtkAttachOptions) 0,
00954         SGUI_PADDING / 2, 0);
00955     gtk_widget_show(gwEWindowParam);
00956 
00957     // - Label & OptionMenu: Window length
00958     gwLWindowLen = gtk_label_new(cpLWindowLenTxt);
00959     gtk_label_set_justify(GTK_LABEL(gwLWindowLen), GTK_JUSTIFY_LEFT);
00960     gtk_table_attach(GTK_TABLE(gwTable2), gwLWindowLen,
00961         3, 4, 0, 1,
00962         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00963         SGUI_PADDING / 2, 0);
00964     gtk_widget_show(gwLWindowLen);
00965     gwOMWindowLen = gtk_option_menu_new();
00966     gtk_table_attach(GTK_TABLE(gwTable2), gwOMWindowLen,
00967         3, 4, 1, 2,
00968         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
00969         SGUI_PADDING / 2, 0);
00970     gtk_widget_show(gwOMWindowLen);
00971     GtkUtils.BuildOptionMenu(gwOMWindowLen, &gwMWindowLen, gwaMIWindowLen,
00972         cpaLWindowLenMenu, SGUI_WINLEN_ITEMS);
00973 
00974     // - Label & Entry: Lower frequency
00975     gwLLowFreq = gtk_label_new(cpLLowFreqTxt);
00976     gtk_label_set_justify(GTK_LABEL(gwLLowFreq), GTK_JUSTIFY_LEFT);
00977     gtk_table_attach(GTK_TABLE(gwTable2), gwLLowFreq,
00978         4, 5, 0, 1,
00979         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
00980         (GtkAttachOptions) 0,
00981         SGUI_PADDING / 2, 0);
00982     gtk_widget_show(gwLLowFreq);
00983     gwELowFreq = gtk_entry_new();
00984     gtk_table_attach(GTK_TABLE(gwTable2), gwELowFreq,
00985         4, 5, 1, 2,
00986         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00987         (GtkAttachOptions) 0,
00988         SGUI_PADDING / 2, 0);
00989     gtk_widget_show(gwELowFreq);
00990 
00991     // - Label & Entry: Higher frequency
00992     gwLHighFreq = gtk_label_new(cpLHighFreqTxt);
00993     gtk_label_set_justify(GTK_LABEL(gwLHighFreq), GTK_JUSTIFY_LEFT);
00994     gtk_table_attach(GTK_TABLE(gwTable2), gwLHighFreq,
00995         5, 6, 0, 1,
00996         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
00997         (GtkAttachOptions) 0,
00998         SGUI_PADDING / 2, 0);
00999     gtk_widget_show(gwLHighFreq);
01000     gwEHighFreq = gtk_entry_new();
01001     gtk_table_attach(GTK_TABLE(gwTable2), gwEHighFreq,
01002         5, 6, 1, 2,
01003         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01004         (GtkAttachOptions) 0,
01005         SGUI_PADDING / 2, 0);
01006     gtk_widget_show(gwEHighFreq);
01007 
01008     // - Label & Entry: Gain
01009     gwLGain = gtk_label_new(cpLGainTxt);
01010     gtk_label_set_justify(GTK_LABEL(gwLGain), GTK_JUSTIFY_LEFT);
01011     gtk_table_attach(GTK_TABLE(gwTable2), gwLGain,
01012         6, 7, 0, 1,
01013         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01014         (GtkAttachOptions) 0,
01015         SGUI_PADDING / 2, 0);
01016     gtk_widget_show(gwLGain);
01017     gwEGain = gtk_entry_new();
01018     gtk_table_attach(GTK_TABLE(gwTable2), gwEGain,
01019         6, 7, 1, 2,
01020         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01021         (GtkAttachOptions) 0,
01022         SGUI_PADDING / 2, 0);
01023     gtk_widget_show(gwEGain);
01024 
01025     // - Label & Entry: Slope
01026     gwLSlope = gtk_label_new(cpLSlopeTxt);
01027     gtk_label_set_justify(GTK_LABEL(gwLSlope), GTK_JUSTIFY_LEFT);
01028     gtk_table_attach(GTK_TABLE(gwTable2), gwLSlope,
01029         7, 8, 0, 1,
01030         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01031         (GtkAttachOptions) 0,
01032         SGUI_PADDING / 2, 0);
01033     gtk_widget_show(gwLSlope);
01034     gwESlope = gtk_entry_new();
01035     gtk_table_attach(GTK_TABLE(gwTable2), gwESlope,
01036         7, 8, 1, 2,
01037         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01038         (GtkAttachOptions) 0,
01039         SGUI_PADDING / 2, 0);
01040     gtk_widget_show(gwESlope);
01041 
01042     // - Label & Entry: Overlap
01043     gwLOverlap = gtk_label_new(cpLOverlapTxt);
01044     gtk_label_set_justify(GTK_LABEL(gwLOverlap), GTK_JUSTIFY_LEFT);
01045     gtk_table_attach(GTK_TABLE(gwTable2), gwLOverlap,
01046         8, 9, 0, 1,
01047         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
01048         (GtkAttachOptions) 0,
01049         SGUI_PADDING / 2, 0);
01050     gtk_widget_show(gwLOverlap);
01051     gwEOverlap = gtk_entry_new();
01052     gtk_table_attach(GTK_TABLE(gwTable2), gwEOverlap,
01053         8, 9, 1, 2,
01054         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
01055         (GtkAttachOptions) 0,
01056         SGUI_PADDING / 2, 0);
01057     gtk_widget_show(gwEOverlap);
01058 
01059     // - CheckButton: Linear scale
01060     gwCBLinear = gtk_check_button_new_with_label(cpLLinearTxt);
01061     gtk_table_attach(GTK_TABLE(gwTable2), gwCBLinear,
01062         9, 10, 0, 1,
01063         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01064         SGUI_PADDING / 2, 0);
01065     gtk_widget_show(gwCBLinear);
01066 
01067     // - CheckButton: Normalize display
01068     gwCBNormalize = gtk_check_button_new_with_label(cpLNormalizeTxt);
01069     gtk_table_attach(GTK_TABLE(gwTable2), gwCBNormalize,
01070         9, 10, 1, 2,
01071         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01072         SGUI_PADDING / 2, 0);
01073     gtk_widget_show(gwCBNormalize);
01074 
01075     return true;
01076 }
01077 
01078 
01079 bool clSpectGUI::BuildTable3()
01080 {
01081     // rows, columns, homogenous
01082     gwTable3 = gtk_table_new(2, 7, FALSE);
01083     // box, child, expand, fill, padding
01084     gtk_box_pack_start(GTK_BOX(gwVBox), gwTable3, FALSE, FALSE, 0);
01085     gtk_widget_show(gwTable3);
01086 
01087     // - Label & OptionMenu: Remove noise
01088     gwLRemoveNoise = gtk_label_new(cpLRemoveNoiseTxt);
01089     gtk_label_set_justify(GTK_LABEL(gwLRemoveNoise), GTK_JUSTIFY_LEFT);
01090     gtk_table_attach(GTK_TABLE(gwTable3), gwLRemoveNoise,
01091         0, 1, 0, 1,
01092         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01093         SGUI_PADDING / 2, 0);
01094     gtk_widget_show(gwLRemoveNoise);
01095     gwOMRemoveNoise = gtk_option_menu_new();
01096     gtk_table_attach(GTK_TABLE(gwTable3), gwOMRemoveNoise,
01097         0, 1, 1, 2,
01098         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01099         SGUI_PADDING / 2, 0);
01100     gtk_widget_show(gwOMRemoveNoise);
01101     GtkUtils.BuildOptionMenu(gwOMRemoveNoise, &gwMRemoveNoise, 
01102         gwaMIRemoveNoise, cpaLRemoveNoiseMenu, SGUI_REMOVE_NOISE_ITEMS);
01103 
01104     // - Label & Entry: Alpha
01105     gwLAlpha = gtk_label_new(cpLAlphaTxt);
01106     gtk_label_set_justify(GTK_LABEL(gwLAlpha), GTK_JUSTIFY_LEFT);
01107     gtk_table_attach(GTK_TABLE(gwTable3), gwLAlpha,
01108         1, 2, 0, 1,
01109         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01110         (GtkAttachOptions) 0,
01111         SGUI_PADDING / 2, 0);
01112     gtk_widget_show(gwLAlpha);
01113     gwEAlpha = gtk_entry_new();
01114     gtk_table_attach(GTK_TABLE(gwTable3), gwEAlpha,
01115         1, 2, 1, 2,
01116         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01117         (GtkAttachOptions) 0,
01118         SGUI_PADDING / 2, 0);
01119     gtk_widget_show(gwEAlpha);
01120     gtk_entry_set_text(GTK_ENTRY(gwEAlpha), "2.0");
01121 
01122     // - Label & Entry: Mean length
01123     gwLMeanLength = gtk_label_new(cpLMeanLengthTxt);
01124     gtk_label_set_justify(GTK_LABEL(gwLMeanLength), GTK_JUSTIFY_LEFT);
01125     gtk_table_attach(GTK_TABLE(gwTable3), gwLMeanLength,
01126         2, 3, 0, 1,
01127         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01128         (GtkAttachOptions) 0,
01129         SGUI_PADDING / 2, 0);
01130     gtk_widget_show(gwLMeanLength);
01131     gwEMeanLength = gtk_entry_new();
01132     gtk_table_attach(GTK_TABLE(gwTable3), gwEMeanLength,
01133         2, 3, 1, 2,
01134         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01135         (GtkAttachOptions) 0,
01136         SGUI_PADDING / 2, 0);
01137     gtk_widget_show(gwEMeanLength);
01138     gtk_entry_set_text(GTK_ENTRY(gwEMeanLength), "10");
01139 
01140     // - Label & Entry: Gap length
01141     gwLGapLength = gtk_label_new(cpLGapLengthTxt);
01142     gtk_label_set_justify(GTK_LABEL(gwLGapLength), GTK_JUSTIFY_LEFT);
01143     gtk_table_attach(GTK_TABLE(gwTable3), gwLGapLength,
01144         3, 4, 0, 1,
01145         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01146         (GtkAttachOptions) 0,
01147         SGUI_PADDING / 2, 0);
01148     gtk_widget_show(gwLGapLength);
01149     gwEGapLength = gtk_entry_new();
01150     gtk_table_attach(GTK_TABLE(gwTable3), gwEGapLength,
01151         3, 4, 1, 2,
01152         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01153         (GtkAttachOptions) 0,
01154         SGUI_PADDING / 2, 0);
01155     gtk_widget_show(gwEGapLength);
01156     gtk_entry_set_text(GTK_ENTRY(gwEGapLength), "3");
01157 
01158     // - Label & Entry: Dynamic range
01159     gwLDynRange = gtk_label_new(cpLDynRangeTxt);
01160     gtk_label_set_justify(GTK_LABEL(gwLDynRange), GTK_JUSTIFY_LEFT);
01161     gtk_table_attach(GTK_TABLE(gwTable3), gwLDynRange,
01162         4, 5, 0, 1,
01163         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01164         (GtkAttachOptions) 0,
01165         SGUI_PADDING / 2, 0);
01166     gtk_widget_show(gwLDynRange);
01167     gwEDynRange = gtk_entry_new();
01168     gtk_table_attach(GTK_TABLE(gwTable3), gwEDynRange,
01169         4, 5, 1, 2,
01170         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01171         (GtkAttachOptions) 0,
01172         SGUI_PADDING / 2, 0);
01173     gtk_widget_show(gwEDynRange);
01174     gtk_entry_set_text(GTK_ENTRY(gwEDynRange), "96.3296");
01175 
01176     // - Label & OptionMenu: Palette
01177     gwLPalette = gtk_label_new(cpLPaletteTxt);
01178     gtk_label_set_justify(GTK_LABEL(gwLPalette), GTK_JUSTIFY_LEFT);
01179     gtk_table_attach(GTK_TABLE(gwTable3), gwLPalette,
01180         5, 6, 0, 1,
01181         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01182         SGUI_PADDING / 2, 0);
01183     gtk_widget_show(gwLPalette);
01184     gwOMPalette = gtk_option_menu_new();
01185     gtk_table_attach(GTK_TABLE(gwTable3), gwOMPalette,
01186         5, 6, 1, 2,
01187         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01188         SGUI_PADDING / 2, 0);
01189     gtk_widget_show(gwOMPalette);
01190     GtkUtils.BuildOptionMenu(gwOMPalette, &gwMPalette, gwaMIPalette, 
01191         cpaLPaletteMenu, SGUI_PALETTE_ITEMS);
01192     gtk_option_menu_set_history(GTK_OPTION_MENU(gwOMPalette), iPalette);
01193 
01194     // - Button: Save
01195     gwBSave = gtk_button_new_with_label(cpBSaveTxt);
01196     gtk_table_attach(GTK_TABLE(gwTable3), gwBSave,
01197         6, 7, 1, 2,
01198         (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0,
01199         SGUI_PADDING / 2, 0);
01200     gtk_widget_show(gwBSave);
01201 
01202     // - FileSelection: Save
01203     gwFSSave = gtk_file_selection_new(cpFSSaveTxt);
01204 
01205     return true;
01206 }
01207 
01208 
01209 bool clSpectGUI::BuildTableGram()
01210 {
01211     // rows, columns, homogenous
01212     gwTableGram = gtk_table_new(2, 2, FALSE);
01213     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(gwScrolledW1),
01214         gwTableGram);
01215     gtk_widget_show(gwTableGram);
01216 
01217     // - HorizontalRuler: Time
01218     gwHRTime = gtk_hruler_new();
01219     gtk_ruler_set_metric(GTK_RULER(gwHRTime), GTK_PIXELS);
01220     // ruler, lower, upper, position, max size
01221     gtk_ruler_set_range(GTK_RULER(gwHRTime), -1.0, 0.0, 0.0, 0.0);
01222     gtk_table_attach(GTK_TABLE(gwTableGram), gwHRTime,
01223         1, 2, 0, 1,
01224         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK), 
01225         (GtkAttachOptions) 0,
01226         0, 0);
01227     gtk_widget_show(gwHRTime);
01228 
01229     // - VerticalRuler: Frequency
01230     gwVRFreq = gtk_vruler_new();
01231     gtk_ruler_set_metric(GTK_RULER(gwVRFreq), GTK_PIXELS);
01232     gtk_ruler_set_range(GTK_RULER(gwVRFreq), 22.05, 0.0, 0.0, 22.05);
01233     gtk_table_attach(GTK_TABLE(gwTableGram), gwVRFreq,
01234         0, 1, 1, 2,
01235         (GtkAttachOptions) 0, 
01236         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01237         0, 0);
01238     gtk_widget_show(gwVRFreq);
01239 
01240     // - DrawingArea: Spectrogram
01241     gwDASpectrogram = gtk_drawing_area_new();
01242     gtk_table_attach(GTK_TABLE(gwTableGram), gwDASpectrogram,
01243         1, 2, 1, 2,
01244         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01245         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01246         0, 0);
01247     gtk_widget_show(gwDASpectrogram);
01248 
01249     return true;
01250 }
01251 
01252 
01253 bool clSpectGUI::BuildTableSpect()
01254 {
01255     // rows, columns, homogenous
01256     gwTableSpect = gtk_table_new(2, 2, FALSE);
01257     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(gwScrolledW2),
01258         gwTableSpect);
01259     gtk_widget_show(gwTableSpect);
01260 
01261     // - HorizontalRuler: Frequency
01262     gwHRFreq = gtk_hruler_new();
01263     gtk_ruler_set_metric(GTK_RULER(gwHRFreq), GTK_PIXELS);
01264     // ruler, lower, upper, position, max size
01265     gtk_ruler_set_range(GTK_RULER(gwHRFreq), 0.0, 22.05, 0.0, 22.05);
01266     gtk_table_attach(GTK_TABLE(gwTableSpect), gwHRFreq,
01267         1, 2, 0, 1,
01268         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01269         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01270         0, 0);
01271     gtk_widget_show(gwHRFreq);
01272 
01273     // - VerticalRuler: Level
01274     gwVRLevel = gtk_vruler_new();
01275     gtk_ruler_set_metric(GTK_RULER(gwVRLevel), GTK_PIXELS);
01276     gtk_ruler_set_range(GTK_RULER(gwVRLevel), 0.0, -96.0, 0.0, 0.0);
01277     gtk_table_attach(GTK_TABLE(gwTableSpect), gwVRLevel,
01278         0, 1, 1, 2,
01279         (GtkAttachOptions) 0,
01280         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01281         0, 0);
01282     gtk_widget_show(gwVRLevel);
01283 
01284     // - DrawingArea: Spectrum
01285     gwDASpectrum = gtk_drawing_area_new();
01286     gtk_table_attach(GTK_TABLE(gwTableSpect), gwDASpectrum,
01287         1, 2, 1, 2,
01288         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01289         (GtkAttachOptions) (GTK_FILL|GTK_EXPAND|GTK_SHRINK),
01290         0, 0);
01291     gtk_widget_show(gwDASpectrum);
01292 
01293     return true;
01294 }
01295 
01296 
01297 bool clSpectGUI::BuildDrawingPrims()
01298 {
01299     int iPalType;
01300 
01301     // Create graphics contexts
01302     ggcGramBG = gdk_gc_new(gwDASpectrogram->window);
01303     gdk_rgb_gc_set_foreground(ggcGramBG, SGUI_GRAM_BG);
01304     gdk_rgb_gc_set_background(ggcGramBG, SGUI_GRAM_BG);
01305     gdk_gc_set_function(ggcGramBG, GDK_COPY);
01306     gdk_gc_set_fill(ggcGramBG, GDK_SOLID);
01307 
01308     ggcGramFG = gdk_gc_new(gwDASpectrogram->window);
01309     gdk_rgb_gc_set_foreground(ggcGramFG, SGUI_GRAM_FG);
01310     gdk_rgb_gc_set_background(ggcGramFG, SGUI_GRAM_BG);
01311     gdk_gc_set_function(ggcGramFG, GDK_COPY);
01312     gdk_gc_set_fill(ggcGramFG, GDK_SOLID);
01313 
01314     ggcSpectBG = gdk_gc_new(gwDASpectrum->window);
01315     gdk_rgb_gc_set_foreground(ggcSpectBG, SGUI_SPECT_BG);
01316     gdk_rgb_gc_set_background(ggcSpectBG, SGUI_SPECT_BG);
01317     gdk_gc_set_function(ggcSpectBG, GDK_COPY);
01318     gdk_gc_set_fill(ggcSpectBG, GDK_SOLID);
01319 
01320     ggcSpectFG = gdk_gc_new(gwDASpectrum->window);
01321     gdk_rgb_gc_set_foreground(ggcSpectFG, SGUI_SPECT_FG);
01322     gdk_rgb_gc_set_background(ggcSpectFG, SGUI_SPECT_BG);
01323     gdk_gc_set_function(ggcSpectFG, GDK_COPY);
01324     gdk_gc_set_fill(ggcSpectFG, GDK_SOLID);
01325 
01326     // Create cursors
01327     gcCrossHair = gdk_cursor_new(GDK_CROSSHAIR);
01328 
01329     // Create specified palette for spectrogram
01330     CfgFile->GetInt("Palette", &iPalType);
01331     switch (iPalType)
01332     {
01333         case SGUI_PAL_BW:
01334             FrameBuf.PalGenBW();
01335             break;
01336         case SGUI_PAL_HSV:
01337             FrameBuf.PalGenHSV();
01338             break;
01339         case SGUI_PAL_LIGHT:
01340             FrameBuf.PalGenLight();
01341             break;
01342         case SGUI_PAL_TEMP:
01343             FrameBuf.PalGenTemp();
01344             break;
01345         case SGUI_PAL_DIR:
01346             FrameBuf.PalGenDir();
01347             break;
01348         case SGUI_PAL_GREEN:
01349             FrameBuf.PalGenGreen();
01350             break;
01351         default:
01352             FrameBuf.PalGenBW();
01353     }
01354 
01355     return true;
01356 }
01357 
01358 
01359 void clSpectGUI::FreeDrawingPrims()
01360 {
01361     gdk_cursor_destroy(gcCrossHair);
01362     gdk_gc_destroy(ggcGramBG);
01363     gdk_gc_destroy(ggcGramFG);
01364     gdk_gc_destroy(ggcSpectBG);
01365     gdk_gc_destroy(ggcSpectFG);
01366 }
01367 
01368 
01369 bool clSpectGUI::ConnectSignals()
01370 {
01371     int iWidgetCntr;
01372     
01373     gtk_widget_add_events(gwDASpectrogram, GDK_POINTER_MOTION_MASK);
01374     GtkUtils.ConnectMotionEvent(gwHRTime, gwDASpectrogram);
01375     GtkUtils.ConnectMotionEvent(gwVRFreq, gwDASpectrogram);
01376     gtk_widget_add_events(gwDASpectrum, GDK_POINTER_MOTION_MASK);
01377     GtkUtils.ConnectMotionEvent(gwHRFreq, gwDASpectrum);
01378     GtkUtils.ConnectMotionEvent(gwVRLevel, gwDASpectrum);
01379     gtk_signal_connect(GTK_OBJECT(gwWindow), "delete_event",
01380         GTK_SIGNAL_FUNC(WrapOnDelete), NULL);
01381     gtk_signal_connect(GTK_OBJECT(gwCBHide), "toggled",
01382         GTK_SIGNAL_FUNC(WrapOnHideToggled), NULL);
01383     gtk_signal_connect(GTK_OBJECT(gwBConnect), "clicked",
01384         GTK_SIGNAL_FUNC(WrapOnConnectClick), NULL);
01385     gtk_signal_connect(GTK_OBJECT(gwBDisconnect), "clicked",
01386         GTK_SIGNAL_FUNC(WrapOnConnectClick), NULL);
01387     gtk_signal_connect(GTK_OBJECT(gwCBFreeze), "toggled",
01388         GTK_SIGNAL_FUNC(WrapOnFreezeToggled), NULL);
01389     for (iWidgetCntr = 0; iWidgetCntr < SGUI_PALETTE_ITEMS; iWidgetCntr++)
01390     {
01391         gtk_signal_connect(GTK_OBJECT(gwaMIPalette[iWidgetCntr]), "activate",
01392             GTK_SIGNAL_FUNC(WrapOnPaletteActivate), NULL);
01393     }
01394     gtk_signal_connect(GTK_OBJECT(gwDASpectrogram), "motion_notify_event",
01395         GTK_SIGNAL_FUNC(WrapOnMotionSgram), NULL);
01396     gtk_signal_connect(GTK_OBJECT(gwDASpectrum), "motion_notify_event",
01397         GTK_SIGNAL_FUNC(WrapOnMotionSpect), NULL);
01398     gtk_signal_connect(GTK_OBJECT(gwDASpectrogram), "expose_event",
01399         GTK_SIGNAL_FUNC(WrapOnExposeSgram), NULL);
01400     gtk_signal_connect(GTK_OBJECT(gwDASpectrum), "expose_event",
01401         GTK_SIGNAL_FUNC(WrapOnExposeSpect), NULL);
01402     gtk_signal_connect(GTK_OBJECT(gwDASpectrogram), "size-allocate",
01403         GTK_SIGNAL_FUNC(WrapOnSizeAllocate), NULL);
01404 
01405     gtk_signal_connect(GTK_OBJECT(gwScrolledW2), "size-allocate",
01406         GTK_SIGNAL_FUNC(WrapOnSizeAllocate), NULL);
01407 
01408     gtk_signal_connect(GTK_OBJECT(gwBSave), "clicked",
01409         GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(2));
01410     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gwFSSave)->ok_button),
01411         "clicked", GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(1));
01412     gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(gwFSSave)->cancel_button),
01413         "clicked", GTK_SIGNAL_FUNC(WrapOnSaveClicks), GINT_TO_POINTER(0));
01414 
01415     return true;
01416 }
01417 
01418 
01419 int clSpectGUI::GetGramHeight ()
01420 {
01421     return (gwScrolledW1->allocation.height - gwHRTime->allocation.height - 2);
01422 }
01423 
01424 
01425 bool clSpectGUI::ParseServerStr(char *cpHostRes, int *ipPortRes,
01426     const char *cpSourceStr)
01427 {
01428     char cpTempStr[SGUI_SERVER_MAXLEN + 1];
01429     char *cpTempHost;
01430     char *cpTempPort;
01431 
01432     strncpy(cpTempStr, cpSourceStr, SGUI_SERVER_MAXLEN);
01433     cpTempHost = strtok(cpTempStr, ": \t\n");
01434     if (cpTempHost != NULL)
01435     {
01436         strcpy(cpHostRes, cpTempHost);
01437         cpTempPort = strtok(NULL, " \t\n");
01438         if (cpTempPort != NULL)
01439         {
01440             *ipPortRes = atoi(cpTempPort);
01441             if (*ipPortRes > 0) return true;
01442         }
01443     }
01444     return false;
01445 }
01446 
01447 
01448 bool clSpectGUI::InitConnection(const char *cpServerHost, int iServerPort)
01449 {
01450     char cpReqProcName[GLOBAL_HEADER_LEN];
01451     
01452     GetSettings();
01453     iSockH = SockClie.Connect(cpServerHost, NULL, iServerPort);
01454     if (iSockH < 0) return false;
01455     g_print("Connection established - sending process request...\n");
01456     bConnected = true;
01457     SockOp = new clSockOp(iSockH);
01458     strcpy(cpReqProcName, SGUI_REQ_PROC);
01459     if (SockOp->WriteN(cpReqProcName, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN) 
01460         return false;
01461     g_print("Sending initial settings...\n");
01462     if (!SendSettings()) return false;
01463     giGdkTag = gdk_input_add(iSockH, GDK_INPUT_READ, WrapGdkInput, NULL);
01464     iClips = 0;
01465     return true;
01466 }
01467 
01468 
01469 void clSpectGUI::GetSettings()
01470 {
01471     float fDirection;
01472     int iItem;
01473     size_t iSpectSize;
01474 
01475     if (iBeamCount)
01476     {
01477         fDirection = gtk_spin_button_get_value_as_float(
01478             GTK_SPIN_BUTTON(gwSBChannel)) + 90.0f;
01479         sSRequest.iChannel = (int)
01480             (fDirection / (180.0f / (float) (iBeamCount - 1)));
01481         g_print("Channel: %i\n", sSRequest.iChannel);
01482     }
01483     else
01484     {
01485         sSRequest.iChannel = gtk_spin_button_get_value_as_int(
01486             GTK_SPIN_BUTTON(gwSBChannel)) - 1;
01487     }
01488     sSRequest.iType = GtkUtils.OptionMenuGetActive(gwOMType,
01489         gwaMIType, SGUI_TYPE_ITEMS);
01490     sSRequest.iWindow = GtkUtils.OptionMenuGetActive(gwOMWindow,
01491         gwaMIWindow, SGUI_WINDOW_ITEMS);
01492     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEWindowParam)), "%g",
01493         &sSRequest.fWinParam);
01494     iItem = GtkUtils.OptionMenuGetActive(gwOMWindowLen, gwaMIWindowLen,
01495         SGUI_WINLEN_ITEMS);
01496     if (iItem >= 0) sSRequest.lLength = atol(cpaLWindowLenMenu[iItem]);
01497     else sSRequest.lLength = atol(cpaLWindowLenMenu[0]);
01498     sSRequest.iLowFreq = atoi(gtk_entry_get_text(GTK_ENTRY(gwELowFreq)));
01499     sSRequest.iHighFreq = atoi(gtk_entry_get_text(GTK_ENTRY(gwEHighFreq)));
01500     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEGain)), "%g",
01501         &sSRequest.fGain);
01502     sscanf(gtk_entry_get_text(GTK_ENTRY(gwESlope)), "%g",
01503         &sSRequest.fSlope);
01504     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEOverlap)), "%d",
01505         &sSRequest.iOverlap);
01506     sSRequest.bLinear = 
01507         (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gwCBLinear)) == TRUE) ?
01508         true : false;
01509     sSRequest.bNormalize = (gtk_toggle_button_get_active(
01510         GTK_TOGGLE_BUTTON(gwCBNormalize)) == TRUE) ?
01511         true : false;
01512     sSRequest.iRemoveNoise = GtkUtils.OptionMenuGetActive(gwOMRemoveNoise,
01513         gwaMIRemoveNoise, SGUI_REMOVE_NOISE_ITEMS);
01514     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEAlpha)), "%g", &sSRequest.fAlpha);
01515     sSRequest.lMeanLength = atol(gtk_entry_get_text(GTK_ENTRY(gwEMeanLength)));
01516     sSRequest.lGapLength = atol(gtk_entry_get_text(GTK_ENTRY(gwEGapLength)));
01517     sscanf(gtk_entry_get_text(GTK_ENTRY(gwEDynRange)), "%g", 
01518         &sSRequest.fDynRange);
01519 
01520     // Memory allocation for requested spectrum size
01521     switch (sSRequest.iType)
01522     {
01523         case MSG_SPECT_TYPE_FFT:
01524             iSpectSize = (sSRequest.lLength / 2 + 1) * sizeof(GDT);
01525             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01526             break;
01527         /*case MSG_SPECT_TYPE_MRFFT:
01528             iSpectSize = (sSRequest.lLength / 2 + 1) * 
01529                 sizeof(GDT) * CountBands(sSRequest.lFreqDiv);
01530             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01531             break;*/
01532         case MSG_SPECT_TYPE_GABOR:
01533             iSpectSize = 0;
01534             iRcvMsgSize = GLOBAL_HEADER_LEN;
01535             break;
01536         case MSG_SPECT_TYPE_WVD:
01537             iSpectSize = (sSRequest.lLength / 2 + 1) * sizeof(GDT);
01538             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01539             break;
01540         case MSG_SPECT_TYPE_HANKEL:
01541             iSpectSize = (sSRequest.lLength / 2 + 1) * sizeof(GDT);
01542             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01543             break;
01544         case MSG_SPECT_TYPE_AUTOCORR:
01545             iSpectSize = (sSRequest.lLength / 2) * sizeof(GDT);
01546             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01547             break;
01548         case MSG_SPECT_TYPE_CEPSTRUM:
01549             iSpectSize = (sSRequest.lLength / 2) * sizeof(GDT);
01550             iRcvMsgSize = GLOBAL_HEADER_LEN + iSpectSize;
01551             break;
01552         default:
01553             iSpectSize = 0;
01554     }
01555     cpRcvMsgBuf = (char *) RcvMsgBuf.Size(iRcvMsgSize);
01556     fpSpect = (GDT *) SpectBuf.Size(iSpectSize);
01557 }
01558 
01559 
01560 bool clSpectGUI::SendSettings()
01561 {
01562     char cpMsgBuf[GLOBAL_HEADER_LEN];
01563 
01564     SpectMsg.SetRequest(cpMsgBuf, &sSRequest);
01565     if (SockOp->WriteN(cpMsgBuf, GLOBAL_HEADER_LEN) < GLOBAL_HEADER_LEN)
01566         return false;
01567     bReConfig = true;
01568     return true;
01569 }
01570 
01571 
01572 void clSpectGUI::ReConfigDisplay()
01573 {
01574     gfloat fSpectTime;
01575     gfloat fMaxFreq;
01576     gfloat fMinFreq;
01577     gfloat fLowKHz;
01578     gfloat fHighKHz;
01579     gfloat fWinWidth;
01580     gfloat fWinHeight;
01581     
01582     iSpectPoints = sSResult.lLength;
01583     if (!iFit) iGramH = iSpectPoints;
01584     //iGramH = GetGramHeight();
01585     FrameBuf.SetSize(iGramW, iGramH);
01586     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDASpectrogram),
01587         iGramW, iGramH);
01588     gtk_drawing_area_size(GTK_DRAWING_AREA(gwDASpectrum),
01589         iSpectPoints, iSpectH);
01590     fSpectTime = sSResult.fLineTime * iGramW;
01591     fLowKHz = (gfloat) sSResult.iLowFreq / (gfloat) 1000.0;
01592     fHighKHz = (gfloat) sSResult.iHighFreq / (gfloat) 1000.0;
01593     gtk_ruler_set_range(GTK_RULER(gwHRTime), 
01594         fSpectTime, 0.0,
01595         0.0, fSpectTime);
01596     if (gwHRFreq->allocation.width > iSpectPoints)
01597     {
01598         fWinWidth = (gfloat) gwHRFreq->allocation.width;
01599         fMaxFreq = fLowKHz + (fHighKHz - fLowKHz) * 
01600             (fWinWidth / (gfloat) iSpectPoints);
01601         gtk_ruler_set_range(GTK_RULER(gwHRFreq),
01602             fLowKHz, fMaxFreq,
01603             fLowKHz, fMaxFreq);
01604     }
01605     else
01606     {
01607         gtk_ruler_set_range(GTK_RULER(gwHRFreq),
01608             fLowKHz, fHighKHz,
01609             fLowKHz, fHighKHz);
01610     }
01611     if (sSResult.bLinear)
01612     {
01613         gtk_ruler_set_range(GTK_RULER(gwVRLevel),
01614             1.0, 0.0,
01615             0.0, 1.0);
01616     }
01617     else
01618     {
01619         gtk_ruler_set_range(GTK_RULER(gwVRLevel),
01620             0.0, -sSRequest.fDynRange,
01621             0.0, 0.0);
01622     }
01623     if (gwVRFreq->allocation.height > iGramH)
01624     {
01625         fWinHeight = (gfloat) gwVRFreq->allocation.height;
01626         fMinFreq = fLowKHz - (fWinHeight - (gfloat) iGramH) * 
01627             ((fHighKHz - fLowKHz) / (gfloat) iGramH);
01628         gtk_ruler_set_range(GTK_RULER(gwVRFreq),
01629             fHighKHz, fMinFreq,
01630             fLowKHz, fHighKHz);
01631     }
01632     else
01633     {
01634         gtk_ruler_set_range(GTK_RULER(gwVRFreq),
01635             fHighKHz, fLowKHz,
01636             fLowKHz, fHighKHz);
01637     }
01638     bReConfig = false;
01639 }
01640 
01641 
01642 void clSpectGUI::DrawSpectrogram()
01643 {
01644     int iYPos;
01645     int iViewHeight;
01646     GtkAdjustment *gaVScrollBar;
01647     GdkWindow *gwGramWin;
01648 
01649     if (iFit)
01650     {
01651         fpIntSpect = (GDT *)
01652             IntSpectBuf.Size(iGramH * sizeof(GDT));
01653         switch (iFit)
01654         {
01655             case SGUI_FIT_NEIGHBOR:
01656                 DSP.Resample(fpIntSpect, iGramH, fpSpect, iSpectPoints);
01657                 break;
01658             case SGUI_FIT_AVERAGE:
01659                 DSP.ResampleAvg(fpIntSpect, iGramH, fpSpect, iSpectPoints);
01660                 break;
01661             default:
01662                 g_warning("Invalid fill algorithm!");
01663         }
01664         FrameBuf.DrawColumn(fpIntSpect);
01665     }
01666     else
01667     {
01668         FrameBuf.DrawColumn(fpSpect);
01669     }
01670 
01671     gaVScrollBar = gtk_scrolled_window_get_vadjustment(
01672         GTK_SCROLLED_WINDOW(gwScrolledW1));
01673     gwGramWin = gwDASpectrogram->window;
01674     iYPos = (int) gaVScrollBar->value - gwHRTime->allocation.height;
01675     if (iYPos < 0) iYPos = 0;
01676     iViewHeight = (iYPos < 0) ?
01677         ((int) gaVScrollBar->page_size + iYPos) : 
01678         (int) gaVScrollBar->page_size;
01679     if (iViewHeight > iGramH) iViewHeight = iGramH;
01680     if (iYPos < 0) iYPos = 0;
01681     if (iYPos > iGramH) return;
01682     #ifndef USE_BACKING_STORE
01683         gdk_window_copy_area(gwGramWin, ggcGramFG,
01684             0, iYPos,
01685             gwGramWin,
01686             1, iYPos, 
01687             iGramW, iViewHeight);  // here should be iGramW - 1
01688         gdk_draw_rgb_32_image(gwGramWin, ggcGramFG,
01689             iGramW, iYPos,  // and here iGramW - 1
01690             1, iViewHeight,
01691             GDK_RGB_DITHER_NONE,
01692             FrameBuf.GetCurPtr(iGramW - 1, iYPos),
01693             FrameBuf.GetRowStride());
01694     #else
01695         gdk_window_copy_area(gwGramWin, ggcGramFG,
01696             0, 0,
01697             gwGramWin,
01698             1, 0,
01699             iGramW - 1, iGramH);
01700         gdk_draw_rgb_32_image(gwGramWin, ggcGramFG,
01701             iGramW - 1, 0,
01702             1, iGramH,
01703             GDK_RGB_DITHER_NONE,
01704             FrameBuf.GetCurPtr(iGramW - 1, 0),
01705             FrameBuf.GetRowStride());
01706     #endif
01707 }
01708 
01709 
01710 void clSpectGUI::DrawSpectrum()
01711 {
01712     int iMaxLine;
01713     int iLineCntr;
01714     int iLineLength;
01715     int iXPos;
01716     int iViewWidth;
01717     GtkAdjustment *gaHScrollBar;
01718     GdkWindow *gwSpectWin;
01719     
01720     gaHScrollBar = gtk_scrolled_window_get_hadjustment(
01721         GTK_SCROLLED_WINDOW(gwScrolledW2));
01722     gwSpectWin = gwDASpectrum->window;
01723     iXPos = (int) gaHScrollBar->value;
01724     iViewWidth = (int) gaHScrollBar->page_size;
01725     gdk_window_clear(gwSpectWin);
01726     iMaxLine = (iSpectPoints <= (iXPos + iViewWidth)) ?
01727         iSpectPoints : iXPos + iViewWidth;
01728     for (iLineCntr = iXPos; iLineCntr < iMaxLine; iLineCntr++)
01729     {
01730         iLineLength = (int) (fpSpect[iLineCntr] * (GDT) (iSpectH - 1) + 0.5);
01731         if (iLineLength < 0) iLineLength = 0;
01732         if (iLineLength >= iSpectH) iLineLength = iSpectH - 1;
01733         gdk_draw_line(gwSpectWin, ggcSpectFG,
01734             iLineCntr, iSpectH - 1, iLineCntr, iSpectH - iLineLength);
01735     }
01736 }
01737 
01738 
01739 void clSpectGUI::PrintRealTime()
01740 {
01741     time_t ttCursorTime;
01742     struct tm *spCursorTime;
01743 
01744     ttCursorTime = sSResult.sTimeStamp.tv_sec - (time_t) (fGramX + 0.5F);
01745     spCursorTime = localtime(&ttCursorTime);
01746     strftime(cpGramXTime, 20, "%d.%m.%Y %H:%M:%S", spCursorTime);
01747 }
01748 
01749 
01750 long clSpectGUI::CountBands(long lDivisor)
01751 {
01752     float fNyquist;
01753     float fFreq;
01754     long lDivCntr = 0L;
01755 
01756     fNyquist = 44100.0F / 2.0F;
01757     fFreq = fNyquist;
01758     while (fFreq > SPECT_BAND_LIMIT)
01759     {
01760         lDivCntr++;
01761         fFreq /= (float) lDivisor;
01762     }
01763     return (lDivCntr - 1);
01764 }
01765 
01766 
01767 void clSpectGUI::SaveInfo (const char *cpFileName)
01768 {
01769     time_t ttTime;
01770     char *cpFullFileName;
01771     char cpTime[24];
01772     FILE *fileInfo;
01773 
01774     cpFullFileName = g_strdup_printf("%s.inf", cpFileName);
01775     fileInfo = fopen(cpFullFileName, FB_TIFF_MODE);
01776     g_free(cpFullFileName);
01777     if (fileInfo == NULL) return;
01778     time(&ttTime);
01779     strftime(cpTime, 23, "%Y/%m/%d %H:%M:%S", localtime(&ttTime));
01780     fprintf(fileInfo, "Time: %s\n", cpTime);
01781     fprintf(fileInfo, "LowFreq: %i\n", sSResult.iLowFreq);
01782     fprintf(fileInfo, "HighFreq: %i\n", sSResult.iHighFreq);
01783     fprintf(fileInfo, "LineTime: %f\n", sSResult.fLineTime);
01784     fclose(fileInfo);
01785 }

Generated on Sun Oct 26 19:11:21 2003 for HASAS by doxygen 1.3.3