]> git.saurik.com Git - wxWidgets.git/blame - contrib/samples/mmedia/mmboard.cpp
corrected #ifdefs testing wxUSE_UNICODE_MSLU
[wxWidgets.git] / contrib / samples / mmedia / mmboard.cpp
CommitLineData
e8482f24
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: mmboard.cpp
3// Purpose: Multimedia Library sample
4// Author: Guilhem Lavaux (created from minimal by J. Smart)
5// Modified by:
6// Created: 13/02/2000
7// RCS-ID: $Id$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19#ifdef __GNUG__
694f70fa 20 #pragma implementation "mmboard.h"
e8482f24
GL
21#endif
22
23// For compilers that support precompilation, includes "wx/wx.h".
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27 #pragma hdrstop
28#endif
29
30// for all others, include the necessary headers (this file is usually all you
be5a51fb 31// need because it includes almost all "standard" wxWidgets headers
e8482f24
GL
32#ifndef WX_PRECOMP
33 #include "wx/wx.h"
34#endif
35
36// ----------------------------------------------------------------------------
37// ressources
38// ----------------------------------------------------------------------------
39// the application icon
618f2efa 40#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
e8482f24
GL
41 #include "mondrian.xpm"
42#endif
43
44// include multimedia classes
45#include "wx/mmedia/sndbase.h"
46#ifdef __WIN32__
47 #include "wx/mmedia/sndwin.h"
48#endif
49#ifdef __UNIX__
50 #include "wx/mmedia/sndoss.h"
51 #include "wx/mmedia/sndesd.h"
52#endif
53
54#include "wx/statline.h"
55#include "wx/stattext.h"
56
57// include personnal classes
58#include "mmboard.h"
59#include "mmbman.h"
60
61#include "play.xpm"
62#include "stop.xpm"
63#include "eject.xpm"
64#include "pause.xpm"
65
66// ----------------------------------------------------------------------------
67// private classes
68// ----------------------------------------------------------------------------
69
70// Main Multimedia Board frame
71class MMBoardFrame : public wxFrame
72{
73public:
74 // ctor(s)
75 MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
76 // dtor
77 ~MMBoardFrame();
dabbc6a5 78
e8482f24
GL
79 // event handlers
80 void OnQuit(wxCommandEvent& event);
81 void OnAbout(wxCommandEvent& event);
82 void OnOpen(wxCommandEvent& event);
83 void OnPlay(wxCommandEvent& event);
84 void OnStop(wxCommandEvent& event);
85 void OnPause(wxCommandEvent& event);
86 void OnEject(wxCommandEvent& event);
87 void OnRefreshInfo(wxEvent& event);
88 void OnSetPosition(wxCommandEvent& event);
dabbc6a5 89
e8482f24
GL
90 void OpenVideoWindow();
91 void CloseVideoWindow();
dabbc6a5 92
e8482f24 93private:
be5a51fb 94 // any class wishing to process wxWidgets events must use this macro
e8482f24
GL
95 DECLARE_EVENT_TABLE()
96
97private:
dabbc6a5 98 void UpdateMMedInfo();
e8482f24 99 void UpdateInfoText();
dabbc6a5 100
e8482f24 101 MMBoardFile *m_opened_file;
dabbc6a5 102
e8482f24
GL
103 wxSlider *m_positionSlider;
104 wxBitmapButton *m_playButton, *m_pauseButton, *m_stopButton, *m_ejectButton;
105 wxStaticText *m_fileType, *m_infoText;
106 wxWindow *m_video_window;
dabbc6a5 107
e8482f24
GL
108 wxPanel *m_panel;
109 wxSizer *m_sizer;
dabbc6a5 110
e8482f24
GL
111 wxTimer *m_refreshTimer;
112};
113
114// ----------------------------------------------------------------------------
115// constants
116// ----------------------------------------------------------------------------
117
118// IDs for the controls and the menu commands
119enum
120{
121 // menu items
122 MMBoard_Quit = 1,
123 MMBoard_Open,
124 MMBoard_About,
125 MMBoard_PositionSlider,
126 MMBoard_PlayButton,
127 MMBoard_PauseButton,
128 MMBoard_ResumeButton,
129 MMBoard_StopButton,
130 MMBoard_EjectButton,
131 MMBoard_RefreshInfo
132};
133
134// ----------------------------------------------------------------------------
be5a51fb 135// event tables and other macros for wxWidgets
e8482f24
GL
136// ----------------------------------------------------------------------------
137
138BEGIN_EVENT_TABLE(MMBoardFrame, wxFrame)
139 EVT_MENU(MMBoard_Quit, MMBoardFrame::OnQuit)
140 EVT_MENU(MMBoard_About, MMBoardFrame::OnAbout)
141 EVT_MENU(MMBoard_Open, MMBoardFrame::OnOpen)
142 EVT_BUTTON(MMBoard_PlayButton, MMBoardFrame::OnPlay)
143 EVT_BUTTON(MMBoard_StopButton, MMBoardFrame::OnStop)
144 EVT_BUTTON(MMBoard_PauseButton, MMBoardFrame::OnPause)
dabbc6a5 145 EVT_BUTTON(MMBoard_EjectButton, MMBoardFrame::OnEject)
e8482f24
GL
146 EVT_SLIDER(MMBoard_PositionSlider, MMBoardFrame::OnSetPosition)
147 EVT_CUSTOM(wxEVT_TIMER, MMBoard_RefreshInfo, MMBoardFrame::OnRefreshInfo)
148END_EVENT_TABLE()
149
150// ---------------------------------------------------------------------------
151// Main board application launcher
152// ---------------------------------------------------------------------------
153
154IMPLEMENT_APP(MMBoardApp)
155
156// ============================================================================
157// implementation
158// ============================================================================
159
160// ----------------------------------------------------------------------------
161// the application class
162// ----------------------------------------------------------------------------
163
164bool MMBoardApp::OnInit()
165{
166 // create the main application window
2bbf230a 167 MMBoardFrame *frame = new MMBoardFrame(_T("Multimedia Board"),
e8482f24
GL
168 wxPoint(50, 50), wxSize(450, 340));
169
170 // and show it (the frames, unlike simple controls, are not shown when
171 // created initially)
dabbc6a5 172 frame->Show();
e8482f24
GL
173
174 m_caps = TestMultimediaCaps();
175
176 if (!m_caps) {
2bbf230a 177 wxMessageBox(_T("Your system has no multimedia capabilities. We are exiting now."), _T("Major error !"), wxOK | wxICON_ERROR, NULL);
dabbc6a5 178 return false;
e8482f24
GL
179 }
180
181 wxString msg;
2bbf230a 182 msg.Printf(_T("Detected : %s%s%s"), (m_caps & MM_SOUND_OSS) ? _T("OSS ") : _T(""),
dabbc6a5
DS
183 (m_caps & MM_SOUND_ESD) ? _T("ESD ") : _T(""),
184 (m_caps & MM_SOUND_WIN) ? _T("WIN") : _T(""));
e8482f24 185
2bbf230a 186 wxMessageBox(msg, _T("Good !"), wxOK | wxICON_INFORMATION, NULL);
e8482f24
GL
187
188 // success: wxApp::OnRun() will be called which will enter the main message
dabbc6a5 189 // loop and the application will run. If we returned false here, the
e8482f24 190 // application would exit immediately.
dabbc6a5 191 return true;
e8482f24
GL
192}
193
194wxUint8 MMBoardApp::TestMultimediaCaps()
195{
196 wxSoundStream *dev;
197 wxUint8 caps;
dabbc6a5 198
e8482f24 199 caps = 0;
dabbc6a5 200
69067986
MW
201#ifdef __WIN32__
202 // We test the Windows sound support.
203
204 dev = new wxSoundStreamWin();
205 if (dev->GetError() == wxSOUND_NOERROR)
206 caps |= MM_SOUND_WIN;
207 delete dev;
208
209#elif defined __UNIX__
e8482f24 210 // We now test the ESD support
dabbc6a5 211
e8482f24 212 dev = new wxSoundStreamESD();
dabbc6a5 213 if (dev->GetError() == wxSOUND_NOERROR)
e8482f24
GL
214 caps |= MM_SOUND_ESD;
215 delete dev;
dabbc6a5 216
e8482f24 217 // We test the OSS (Open Sound System) support.
c42b1de6
GL
218 // WARNING: There is a conflict between ESD and ALSA. We may be interrested
219 // in disabling the auto detection of OSS is ESD has been detected.
220#if 1
221 if (!(caps & MM_SOUND_ESD)) {
222#endif
223
e8482f24
GL
224 dev = new wxSoundStreamOSS();
225 if (dev->GetError() == wxSOUND_NOERROR)
226 caps |= MM_SOUND_OSS;
227 delete dev;
c42b1de6
GL
228#if 1
229 }
230#endif
231
e8482f24 232#endif
dabbc6a5 233
e8482f24
GL
234 return caps;
235}
236
237// ----------------------------------------------------------------------------
238// main frame
239// ----------------------------------------------------------------------------
240
241// frame constructor
242MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
dabbc6a5 243 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
e8482f24
GL
244{
245#ifdef __WXMAC__
246 // we need this in order to allow the about menu relocation, since ABOUT is
247 // not the default id of the about menu
248 wxApp::s_macAboutMenuItemId = MMBoard_About;
249#endif
250
251 // set the frame icon
252 SetIcon(wxICON(mondrian));
253
254 // create a menu bar
dabbc6a5 255 wxMenu *menuFile = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
e8482f24
GL
256
257 // the "About" item should be in the help menu
258 wxMenu *helpMenu = new wxMenu;
259 helpMenu->Append(MMBoard_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
260
261 menuFile->Append(MMBoard_Open, wxT("&Open\tAlt-O"), wxT("Open file"));
262 menuFile->AppendSeparator();
263 menuFile->Append(MMBoard_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
264
265 // now append the freshly created menu to the menu bar...
266 wxMenuBar *menuBar = new wxMenuBar();
267 menuBar->Append(menuFile, wxT("&File"));
268 menuBar->Append(helpMenu, wxT("&Help"));
269
270 // ... and attach this menu bar to the frame
271 SetMenuBar(menuBar);
272
273#if wxUSE_STATUSBAR
274 // create a status bar just for fun (by default with 1 pane only)
275 CreateStatusBar(3);
be5a51fb 276 SetStatusText(wxT("Welcome to wxWidgets!"));
e8482f24
GL
277#endif // wxUSE_STATUSBAR
278
279 // Misc variables
280 m_opened_file = NULL;
281
dabbc6a5 282 m_panel = new wxPanel(this, wxID_ANY);
e8482f24
GL
283
284 // Initialize main slider
285 m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
422d0ff0 286 wxDefaultPosition, wxSize(300, wxDefaultCoord),
dabbc6a5 287 wxSL_HORIZONTAL | wxSL_AUTOTICKS);
e8482f24 288 m_positionSlider->SetPageSize(60); // 60 secs
dabbc6a5
DS
289 m_positionSlider->Disable();
290
e8482f24 291 // Initialize info panel
dabbc6a5 292 wxPanel *infoPanel = new wxPanel( m_panel, wxID_ANY);
e8482f24
GL
293 infoPanel->SetBackgroundColour(*wxBLACK);
294 infoPanel->SetForegroundColour(*wxWHITE);
295
296 wxBoxSizer *infoSizer = new wxBoxSizer(wxVERTICAL);
297
dabbc6a5 298 m_fileType = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
e38c6b5f 299#if wxUSE_STATLINE
dabbc6a5 300 wxStaticLine *line = new wxStaticLine(infoPanel, wxID_ANY);
e38c6b5f 301#endif // wxUSE_STATLINE
dabbc6a5 302 m_infoText = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
e8482f24
GL
303
304 UpdateInfoText();
305
306 infoSizer->Add(m_fileType, 0, wxGROW | wxALL, 1);
e38c6b5f 307#if wxUSE_STATLINE
e8482f24 308 infoSizer->Add(line, 0, wxGROW | wxCENTRE, 20);
e38c6b5f 309#endif // wxUSE_STATLINE
e8482f24 310 infoSizer->Add(m_infoText, 0, wxGROW | wxALL, 1);
dabbc6a5 311
e8482f24 312 infoPanel->SetSizer(infoSizer);
e8482f24
GL
313
314 // Bitmap button panel
315 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
dabbc6a5 316
a977709b
JS
317 wxBitmap play_bmp(play_back_xpm);
318 wxBitmap stop_bmp(stop_back_xpm);
319 wxBitmap eject_bmp(eject_xpm);
320 wxBitmap pause_bmp(pause_xpm);
e8482f24 321
a977709b 322 m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, play_bmp);
dabbc6a5 323 m_playButton->Disable();
a977709b 324 m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, pause_bmp);
dabbc6a5 325 m_pauseButton->Disable();
a977709b 326 m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, stop_bmp);
dabbc6a5 327 m_stopButton->Disable();
a977709b 328 m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, eject_bmp);
dabbc6a5
DS
329 m_ejectButton->Disable();
330
e8482f24 331 buttonSizer->Add(m_playButton, 0, wxALL, 2);
dabbc6a5 332 buttonSizer->Add(m_pauseButton, 0, wxALL, 2);
e8482f24
GL
333 buttonSizer->Add(m_stopButton, 0, wxALL, 2);
334 buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
335
336 // Top sizer
337 m_sizer = new wxBoxSizer(wxVERTICAL);
e38c6b5f 338#if wxUSE_STATLINE
dabbc6a5 339 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 340#endif // wxUSE_STATLINE
e8482f24 341 m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
e38c6b5f 342#if wxUSE_STATLINE
dabbc6a5 343 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 344#endif // wxUSE_STATLINE
e8482f24 345 m_sizer->Add(buttonSizer, 0, wxALL, 0);
e38c6b5f 346#if wxUSE_STATLINE
dabbc6a5 347 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 348#endif // wxUSE_STATLINE
e8482f24 349 m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
dabbc6a5 350
e8482f24 351 m_panel->SetSizer(m_sizer);
e8482f24
GL
352 m_sizer->Fit(this);
353 m_sizer->SetSizeHints(this);
354
355 // Timer
356 m_refreshTimer = new wxTimer(this, MMBoard_RefreshInfo);
357
358 // Video window
359 m_video_window = NULL;
360
361 // Multimedia file
362 m_opened_file = NULL;
363}
364
365MMBoardFrame::~MMBoardFrame()
366{
367 if (m_opened_file)
368 delete m_opened_file;
dabbc6a5 369
e8482f24
GL
370 delete m_refreshTimer;
371}
372
373void MMBoardFrame::OpenVideoWindow()
374{
375 if (m_video_window)
376 return;
377
dabbc6a5 378 m_video_window = new wxWindow(m_panel, wxID_ANY, wxDefaultPosition, wxSize(200, 200));
e8482f24
GL
379 m_video_window->SetBackgroundColour(*wxBLACK);
380 m_sizer->Prepend(m_video_window, 2, wxGROW | wxSHRINK | wxCENTRE, 1);
381
382 m_sizer->Fit(this);
383}
384
385void MMBoardFrame::CloseVideoWindow()
386{
387 if (!m_video_window)
388 return;
12a3f227
RL
389
390 m_sizer->Detach( m_video_window );
e8482f24
GL
391 delete m_video_window;
392 m_video_window = NULL;
12a3f227 393
e8482f24
GL
394 m_sizer->Fit(this);
395}
396
397// event handlers
398
399void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
400{
dabbc6a5
DS
401 // true is to force the frame to close
402 Close(true);
e8482f24
GL
403}
404
405void MMBoardFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
406{
407 wxString msg;
be5a51fb
JS
408 msg.Printf( wxT("wxWidgets Multimedia board v1.0a, wxMMedia v2.0a:\n")
409 wxT("an example of the capabilities of the wxWidgets multimedia classes.\n")
dabbc6a5
DS
410 wxT("Copyright 1999, 2000, Guilhem Lavaux.\n"));
411
2bbf230a 412 wxMessageBox(msg, _T("About MMBoard"), wxOK | wxICON_INFORMATION, this);
e8482f24
GL
413}
414
415void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
416{
417 wxString selected_file;
dabbc6a5 418
e8482f24
GL
419 if (m_opened_file) {
420 if (!m_opened_file->IsStopped()) {
421 wxCommandEvent event2;
422 OnStop(event2);
423 }
424 delete m_opened_file;
425 }
dabbc6a5 426
e8482f24 427 // select a file to be opened
c54e5eb0 428#if wxUSE_FILEDLG
2bbf230a 429 selected_file = wxLoadFileSelector(_T("multimedia"), _T("*"), NULL, this);
c54e5eb0
WS
430#endif // wxUSE_FILEDLG
431 if (selected_file.empty())
e8482f24 432 return;
dabbc6a5 433
e8482f24 434 m_opened_file = MMBoardManager::Open(selected_file);
dabbc6a5 435
e8482f24
GL
436 // Change the range values of the slider.
437 MMBoardTime length;
dabbc6a5 438
e8482f24
GL
439 length = m_opened_file->GetLength();
440 m_positionSlider->SetRange(0, length.hours * 3600 + length.minutes * 60 + length.seconds);
dabbc6a5 441
e8482f24
GL
442 // Update misc info
443 UpdateMMedInfo();
dabbc6a5 444
d96cdd4a 445#if wxUSE_STATUSBAR
e8482f24 446 SetStatusText(selected_file, 2);
d96cdd4a 447#endif // wxUSE_STATUSBAR
dabbc6a5 448
e8482f24
GL
449 // Update info text
450 UpdateInfoText();
dabbc6a5 451
e8482f24 452 // Enable a few buttons
dabbc6a5
DS
453 m_playButton->Enable();
454 m_ejectButton->Enable();
455 m_positionSlider->Enable();
456
e8482f24
GL
457 if (m_opened_file->NeedWindow()) {
458 OpenVideoWindow();
459 m_opened_file->SetWindow(m_video_window);
460 } else
461 CloseVideoWindow();
462}
463
464void MMBoardFrame::UpdateInfoText()
465{
466 wxString infotext1, infotext2;
dabbc6a5 467
e8482f24
GL
468 if (m_opened_file) {
469 infotext1 = wxT("File type:\n\t");
470 infotext1 += m_opened_file->GetStringType() + wxT("\n");
dabbc6a5 471
e8482f24
GL
472 infotext2 = wxT("File informations:\n\n");
473 infotext2 += m_opened_file->GetStringInformation();
474 } else {
475 infotext1 = wxT("File type: \n\tNo file opened");
476 infotext2 = wxT("File informations:\nNo information\n\n\n\n\n");
477 }
dabbc6a5 478
e8482f24
GL
479 m_fileType->SetLabel(infotext1);
480 m_infoText->SetLabel(infotext2);
481}
482
483void MMBoardFrame::UpdateMMedInfo()
484{
e8482f24 485 MMBoardTime current, length;
dabbc6a5 486
e8482f24
GL
487 if (m_opened_file) {
488 current = m_opened_file->GetPosition();
489 length = m_opened_file->GetLength();
490 } else {
491 current.hours = current.minutes = current.seconds = 0;
492 length = current;
493 }
494
d96cdd4a 495#if wxUSE_STATUSBAR
e8482f24 496 // We refresh the status bar
d96cdd4a 497 wxString temp_string;
e8482f24
GL
498 temp_string.Printf(wxT("%02d:%02d / %02d:%02d"), current.hours * 60 + current.minutes,
499 current.seconds, length.hours * 60 + length.minutes, length.seconds);
500 SetStatusText(temp_string, 1);
d96cdd4a
WS
501#else
502 wxUnusedVar(length);
503#endif // wxUSE_STATUSBAR
dabbc6a5 504
e8482f24
GL
505 // We set the slider position
506 m_positionSlider->SetValue(current.hours * 3600 + current.minutes * 60 + current.seconds);
507}
508
509// ----------------------------------------------------------------------------
510// Playing management, refreshers, ...
511
512void MMBoardFrame::OnRefreshInfo(wxEvent& WXUNUSED(event))
513{
514 UpdateMMedInfo();
dabbc6a5
DS
515
516 if (m_opened_file->IsStopped())
517 {
e8482f24 518 m_refreshTimer->Stop();
dabbc6a5
DS
519 m_playButton->Enable();
520 m_stopButton->Disable();
521 m_pauseButton->Disable();
e8482f24
GL
522 }
523}
524
525void MMBoardFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
526{
dabbc6a5
DS
527 m_stopButton->Enable();
528 m_pauseButton->Enable();
529 m_playButton->Disable();
530
531 if (m_opened_file->IsPaused())
532 {
e8482f24
GL
533 m_opened_file->Resume();
534 return;
535 }
dabbc6a5
DS
536
537 m_refreshTimer->Start(1000, false);
538
e8482f24 539 m_opened_file->Play();
dabbc6a5
DS
540
541 m_stopButton->Enable();
542 m_pauseButton->Enable();
543 m_playButton->Disable();
e8482f24
GL
544}
545
546void MMBoardFrame::OnStop(wxCommandEvent& WXUNUSED(event))
547{
548 m_opened_file->Stop();
549 m_refreshTimer->Stop();
550
dabbc6a5
DS
551 m_stopButton->Disable();
552 m_playButton->Enable();
553
e8482f24
GL
554 UpdateMMedInfo();
555}
556
557void MMBoardFrame::OnPause(wxCommandEvent& WXUNUSED(event))
558{
559 m_opened_file->Pause();
dabbc6a5
DS
560
561 m_playButton->Enable();
562 m_pauseButton->Disable();
e8482f24
GL
563}
564
565void MMBoardFrame::OnEject(wxCommandEvent& WXUNUSED(event))
566{
567 m_opened_file->Stop();
568
569 delete m_opened_file;
570 m_opened_file = NULL;
dabbc6a5
DS
571
572 m_playButton->Disable();
573 m_pauseButton->Disable();
574 m_stopButton->Disable();
575 m_ejectButton->Disable();
576 m_positionSlider->Disable();
e8482f24
GL
577
578 UpdateInfoText();
579 UpdateMMedInfo();
580}
581
582void MMBoardFrame::OnSetPosition(wxCommandEvent& WXUNUSED(event))
583{
584 wxUint32 itime;
585 MMBoardTime btime;
dabbc6a5 586
e8482f24
GL
587 itime = m_positionSlider->GetValue();
588 btime.seconds = itime % 60;
589 btime.minutes = (itime / 60) % 60;
590 btime.hours = itime / 3600;
591 m_opened_file->SetPosition(btime);
592
593 UpdateMMedInfo();
594}