Fix crash
[ryzomcore.git] / nel / tools / sound / source_sounds_builder / SoundPage.cpp
blob0ad410098a59f64e9ac8f45ecedff98f56a045e9
1 // SoundPage.cpp : implementation file
2 //
4 #include "stdafx.h"
5 #include "source_sounds_builder.h"
6 #include "source_sounds_builderDlg.h"
7 #include "SoundPage.h"
9 #include "../src/sound/driver/buffer.h"
10 #include "../src/sound/audio_mixer_user.h"
12 #include "nel/sound/u_listener.h"
14 #include <nel/misc/common.h>
15 #include <nel/misc/vector.h>
16 using namespace NLMISC;
18 #include <math.h>
20 using namespace std;
23 #ifdef _DEBUG
24 #define new DEBUG_NEW
25 #undef THIS_FILE
26 static char THIS_FILE[] = __FILE__;
27 #endif
30 #define CONE_X 340
31 #define CONE_Y 280
32 #define CONE_R 30
35 uint XCenter;
36 uint YCenter;
37 uint Radius;
40 const char *PriorityStr [NbSoundPriorities] = { "Highest", "High", "Medium", "Low" };
43 //----------------------------------------------------------
44 // Name: ConvertLinearSliderPosToLogScale()
45 // Desc: Converts a linear slider position to a quasi logrithmic scale
46 //-----------------------------------------------------------------------------
47 float ConvertLinearSliderPosToLogScale( LONG lSliderPos )
49 if( lSliderPos > 0 && lSliderPos <= 10 )
51 return lSliderPos*0.01f;
53 else if( lSliderPos > 10 && lSliderPos <= 20 )
55 return (lSliderPos-10)*0.1f;
57 else if( lSliderPos > 20 && lSliderPos <= 30 )
59 return (lSliderPos-20)*1.0f;
61 else if( lSliderPos > 30 && lSliderPos <= 40 )
63 return (lSliderPos-30)*10.0f;
66 return 0.0f;
72 //-----------------------------------------------------------------------------
73 // Name: ConvertLinearSliderPosToLogScale()
74 // Desc: Converts a quasi logrithmic scale to a slider position
75 //-----------------------------------------------------------------------------
76 LONG ConvertLogScaleToLinearSliderPosTo( FLOAT fValue )
78 if( fValue > 0.0f && fValue <= 0.1f )
80 return (LONG)(fValue/0.01f);
82 else if( fValue > 0.1f && fValue <= 1.0f )
84 return (LONG)(fValue/0.1f) + 10;
86 else if( fValue > 1.0f && fValue <= 10.0f )
88 return (LONG)(fValue/1.0f) + 20;
90 else if( fValue > 10.0f && fValue <= 100.0f )
92 return (LONG)(fValue/10.0f) + 30;
95 return 0;
100 /////////////////////////////////////////////////////////////////////////////
101 // CSoundPage dialog
104 CSoundPage::CSoundPage(CWnd* pParent /*=NULL*/)
105 : CDialog(CSoundPage::IDD, pParent)
107 //{{AFX_DATA_INIT(CSoundPage)
108 m_Filename = _T("");
109 m_Gain = 1.0f;
110 m_Pos3D = FALSE;
111 m_MinDist = 1.0f;
112 m_MaxDist = 1000000.0f;
113 m_InnerAngleDeg = 360;
114 m_OuterAngleDeg = 360;
115 m_OuterGain = 1.0f;
116 m_Looped = FALSE;
117 m_Stereo = _T("");
118 m_Pitch = 1.0f;
119 m_Looping = false;
120 m_SoundName = _T("");
121 //}}AFX_DATA_INIT
123 _CurrentSound = NULL;
124 _Tree = NULL;
125 _Source = NULL;
132 BOOL CSoundPage::OnInitDialog()
134 CDialog::OnInitDialog();
136 // Load driver
137 CWaitCursor waitcursor;
138 _AudioMixer = UAudioMixer::createAudioMixer();
141 _AudioMixer->init();
142 //_AudioMixer->getListener()->setPos( CVector(0.0f,0.0001f,0.0f) );
144 catch( Exception& e )
146 CString s;
147 s.Format( "No sound driver: %s\n\nSound playback will be unavailable" , e.what() );
148 AfxMessageBox( s );
149 _AudioMixer = NULL;
152 // Fill priorities
153 uint i;
154 for ( i=0; i!=NbSoundPriorities; ++i )
156 m_Priority.AddString( PriorityStr[i] );
159 // We want to load nss files even if the corresponding waves are missing
160 CSound::allowMissingWave( true );
162 // Cone drawing: make it work with normal and big fonts (depending on system settings)
163 CRect parentrect, sliderrect;
164 this->GetWindowRect( &parentrect );
165 GetDlgItem( IDC_SliderOuterAngle )->GetWindowRect( &sliderrect );
166 XCenter = sliderrect.right - parentrect.left + 15 + CONE_R;
167 YCenter = sliderrect.top - parentrect.top + 10;
168 Radius = CONE_R;
170 waitcursor.Restore();
172 _NameFont = new CFont();
173 LOGFONT logfont;
174 GetFont()->GetLogFont( &logfont );
175 logfont.lfWeight = FW_BOLD;
176 _NameFont->CreateFontIndirect( &logfont );
178 GetDlgItem( IDC_SoundName )->SetFont( _NameFont );
180 ((CSliderCtrl*)GetDlgItem( IDC_SliderGain ))->SetRange( 0, 40 );
181 ((CSliderCtrl*)GetDlgItem( IDC_SliderPitch ))->SetRange( 0, 40 );
182 ((CSliderCtrl*)GetDlgItem( IDC_SliderMinDist ))->SetRange( 0, 1000 );
183 ((CSliderCtrl*)GetDlgItem( IDC_SliderMaxDist ))->SetRange( 0, 1000 );
184 ((CSliderCtrl*)GetDlgItem( IDC_SliderInnerAngle ))->SetRange( 0, 360 );
185 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterAngle ))->SetRange( 0, 360 );
186 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterGain ))->SetRange( 0, 40 );
188 return TRUE; // return TRUE unless you set the focus to a control
189 // EXCEPTION: OCX Property Pages should return FALSE
193 void CSoundPage::DoDataExchange(CDataExchange* pDX)
195 CDialog::DoDataExchange(pDX);
196 //{{AFX_DATA_MAP(CSoundPage)
197 DDX_Control(pDX, IDC_CbPriority, m_Priority);
198 DDX_Text(pDX, IDC_EditFilename, m_Filename);
199 DDX_Text(pDX, IDC_EditGain, m_Gain);
200 DDV_MinMaxFloat(pDX, m_Gain, 0.f, 1.f);
201 DDX_Check(pDX, IDC_Pos3D, m_Pos3D);
202 DDX_Text(pDX, IDC_EditMinDist, m_MinDist);
203 DDV_MinMaxFloat(pDX, m_MinDist, 0.f, 1.e+006f);
204 DDX_Text(pDX, IDC_EditMaxDist, m_MaxDist);
205 DDV_MinMaxFloat(pDX, m_MaxDist, 0.f, 1.e+006f);
206 DDX_Text(pDX, IDC_EditInnerAngle, m_InnerAngleDeg);
207 DDV_MinMaxUInt(pDX, m_InnerAngleDeg, 0, 360);
208 DDX_Text(pDX, IDC_EditOuterAngle, m_OuterAngleDeg);
209 DDV_MinMaxUInt(pDX, m_OuterAngleDeg, 0, 360);
210 DDX_Text(pDX, IDC_EditOuterGain, m_OuterGain);
211 DDV_MinMaxFloat(pDX, m_OuterGain, 0.f, 1.f);
212 DDX_Check(pDX, IDC_Looped, m_Looped);
213 DDX_Text(pDX, IDC_Stereo, m_Stereo);
214 DDX_Text(pDX, IDC_EditPitch, m_Pitch);
215 DDV_MinMaxFloat(pDX, m_Pitch, 1.e-011f, 1.f);
216 DDX_Check(pDX, IDC_Looping, m_Looping);
217 DDX_Text(pDX, IDC_SoundName, m_SoundName);
218 //}}AFX_DATA_MAP
222 BEGIN_MESSAGE_MAP(CSoundPage, CDialog)
223 //{{AFX_MSG_MAP(CSoundPage)
224 ON_BN_CLICKED(IDC_Pos3D, OnPos3D)
225 ON_BN_CLICKED(IDC_ChooseFile, OnChooseFile)
226 ON_BN_CLICKED(IDC_Remove, OnRemove)
227 ON_BN_CLICKED(IDC_PlaySound, OnPlaySound)
228 ON_WM_CLOSE()
229 ON_BN_CLICKED(IDC_Looped, OnLooped)
230 ON_EN_CHANGE(IDC_EditInnerAngle, OnChangeEditInnerAngle)
231 ON_EN_CHANGE(IDC_EditOuterAngle, OnChangeEditOuterAngle)
232 ON_WM_PAINT()
233 ON_EN_CHANGE(IDC_EditOuterGain, OnChangeEditOuterGain)
234 ON_WM_HSCROLL()
235 ON_EN_CHANGE(IDC_EditMinDist, OnChangeEditMinDist)
236 ON_EN_CHANGE(IDC_EditMaxDist, OnChangeEditMaxDist)
237 ON_BN_CLICKED(IDC_ButtonHelp, OnButtonHelp)
238 ON_EN_CHANGE(IDC_EditGain, OnChangeEditGain)
239 ON_BN_CLICKED(IDC_ButtonTestOuterGain, OnButtonTestOuterGain)
240 ON_EN_CHANGE(IDC_EditPitch, OnChangeEditPitch)
241 ON_BN_CLICKED(IDC_Cancel, OnCancel)
242 ON_BN_CLICKED(IDC_Home, OnHome)
243 //}}AFX_MSG_MAP
244 END_MESSAGE_MAP()
250 const char *StereoToCStr( CSound* snd, bool *st )
252 static const char empty [] = "";
253 static const char mono [] = "Mono";
254 static const char stereo [] = "Stereo";
255 if ( snd->getBuffer() == NULL )
257 *st = false;
258 return empty;
260 else
262 if ( snd->getBuffer()->isStereo() )
264 *st = true;
265 return stereo;
267 else
269 *st = false;
270 return mono;
279 void CSoundPage::UpdateStereo()
281 bool stereo;
282 m_Stereo = StereoToCStr( _CurrentSound, &stereo );
283 if ( stereo )
285 m_Pos3D = false;
287 GetDlgItem( IDC_Pos3D )->EnableWindow( ! stereo );
294 void CSoundPage::getPropertiesFromSound()
296 m_SoundName = _CurrentSound->getName().c_str();
297 m_Filename = _CurrentSound->getFilename().c_str();
298 m_Gain = _CurrentSound->getGain();
299 m_Pitch = _CurrentSound->getPitch();
300 m_Priority.SetCurSel( _CurrentSound->getPriority() );
301 m_Looping = _CurrentSound->getLooping();
302 m_Pos3D = _CurrentSound->isDetailed();
303 ((CSliderCtrl*)GetDlgItem( IDC_SliderGain ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_Gain*100.0f ) );
304 ((CSliderCtrl*)GetDlgItem( IDC_SliderPitch ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_Pitch*100.0f ) );
305 UpdateStereo();
307 if ( m_Pos3D )
309 m_MinDist = _CurrentSound->getMinDistance();
310 m_MaxDist = _CurrentSound->getMaxDistance();
311 m_InnerAngleDeg = (uint)radToDeg( _CurrentSound->getConeInnerAngle() );
312 m_OuterAngleDeg = (uint)radToDeg( _CurrentSound->getConeOuterAngle() );
313 m_OuterGain = _CurrentSound->getConeOuterGain();
315 ((CSliderCtrl*)GetDlgItem( IDC_SliderMinDist ))->SetPos( (int)m_MinDist );
316 ((CSliderCtrl*)GetDlgItem( IDC_SliderMaxDist ))->SetPos( (int)m_MaxDist );
317 ((CSliderCtrl*)GetDlgItem( IDC_SliderInnerAngle ))->SetPos( m_InnerAngleDeg );
318 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterAngle ))->SetPos( m_OuterAngleDeg );
319 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterGain ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_OuterGain*100.0f ) );
320 UpdateData( false );
322 Invalidate();
323 OnPos3D(); // enable/disable 3d properties
330 void CSoundPage::UpdateCurrentSound()
332 CString name = ((CSource_sounds_builderDlg*)GetOwner())->SoundName( _HItem );
333 if ( ! m_Pos3D )
335 _CurrentSound->setProperties( string(name), string(m_Filename), m_Gain, m_Pitch, (TSoundPriority)(m_Priority.GetCurSel()), m_Looping!=0, m_Pos3D!=0 );
337 else
339 _CurrentSound->setProperties( string(name), string(m_Filename), m_Gain, m_Pitch, (TSoundPriority)(m_Priority.GetCurSel()), m_Looping!=0, m_Pos3D!=0,
340 m_MinDist, m_MaxDist, degToRad((float)m_InnerAngleDeg), degToRad((float)m_OuterAngleDeg), m_OuterGain );
342 // Argument checking is already done by the dialog wizard
348 /////////////////////////////////////////////////////////////////////////////
349 // CSoundPage message handlers
355 void CSoundPage::setCurrentSound( CSound *sound, HTREEITEM hitem )
357 _CurrentSound = sound;
358 _HItem = hitem;
359 if ( _Source != NULL )
361 _Source->stop();
363 m_Looped = false;
364 UpdateData( false );
371 void CSoundPage::OnPos3D()
373 UpdateData( true );
374 GetDlgItem( IDC_Pos3DGroup )->EnableWindow( m_Pos3D );
375 GetDlgItem( IDC_MinDist )->EnableWindow( m_Pos3D );
376 GetDlgItem( IDC_MaxDist )->EnableWindow( m_Pos3D );
377 GetDlgItem( IDC_ConeInnerAngle )->EnableWindow( m_Pos3D );
378 GetDlgItem( IDC_ConeOuterAngle )->EnableWindow( m_Pos3D );
379 GetDlgItem( IDC_ConeOuterGain )->EnableWindow( m_Pos3D );
380 GetDlgItem( IDC_EditMinDist )->EnableWindow( m_Pos3D );
381 GetDlgItem( IDC_EditMaxDist )->EnableWindow( m_Pos3D );
382 GetDlgItem( IDC_EditInnerAngle )->EnableWindow( m_Pos3D );
383 GetDlgItem( IDC_EditOuterAngle )->EnableWindow( m_Pos3D );
384 GetDlgItem( IDC_EditOuterGain )->EnableWindow( m_Pos3D );
385 GetDlgItem( IDC_SliderMinDist )->EnableWindow( m_Pos3D );
386 GetDlgItem( IDC_SliderMaxDist )->EnableWindow( m_Pos3D );
387 GetDlgItem( IDC_SliderInnerAngle )->EnableWindow( m_Pos3D );
388 GetDlgItem( IDC_SliderOuterAngle )->EnableWindow( m_Pos3D );
389 GetDlgItem( IDC_SliderOuterGain )->EnableWindow( m_Pos3D );
390 GetDlgItem( IDC_ButtonTestOuterGain )->EnableWindow( m_Pos3D );
392 DrawCones();
399 void CSoundPage::apply()
401 if ( _CurrentSound )
403 if ( _Source != NULL )
405 _Source->stop();
408 UpdateData( true );
410 UpdateCurrentSound();
412 //(static_cast<CSource_sounds_builderDlg*>(GetOwner()))->setModified();
414 nlassert( _Tree );
416 if ( !m_Filename.empty() )
418 CString s = ((CSource_sounds_builderDlg*)GetOwner())->SoundName( _HItem ) + " (" + m_Filename + ")";
419 _Tree->SetItemText( _HItem, s );
422 //_Tree->SelectItem( NULL );
424 GetOwner()->SetFocus();
432 void CSoundPage::rename( CString s )
434 // Quick way to do it (should be simplified)
436 getPropertiesFromSound();
437 nlassert( _Tree );
438 _Tree->SetItemText( _HItem, s );
439 UpdateCurrentSound();
441 m_SoundName = s;
442 UpdateData( false );
447 * Reverts the changes
449 void CSoundPage::OnCancel()
451 getPropertiesFromSound();
456 * Unselects the current sound
458 void CSoundPage::cancel()
460 if ( _Source != NULL )
462 _Source->stop();
465 _CurrentSound = NULL;
472 void CSoundPage::OnHome()
474 nlassert( _Tree );
475 _Tree->SelectItem( _Tree->GetRootItem() );
476 GetOwner()->SetFocus();
483 void CSoundPage::OnChooseFile()
485 // Prompt filename
486 CFileDialog opendlg( true, "wav", "", OFN_OVERWRITEPROMPT, "PCM Wave files (*.wav)|*.wav||", this );
487 if ( opendlg.DoModal()==IDOK )
489 UpdateData( true );
490 m_Filename = opendlg.GetFileName();
491 try
493 loadSound();
495 catch ( Exception& e )
497 CString s;
498 s.Format( "%s", e.what() );
499 AfxMessageBox( s );
501 UpdateData( false );
509 bool CSoundPage::loadSound()
511 UpdateCurrentSound();
512 nlassert( _CurrentSound );
513 if ( (m_Filename != "") && (_AudioMixer != NULL) )
515 _CurrentSound->loadBuffer( string(m_Filename) );
516 UpdateStereo();
517 return true;
519 else
521 return false;
529 void CSoundPage::OnRemove()
531 removeSound();
538 void CSoundPage::removeSound()
540 /*if ( AfxMessageBox( "Are you sure to remove the current sound from the list ?", MB_YESNO | MB_ICONQUESTION ) == IDYES )
542 if ( _CurrentSound )
544 nlassert( _Tree );
545 _Tree->DeleteItem( _HItem );
547 /*}*/
554 void CSoundPage::Play( bool outsidecone )
556 CWaitCursor waitcursor;
558 // Load sound
559 try
561 if ( loadSound() )
563 UpdateData( false );
565 // Play source
566 if ( _Source == NULL )
568 _Source = _AudioMixer->createSource( _CurrentSound );
570 else
572 _Source->stop();
573 _Source->setSound( _CurrentSound );
575 _Source->setLooping( m_Looped!=0 );
576 if ( outsidecone )
578 // The listener is just behind the source
579 _Source->setPos( CVector(0.0f,0.1f,0.0f) );
580 _Source->setDirection( CVector(0.0f,1.0f,0.0f) ); // directional
582 else
584 // The listener is at the source pos
585 _Source->setPos( CVector(0.0f,0.0f,0.0f) );
586 _Source->setDirection( CVector(0.0f,0.0f,0.0f) ); // non-directional
588 _Source->play();
591 waitcursor.Restore();
593 catch ( Exception& e )
595 waitcursor.Restore();
597 CString s;
598 s.Format( "%s", e.what() );
599 AfxMessageBox( s );
607 void CSoundPage::OnPlaySound()
609 UpdateData( true );
610 m_Looped = false;
611 Play( false );
618 void CSoundPage::OnLooped()
620 UpdateData( true );
621 if ( m_Looped )
623 Play( false );
625 else
627 if ( _Source != NULL )
629 _Source->stop();
638 void CSoundPage::OnButtonTestOuterGain()
640 UpdateData( true );
641 m_Looped = false;
642 Play( true );
649 void CSoundPage::OnClose()
651 if ( _AudioMixer != NULL )
653 if ( _Source != NULL )
655 delete _Source;
657 delete _AudioMixer;
665 void CSoundPage::DrawCones()
667 if ( m_InnerAngleDeg > m_OuterAngleDeg )
669 GetDlgItem( IDC_BadCone )->SetWindowText( "Inner > Outer !" );
671 else
673 GetDlgItem( IDC_BadCone )->SetWindowText( "" );
676 CRect rect( XCenter-Radius, YCenter-Radius, XCenter+Radius+1, YCenter+Radius+1 );
677 InvalidateRect( &rect, true );
684 void CSoundPage::OnChangeEditGain()
686 UpdateData( true );
687 ((CSliderCtrl*)GetDlgItem( IDC_SliderGain ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_Gain*100.0f ) );
694 void CSoundPage::OnChangeEditPitch()
696 UpdateData( true );
697 ((CSliderCtrl*)GetDlgItem( IDC_SliderPitch ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_Pitch*100.0f ) );
704 void CSoundPage::OnChangeEditMinDist()
706 UpdateData( true );
707 ((CSliderCtrl*)GetDlgItem( IDC_SliderMinDist ))->SetPos( (int)m_MinDist );
714 void CSoundPage::OnChangeEditMaxDist()
716 UpdateData( true );
717 ((CSliderCtrl*)GetDlgItem( IDC_SliderMaxDist ))->SetPos( (int)m_MaxDist );
724 void CSoundPage::OnChangeEditInnerAngle()
726 UpdateData( true );
727 ((CSliderCtrl*)GetDlgItem( IDC_SliderInnerAngle ))->SetPos( m_InnerAngleDeg );
728 DrawCones();
735 void CSoundPage::OnChangeEditOuterAngle()
737 UpdateData( true );
738 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterAngle ))->SetPos( m_OuterAngleDeg );
739 DrawCones();
746 void CSoundPage::OnChangeEditOuterGain()
748 UpdateData( true );
749 ((CSliderCtrl*)GetDlgItem( IDC_SliderOuterGain ))->SetPos( ConvertLogScaleToLinearSliderPosTo( m_OuterGain*100.0f) );
750 DrawCones();
757 void CSoundPage::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
759 CSliderCtrl *slider = (CSliderCtrl*)pScrollBar; // MFC sucks
761 nPos = slider->GetPos();
763 if ( slider == GetDlgItem( IDC_SliderGain ) )
765 m_Gain = ConvertLinearSliderPosToLogScale( nPos ) / 100.0f;
766 if ( _Source != NULL )
768 _Source->setGain( m_Gain );
771 else if ( slider == GetDlgItem( IDC_SliderPitch ) )
773 m_Pitch = ConvertLinearSliderPosToLogScale( nPos ) / 100.0f;
774 if ( _Source != NULL )
776 _Source->setPitch( m_Pitch );
779 else if ( slider == GetDlgItem( IDC_SliderMinDist ) )
781 m_MinDist = (float)nPos;
783 else if ( slider == GetDlgItem( IDC_SliderMaxDist ) )
785 m_MaxDist = (float)nPos;
787 else if ( slider == GetDlgItem( IDC_SliderInnerAngle ) )
789 m_InnerAngleDeg = nPos;
791 else if ( slider == GetDlgItem( IDC_SliderOuterAngle ) )
793 m_OuterAngleDeg = nPos;
795 else if ( slider == GetDlgItem( IDC_SliderOuterGain ) )
797 m_OuterGain = ConvertLinearSliderPosToLogScale( nPos ) / 100.0f;
799 UpdateData( false );
800 DrawCones();
808 void CSoundPage::OnPaint()
810 CPaintDC dc(this); // device context for painting
812 float innerangle = degToRad((float)m_InnerAngleDeg);
813 float outerangle = degToRad((float)m_OuterAngleDeg);
815 /*// Erase background (done by InvalidateRect())
816 CRect rect( XCenter-Radius, YCenter-Radius, XCenter+Radius+1, YCenter+Radius+1 );
817 CBrush brush;
818 brush.CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
819 dc.FillRect( &rect, &brush );*/
821 if ( m_Pos3D )
823 COLORREF innercolor = RGB(255,0,0);
824 uint8 c = (uint)(255.0f * (1.0f - (float)(ConvertLogScaleToLinearSliderPosTo( m_OuterGain*100.0f ))/40.0f )); // linear, not logarithmic
825 COLORREF outercolor = RGB(255,c,c);
826 COLORREF tcolor = RGB(255,c/1.5,c/1.5); // not progressive
827 if ( m_OuterGain == 0.0f ) // change white to background color
829 outercolor = GetSysColor( COLOR_BTNFACE );
832 uint dx = (uint)(Radius*sin(outerangle/2.0f));
833 uint y = YCenter-(uint)(Radius*cos(outerangle/2.0f));
835 // Outside
836 CPen outpen( PS_SOLID, 1, outercolor );
837 CBrush outbrush;
838 outbrush.CreateSolidBrush( outercolor );
839 dc.SelectObject( &outpen );
840 dc.SelectObject( &outbrush );
841 dc.Pie( XCenter-Radius, YCenter-Radius, XCenter+Radius+1, YCenter+Radius+1, XCenter-dx, y, XCenter+dx, y );
843 // Transition
844 if ( (dx != 0) || (outerangle > 3.14) )
846 CPen tpen( PS_SOLID, 1, tcolor );
847 CBrush tbrush;
848 tbrush.CreateSolidBrush( tcolor );
849 dc.SelectObject( &tpen );
850 dc.SelectObject( &tbrush );
851 dc.Pie( XCenter-Radius, YCenter-Radius, XCenter+Radius+1, YCenter+Radius+1, XCenter+dx, y, XCenter-dx, y );
854 dx = (uint)(Radius*sin(innerangle/2.0f));
855 y = YCenter-(uint)(Radius*cos(innerangle/2.0f));
857 // Inner
858 if ( (dx != 0) || (innerangle > 3.14) )
860 CPen inpen( PS_SOLID, 1, innercolor );
861 CBrush inbrush;
862 inbrush.CreateSolidBrush( innercolor );
863 dc.SelectObject( &inpen );
864 dc.SelectObject( &inbrush );
865 dc.Pie( XCenter-Radius, YCenter-Radius, XCenter+Radius+1, YCenter+Radius+1, XCenter+dx, y, XCenter-dx, y );
874 BOOL CSoundPage::DestroyWindow()
876 delete _NameFont;
878 return CDialog::DestroyWindow();
885 void CSoundPage::OnButtonHelp()
887 MessageBox( "\
888 Gain: Range: [0, 1]. A gain factor is logarithmic ; 1.0 means no attenuation (full volume) ; 0.5 \
889 means an attenuation of 6 dB ; 0 means silence.\n\n\
890 Pitch: Range: ]0, 1]. 1.0 means normal ; dividing by 2 means pitching one octave down. Pitching up \
891 is not supported. 0 is not a legal value.\n\n\
892 Min Dist: Distance threshold below which gain is clamped (does not increase anymore).\n\
893 Unit: meters. Range: 0 - 1000000 (the maximum value 1e+006 is considered as infinite).\n\n\
894 Max Dist: Distance threshold above which gain is clamped (does not decrease anymore).\n\
895 Unit: meters. Range: 0 - 1000000 m (the maximum value 1e+006 is considered as infinite).\n\n\
896 Cone Inner Angle: Inside angle of the sound cone where the main gain is applied. \
897 The default of 360 means that the inner angle covers the entire world, which is equivalent to \
898 an omnidirectional source.\n\
899 Unit: degrees. Range: 0 - 360.\n\n\
900 Cone Outer Angle: Outer angle of the sound cone where the outer gain is applied \
901 to the main gain. The default of 360 means that the outer angle covers the entire world. If \
902 the inner angle is also 360, then there is no transition zone for angle-dependent (progressive) \
903 attenuation.\n\
904 Unit: degress. Range: 0 - 360.\n\n\
905 Cone Outer Gain: The factor with which the main gain is multiplied to determine the effective \
906 gain outside the cone defined by the outer angle. To test the outer gain, you can play the \
907 sound source as if you were outside the cone.\n\
908 Range: 0 - 1.\
909 ", "Help about types" );