Update of /cvsroot/audacity/audacity-src/src/widgets
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv3511/widgets

Modified Files:
        Meter.cpp Meter.h 
Log Message:
basic MixerBoard port from UmixIt. 

Lots of things to tweak yet. More commits later today.

Index: Meter.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/widgets/Meter.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- Meter.h     10 Nov 2008 20:31:15 -0000      1.12
+++ Meter.h     9 Jul 2009 23:52:18 -0000       1.13
@@ -84,15 +84,6 @@
    DECLARE_DYNAMIC_CLASS(Meter)
 
  public:
-   Meter(wxWindow* parent, wxWindowID id,
-         bool isInput,
-         const wxPoint& pos = wxDefaultPosition,
-         const wxSize& size = wxDefaultSize);
-
-   ~Meter();
-
-   void UpdatePrefs();
-
    // These should be kept in the same order as they appear
    // in the menu
    enum Style {
@@ -100,9 +91,21 @@
       VerticalStereo,
       VerticalMulti,
       Equalizer,
-      Waveform
+      Waveform, 
+      MixerTrackCluster // Doesn't show menu, icon, or L/R labels, but 
otherwise like VerticalStereo.
    };
 
+
+   Meter(wxWindow* parent, wxWindowID id,
+         bool isInput,
+         const wxPoint& pos = wxDefaultPosition,
+         const wxSize& size = wxDefaultSize, 
+         Style style = HorizontalStereo);
+
+   ~Meter();
+
+   void UpdatePrefs();
+
    Style GetStyle() { return mStyle; }
    void SetStyle(Style newStyle);
 
@@ -112,6 +115,7 @@
     * different thread (like from an audio I/O callback).
     */
    void Reset(double sampleRate, bool resetClipping);
+
    /** \brief Update the meters with a block of audio data
     *
     * Process the supplied block of audio data, extracting the peak and RMS
@@ -119,6 +123,8 @@
     * clipping that lies on block boundaries.
     * This method is thread-safe!  Feel free to call from a different thread
     * (like from an audio I/O callback).
+    *
+    * First overload:
     * \param numChannels The number of channels of audio being played back or
     * recorded.
     * \param numFrames The number of frames (samples) in this data block. It is
@@ -129,9 +135,16 @@
     * then the second sample of channel 1, second sample of channel 2, and so
     * to the second sample of channel (numChannels). The last sample in the
     * array will be the (numFrames) sample for channel (numChannels).
+    *
+    * The second overload is for ease of use in MixerBoard.
     */
    void UpdateDisplay(int numChannels,
                       int numFrames, float *sampleData);
+   void UpdateDisplay(int numChannels, int numFrames, 
+                        // Need to make these double-indexed max and min 
arrays if we handle more than 2 channels.
+                        float* maxLeft, float* rmsLeft, 
+                        float* maxRight, float* rmsRight);
+
    /** \brief Find out if the level meter is disabled or not.
     *
     * This method is thread-safe!  Feel free to call from a

Index: Meter.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/widgets/Meter.cpp,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- Meter.cpp   6 Jul 2009 07:41:18 -0000       1.43
+++ Meter.cpp   9 Jul 2009 23:52:18 -0000       1.44
@@ -5,6 +5,7 @@
   Meter.cpp
 
   Dominic Mazzoni
+  Vaughan Johnson
 
   2004.06.25 refresh rate limited to 30mS, by ChackoN
 
@@ -16,6 +17,10 @@
   This is a bunch of common code that can display many different
   forms of VU meters and other displays.
 
+  But note that a lot of later code here assumes these are 
+  MeterToolBar meters, e.g., Meter::StartMonitoring, 
+  so these are not as generic/common as originally intended.
+
 *//****************************************************************//**
 
 \class MeterBar
@@ -40,10 +45,7 @@
 #include <wx/dcmemory.h>
 #include <wx/image.h>
 #include <wx/intl.h>
-#define WANT_METER_MENU 1 //vvv
-#if WANT_METER_MENU
-   #include <wx/menu.h>
-#endif
+#include <wx/menu.h>
 #include <wx/settings.h>
 #include <wx/textdlg.h>
 #include <wx/numdlg.h>
@@ -185,20 +187,18 @@
    EVT_ERASE_BACKGROUND(Meter::OnErase)
    EVT_PAINT(Meter::OnPaint)
    EVT_SIZE(Meter::OnSize)
-   #if WANT_METER_MENU
-      EVT_MENU(OnDisableMeterID, Meter::OnDisableMeter)
-      EVT_MENU(OnHorizontalID, Meter::OnHorizontal)
-      EVT_MENU(OnVerticalID, Meter::OnVertical)
-      EVT_MENU(OnMultiID, Meter::OnMulti)
-      EVT_MENU(OnEqualizerID, Meter::OnEqualizer)
-      EVT_MENU(OnWaveformID, Meter::OnWaveform)
-      EVT_MENU(OnLinearID, Meter::OnLinear)
-      EVT_MENU(OnDBID, Meter::OnDB)
-      EVT_MENU(OnClipID, Meter::OnClip)
-      EVT_MENU(OnMonitorID, Meter::OnMonitor)
-      EVT_MENU(OnFloatID, Meter::OnFloat)
-      EVT_MENU(OnPreferencesID, Meter::OnPreferences)
-   #endif
+   EVT_MENU(OnDisableMeterID, Meter::OnDisableMeter)
+   EVT_MENU(OnHorizontalID, Meter::OnHorizontal)
+   EVT_MENU(OnVerticalID, Meter::OnVertical)
+   EVT_MENU(OnMultiID, Meter::OnMulti)
+   EVT_MENU(OnEqualizerID, Meter::OnEqualizer)
+   EVT_MENU(OnWaveformID, Meter::OnWaveform)
+   EVT_MENU(OnLinearID, Meter::OnLinear)
+   EVT_MENU(OnDBID, Meter::OnDB)
+   EVT_MENU(OnClipID, Meter::OnClip)
+   EVT_MENU(OnMonitorID, Meter::OnMonitor)
+   EVT_MENU(OnFloatID, Meter::OnFloat)
+   EVT_MENU(OnPreferencesID, Meter::OnPreferences)
 END_EVENT_TABLE()
 
 IMPLEMENT_CLASS(Meter, wxPanel)
@@ -206,12 +206,13 @@
 Meter::Meter(wxWindow* parent, wxWindowID id,
              bool isInput,
              const wxPoint& pos /*= wxDefaultPosition*/,
-             const wxSize& size /*= wxDefaultSize*/):
-   wxPanel(parent, id, pos, size),
+             const wxSize& size /*= wxDefaultSize*/, 
+             Style style /*= HorizontalStereo*/)
+: wxPanel(parent, id, pos, size),
    mQueue(1024),
    mWidth(size.x), mHeight(size.y),
    mIsInput(isInput),
-   mStyle(HorizontalStereo),
+   mStyle(style),
    mDB(true),
    mDBRange(ENV_DB_RANGE),
    mDecay(true),
@@ -276,7 +277,10 @@
       mRMSBrush = mDisabledBkgndBrush;
    }
 
-   CreateIcon(2);
+   // MixerTrackCluster style has no menu, so disallows SetStyle, so never 
needs icon.
+   if (mStyle != MixerTrackCluster)
+      CreateIcon(2);
+
    mRuler.SetFonts(GetFont(), GetFont(), GetFont());
 
    mTimer.SetOwner(this, OnMeterUpdateID);
@@ -361,6 +365,9 @@
 
 void Meter::OnMouse(wxMouseEvent &evt)
 {
+   if (mStyle == MixerTrackCluster) // MixerTrackCluster style has no menu.
+      return;
+
   #if wxUSE_TOOLTIPS // Not available in wxX11
    if (evt.Leaving()){
       GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
@@ -375,57 +382,51 @@
    }
   #endif
 
-   #if WANT_METER_MENU
-      if (evt.RightDown() ||
-          (evt.ButtonDown() && mMenuRect.Contains(evt.m_x, evt.m_y))) 
-      {
-         wxMenu *menu = new wxMenu();
-         // Note: these should be kept in the same order as the enum
-         if (mMeterDisabled)
-            menu->Append(OnDisableMeterID, _("Enable Meter"));
+   if (evt.RightDown() ||
+       (evt.ButtonDown() && mMenuRect.Contains(evt.m_x, evt.m_y))) 
+   {
+      wxMenu *menu = new wxMenu();
+      // Note: these should be kept in the same order as the enum
+      if (mMeterDisabled)
+         menu->Append(OnDisableMeterID, _("Enable Meter"));
+      else
+         menu->Append(OnDisableMeterID, _("Disable Meter"));
+      if (mIsInput) {
+         if (gAudioIO->IsMonitoring())
+            menu->Append(OnMonitorID, _("Stop Monitoring"));
          else
-            menu->Append(OnDisableMeterID, _("Disable Meter"));
-         if (mIsInput) {
-            if (gAudioIO->IsMonitoring())
-               menu->Append(OnMonitorID, _("Stop Monitoring"));
-            else
-               menu->Append(OnMonitorID, _("Start Monitoring"));
-         }
-         menu->AppendSeparator();
-
-         menu->Append(OnHorizontalID, _("Horizontal Stereo"));
-         menu->Append(OnVerticalID, _("Vertical Stereo"));
-         //menu->Append(OnMultiID, _("Vertical Multichannel"));
-         //menu->Append(OnEqualizerID, _("Equalizer"));
-         //menu->Append(OnWaveformID, _("Waveform"));
-         //menu->Enable(OnHorizontalID + mStyle, false);
-         menu->Enable(mStyle==VerticalStereo? OnVerticalID: OnHorizontalID, 
false);
-         menu->AppendSeparator();
+            menu->Append(OnMonitorID, _("Start Monitoring"));
+      }
+      menu->AppendSeparator();
 
-         menu->Append(OnLinearID, _("Linear"));
-         menu->Append(OnDBID, _("dB"));
-         menu->Enable(mDB? OnDBID: OnLinearID, false);
-         //menu->AppendSeparator();
-         //menu->Append(OnClipID, _("Turn on clipping"));
-         //menu->AppendSeparator();
-         //menu->Append(OnFloatID, _("Float Window"));
+      menu->Append(OnHorizontalID, _("Horizontal Stereo"));
+      menu->Append(OnVerticalID, _("Vertical Stereo"));
+      //menu->Append(OnMultiID, _("Vertical Multichannel"));
+      //menu->Append(OnEqualizerID, _("Equalizer"));
+      //menu->Append(OnWaveformID, _("Waveform"));
+      //menu->Enable(OnHorizontalID + mStyle, false);
+      menu->Enable(mStyle==VerticalStereo? OnVerticalID: OnHorizontalID, 
false);
+      menu->AppendSeparator();
 
-         menu->AppendSeparator();
-         menu->Append(OnPreferencesID, _("Preferences..."));
+      menu->Append(OnLinearID, _("Linear"));
+      menu->Append(OnDBID, _("dB"));
+      menu->Enable(mDB? OnDBID: OnLinearID, false);
+      //menu->AppendSeparator();
+      //menu->Append(OnClipID, _("Turn on clipping"));
+      //menu->AppendSeparator();
+      //menu->Append(OnFloatID, _("Float Window"));
 
+      menu->AppendSeparator();
+      menu->Append(OnPreferencesID, _("Preferences..."));
 
-         if (evt.RightDown())
-            PopupMenu(menu, evt.m_x, evt.m_y);
-         #if WANT_METER_MENU
-            else
-               PopupMenu(menu, mMenuRect.x + 1, mMenuRect.y + mMenuRect.height 
+ 1);
-         #endif // WANT_METER_MENU
-         delete menu;
-      }       
-      else 
-   #endif // WANT_METER_MENU
 
-   if (evt.ButtonDown()) {
+      if (evt.RightDown())
+         PopupMenu(menu, evt.m_x, evt.m_y);
+      else
+         PopupMenu(menu, mMenuRect.x + 1, mMenuRect.y + mMenuRect.height + 1);
+      delete menu;
+   }
+   else if (evt.ButtonDown()) {
       if (mIsInput)
          StartMonitoring();
    }
@@ -433,6 +434,9 @@
 
 void Meter::SetStyle(Meter::Style newStyle)
 {
+   // MixerTrackCluster disallows style change.
+   if (mStyle == MixerTrackCluster)
+      return;
    mStyle = newStyle;
    mLayoutValid = false;
    Refresh(true);
@@ -547,6 +551,56 @@
    mQueue.Put(msg);
 }
 
+void Meter::UpdateDisplay(int numChannels, int numFrames, 
+                           // Need to make these double-indexed arrays if we 
handle more than 2 channels.
+                           float* maxLeft, float* rmsLeft, 
+                           float* maxRight, float* rmsRight)
+{
+   int i, j;
+   int num = intmin(numChannels, mNumBars);
+   MeterUpdateMsg msg;
+
+   msg.numFrames = numFrames;
+   for(j=0; j<mNumBars; j++) {
+      msg.peak[j] = 0.0;
+      msg.rms[j] = 0.0;
+      msg.clipping[j] = false;
+      msg.headPeakCount[j] = 0;
+      msg.tailPeakCount[j] = 0;
+   }
+
+   for(i=0; i<numFrames; i++) {
+      for(j=0; j<num; j++) {
+         msg.peak[j] = floatMax(msg.peak[j], ((j == 0) ? maxLeft[i] : 
maxRight[i]));
+         msg.rms[j] = floatMax(msg.rms[j], ((j == 0) ? rmsLeft[i] : 
rmsRight[i]));
+
+         // In addition to looking for mNumPeakSamplesToClip peaked
+         // samples in a row, also send the number of peaked samples
+         // at the head and tail, in case there's a run 
+         // of peaked samples that crosses block boundaries.
+         if (fabs((j == 0) ? maxLeft[i] : maxRight[i]) >= 1.0)
+         {
+            if (msg.headPeakCount[j]==i)
+               msg.headPeakCount[j]++;
+            msg.tailPeakCount[j]++;
+            if (msg.tailPeakCount[j] > mNumPeakSamplesToClip)
+               msg.clipping[j] = true;
+         }
+         else
+            msg.tailPeakCount[j] = 0;
+      }
+   }
+
+   if (mDB) {
+      for(j=0; j<mNumBars; j++) {
+         msg.peak[j] = ToDB(msg.peak[j], mDBRange);
+         msg.rms[j] = ToDB(msg.rms[j], mDBRange);
+      }
+   }
+
+   mQueue.Put(msg);
+}
+
 void Meter::OnMeterUpdate(wxTimerEvent &evt)
 {
    MeterUpdateMsg msg;
@@ -562,6 +616,7 @@
       double deltaT = msg.numFrames / mRate;
       int j;
       
+      // <Why is this in the loop, rather than top of the method?>
       if (mMeterDisabled)
          return;
       //wxLogDebug(wxT("Pop: %s"), msg.toString().c_str());
@@ -645,10 +700,17 @@
 
 void Meter::HandleLayout()
 {
-   int iconWidth = mIcon->GetWidth();
-   int iconHeight = mIcon->GetHeight();
-   int menuWidth = 17;
-   int menuHeight = 14;
+   int iconWidth = 0;
+   int iconHeight = 0;
+   int menuWidth = 0;
+   int menuHeight = 0;
+   if (mStyle != MixerTrackCluster)
+   {
+      iconWidth = mIcon->GetWidth();
+      iconHeight = mIcon->GetHeight();
+      menuWidth = 17;
+      menuHeight = 11;
+   }
    int width = mWidth;
    int height = mHeight;
    int left = 0, top = 0;
@@ -664,20 +726,25 @@
       wxPrintf(wxT("Style not handled yet!\n"));
       break;
    case VerticalStereo:
-      #if WANT_METER_MENU
-         mMenuRect = wxRect(mWidth - menuWidth - 5, mHeight - menuHeight - 2,
-                            menuWidth, menuHeight);
-         if (mHeight < (menuHeight + iconHeight + 8))
-            mIconPos = wxPoint(-999, -999); // Don't display
-         else
-      #endif // WANT_METER_MENU
-            mIconPos = wxPoint(mWidth - iconWidth - 1, 1);
+      mMenuRect = wxRect(mWidth - menuWidth - 5, mHeight - menuHeight - 2,
+                         menuWidth, menuHeight);
+      if (mHeight < (menuHeight + iconHeight + 8))
+         mIconPos = wxPoint(-999, -999); // Don't display
+      else
+         mIconPos = wxPoint(mWidth - iconWidth - 1, 1);
       width = intmin(mWidth-(iconWidth+2), mWidth-(menuWidth+3));
+   case MixerTrackCluster:
+      // Doesn't show menu, icon, or L/R labels,
+      // but otherwise like VerticalStereo.
+
       if (width >= mLeftSize.x + mRightSize.x + 24) {
-         mLeftTextPos = wxPoint(2, height-2-mLeftSize.y);
+         if (mStyle != MixerTrackCluster)
+         {
+            mLeftTextPos = wxPoint(2, height-2-mLeftSize.y);
+            left += mLeftSize.x+4;
+         }
          mRightTextPos = wxPoint(width-mLeftSize.x, height-2-mLeftSize.y);
-         left += mLeftSize.x+4;
-         width -= mLeftSize.x + mRightSize.x + 8;
+         width -= mLeftSize.x + mRightSize.x + 8; //vvvvv ...but then -8 in 
UmixIt? -- for vertical only?
       }
       barw = (width-2)/2;
       barh = height - 4;
@@ -713,24 +780,19 @@
          mRuler.SetRange(1, 0);
          mRuler.SetFormat(Ruler::RealFormat);
       }
-      #if WANT_METER_MENU
+      if (mStyle != MixerTrackCluster) // MixerTrackCluster style has no menu.
          mRuler.OfflimitsPixels(mMenuRect.y-mBar[1].r.y, mBar[1].r.height);
-      #endif // WANT_METER_MENU
       break;
    case HorizontalStereo:
       if (mWidth < menuWidth + iconWidth + 8) {
          mIconPos = wxPoint(-999, -999); // Don't display icon
-         #if WANT_METER_MENU
-            mMenuRect = wxRect(2, mHeight - menuHeight - 2,
-                               menuWidth, menuHeight);
-         #endif // WANT_METER_MENU
+         mMenuRect = wxRect(2, mHeight - menuHeight - 2,
+                            menuWidth, menuHeight);
       }         
       else {
          mIconPos = wxPoint(2, mHeight - iconHeight);
-         #if WANT_METER_MENU
-            mMenuRect = wxRect(iconWidth + 2, mHeight - menuHeight - 5,
-                               menuWidth, menuHeight);
-         #endif // WANT_METER_MENU
+         mMenuRect = wxRect(iconWidth + 2, mHeight - menuHeight - 5,
+                            menuWidth, menuHeight);
       }
       height = intmin(height-(menuHeight+3), height-iconHeight) - 2;
       left = 2 + intmax(mLeftSize.x, mRightSize.x);
@@ -771,9 +833,7 @@
          mRuler.SetRange(0, 1);
          mRuler.SetFormat(Ruler::RealFormat);
       }
-      #if WANT_METER_MENU
-         mRuler.OfflimitsPixels(0, mMenuRect.x+mMenuRect.width-4);
-      #endif // WANT_METER_MENU
+      mRuler.OfflimitsPixels(0, mMenuRect.x+mMenuRect.width-4);
       break;
    case Waveform:
       mNumBars = 0;
@@ -801,7 +861,9 @@
       mAllBarsRect = wxRect(left, top, right-left+1, bottom-top+1);
    }
 
-   CreateIcon(mIconPos.y % 4);
+   // MixerTrackCluster style has no popup, so disallows SetStyle, so never 
needs icon.
+   //vvvvv There's an ASSERT failure if this:  if (mStyle != MixerTrackCluster)
+      CreateIcon(mIconPos.y % 4);
 
    mLayoutValid = true;
 }
@@ -811,9 +873,21 @@
    int i;
 
    dc.SetFont(GetFont());
-   if (mLeftSize.x == 0) {
-      dc.GetTextExtent(mLeftText, &mLeftSize.x, &mLeftSize.y);
-      dc.GetTextExtent(mRightText, &mRightSize.x, &mRightSize.y);
+   if (mLeftSize.x == 0) { // Not yet initialized to dc.
+      if (mStyle != MixerTrackCluster) // MixerTrackCluster style has no L/R 
labels.
+      {
+         dc.GetTextExtent(mLeftText, &mLeftSize.x, &mLeftSize.y);
+         dc.GetTextExtent(mRightText, &mRightSize.x, &mRightSize.y);
+      }
+      if ((mStyle == VerticalStereo) || (mStyle == MixerTrackCluster)) // 
VerticalMulti?
+      {
+         // For any vertical style, also need mRightSize big enough for Ruler 
width.
+         int rulerWidth;
+         int rulerHeight;
+         dc.GetTextExtent(wxT("-88"), &rulerWidth, &rulerHeight); // -88 is 
nice and wide.
+         if (mRightSize.x < rulerWidth)
+            mRightSize.x = rulerWidth;
+      }
    }
 
    if (!mLayoutValid)
@@ -832,42 +906,36 @@
    dc.DrawRectangle(0, 0, mWidth, mHeight);
 #endif
 
-   dc.DrawBitmap(*mIcon, mIconPos.x, mIconPos.y, true);
+   // MixerTrackCluster style has no icon or menu.
+   if (mStyle != MixerTrackCluster)
+   {
+      dc.DrawBitmap(*mIcon, mIconPos.x, mIconPos.y, true);
 
-   #if WANT_METER_MENU
       // Draws a beveled button and a down pointing triangle.
       // The style and sizing matches the ones in the title 
       // bar of the waveform left-hand-side panels.
-      {
-         wxRect r = mMenuRect;
-         AColor::Bevel(dc, true, r);
-         dc.SetBrush(*wxBLACK_BRUSH);
-         dc.SetPen(*wxBLACK_PEN);
-         AColor::Arrow(dc,
-                       r.x + 3,
-                       r.y + 5,
-                       10);
-      }
 
-      if (mNumBars>0)
-         mRuler.Draw(dc);
-   #else
-      // Label as "Mix Volume" and "Input Volume" for Camp Jam. 
-      int nFontSize = this->GetFont().GetPointSize();
-      int nXPos = mIconPos.x + mIcon->GetWidth() + 8;
-      int nYPos = mIconPos.y + (mIcon->GetHeight() - nFontSize - 6)/2;
-      if (nYPos < 0)
-         nYPos = 0;
-      if (mIsInput)
-         dc.DrawText(_("Input Volume"), nXPos, nYPos);
-      else
-         dc.DrawText(_("Mix Volume"), nXPos, nYPos);
-   #endif // WANT_METER_MENU
-   
-   dc.SetFont(GetFont());
-   dc.DrawText(mLeftText, mLeftTextPos.x, mLeftTextPos.y);
-   dc.DrawText(mRightText, mRightTextPos.x, mRightTextPos.y);
+      wxRect r = mMenuRect;
+      AColor::Bevel(dc, true, r);
+      dc.SetBrush(*wxBLACK_BRUSH);
+      dc.SetPen(*wxBLACK_PEN);
+      AColor::Arrow(dc,
+                    r.x + 3,
+                    r.y + 5,
+                    10);
+   }
+
+   if (mNumBars>0)
+      mRuler.Draw(dc);
    
+   // MixerTrackCluster style has no L/R labels.
+   if (mStyle != MixerTrackCluster)
+   {
+      dc.SetFont(GetFont());
+      dc.DrawText(mLeftText, mLeftTextPos.x, mLeftTextPos.y);
+      dc.DrawText(mRightText, mRightTextPos.x, mRightTextPos.y);
+   }
+
    for(i=0; i<mNumBars; i++)
       DrawMeterBar(dc, &mBar[i]);
 }
@@ -998,12 +1066,10 @@
    if (gAudioIO->IsMonitoring())
       gAudioIO->StopStream();
    else {
-      #if WANT_METER_MENU
-         if (mMeterDisabled){
-            wxCommandEvent dummy;
-            OnDisableMeter(dummy);
-         }
-      #endif
+      if (mMeterDisabled){
+         wxCommandEvent dummy;
+         OnDisableMeter(dummy);
+      }
 
       AudacityProject *p = GetActiveProject();
       if (p) {
@@ -1020,7 +1086,6 @@
 
 }
 
-#if WANT_METER_MENU
 //
 // Pop-up menu handlers
 //
@@ -1157,8 +1222,6 @@
    mTimer.Start(1000 / mMeterRefreshRate);
 }
 
-#endif // WANT_METER_MENU
-
 // Indentation settings for Vim and Emacs.
 // Please do not modify past this point.
 //


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Audacity-cvs mailing list
Audacity-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to