home *** CD-ROM | disk | FTP | other *** search
- /*
- * AudioProperties.cpp
- *
- * Copyright (C) Alberto Vigata - July 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * FlasKMPEG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-
- #include "FlasKMPEG.h"
- #include "auxiliary.h"
- #include "resource.h"
- #include "Player.h"
- #include "debug.h"
- #include "AudioProperties.h"
- #include "./RunState.h"
- #include "./Audio/AudioPlayback.h"
- #include "./Misc/StatsStrings.h"
- #include <string>
-
- // Extern globals
- extern TConfig o;
- extern TRunState rs;
- extern HINSTANCE hInst;
- extern HWND hMainWnd;
-
- // Local variables
- static HWND hPlayerDlg;
- static CAudioThread *g_pAudioThread;
-
- #define NORMSLIDER_MAX 200
- #undef AUDIO_PLAYBACK_TRACE
-
- const int nTrackBarRange = 1000;
-
- extern TProfile pprof; // the player profile. Use this only
-
-
- // Actual running thread
- DWORD CAudioThread::ThreadProc()
- {
- m_nState = stStopped;
- bool bAudioAvailable;
-
- TCommand sCommand;
-
- ui32 nSamplesPlayed=0; // This is our way to keep track of time with audio
- mmtick tkPresTime;
-
- m_tkSensThreshold = 1000;
-
- pprof.sAudioProperties.sAudioTrack = rs.sAudioTrack;
-
- TAudioPlayback sAudioPlayback;
- unsigned char *data;
- sAudioPlayback.n_channels = 2;
- if (pprof.sampleFreqSameAsInput)
- sAudioPlayback.sample_freq = rs.audio->sampleRate;
- else
- sAudioPlayback.sample_freq = pprof.outSampleFrequency;
- sAudioPlayback.chunk_size = 16384*2;
-
- bAudioAvailable = AudioPlaybackStart(&sAudioPlayback) > 0;
- SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
-
- while(1)
- {
- // open scope to lock command
- if( GetCommand(&sCommand) )
- {
- switch( sCommand.nCommand )
- {
- case noCommand:
- break;
- case seek:
- if(rs.audio )
- {
- if(m_nState!=stStopped)
- rs.audio->Stop();
- rs.audio->SetStreamPos(sCommand.nParam);
- rs.audio->Start(sAudioPlayback.sample_freq, DO_AUDIO|AUDIO_PREVIEW, &pprof.sAudioProperties);
- m_nState = stStopped;
- }
- break;
- case play:
- if(rs.audio && bAudioAvailable )
- {
- if(m_nState!=stStopped)
- rs.audio->Stop();
-
- nSamplesPlayed = 0;
- rs.audio->Start(sAudioPlayback.sample_freq, DO_AUDIO|AUDIO_PREVIEW, &pprof.sAudioProperties);
- m_nState = stPlaying;
- }
- break;
- case trackChange:
- if(rs.audio )
- {
- TAudioTrack *pTrack = (TAudioTrack *)sCommand.nParam;
- rs.audio->SetTrack(pTrack);
- }
- break;
- case stop:
- if(rs.audio )
- {
- if(m_nState!=stStopped)
- rs.audio->Stop();
-
- if(bAudioAvailable)
- AudioPlayBackReset();
-
- m_nState = stStopped;
- }
- break;
- case normalize:
- if(rs.audio )
- {
- if(m_nState!=stStopped)
- rs.audio->Stop();
- rs.audio->SetStreamPos(0);
- rs.audio->Start(sAudioPlayback.sample_freq,
- DO_AUDIO|AUDIO_PREVIEW|AUDIO_DONT_NORMALIZE,
- &pprof.sAudioProperties );
- m_nState = stNormalizing;
- }
- break;
- case exit:
- if(m_nState!=stStopped && rs.audio)
- rs.audio->Stop();
-
- ReplyCommand(&sCommand);
- goto end;
- break;
- }
-
- ReplyCommand(&sCommand);
- }
- else // No command. Wait if stopped
- {
- if(m_nState==stStopped)
- WaitCommand();
- }
-
- // Perform action according the state of the playe
-
-
- switch(m_nState)
- {
- case stStopped:
- break;
- case stPlaying:
- if( !rs.audio->GetSamples(0, (short **)&data, (sAudioPlayback.chunk_size)>>2) )
- {
- rs.audio->Stop();
-
- if(bAudioAvailable)
- AudioPlayBackReset();
-
- m_nState = stStopped;
- continue;
- }
-
- // DBG_STR((str, "Starting Audio Playing at %I64d ms\n", m_pMasterClock->GetTickCount()/10 ))
-
- nSamplesPlayed += (sAudioPlayback.chunk_size)>>2;
-
- // Calculate the presentation time of the first sample of this chunk
- tkPresTime = ((mmtick)nSamplesPlayed * (mmtick)10000) /(mmtick)sAudioPlayback.sample_freq;
-
- // Adjust the presentation time taking into account
- // the amount of data currently in the audio buffer
- if(bAudioAvailable)
- {
- m_pMasterClock->Set( tkPresTime - AudioGetBufferDelay(&sAudioPlayback)*10);
- AudioPlaybackWrite(&sAudioPlayback, data);
- }
-
-
-
- break;
- case stNormalizing:
- rs.audio->GetSamples(0, (short **)&data, (sAudioPlayback.chunk_size)>>2);
- nSamplesPlayed += (sAudioPlayback.chunk_size)>>2;
-
- ui16 max = FindMax((i16*)data, sAudioPlayback.chunk_size);
- if( max >= m_nMaxSample )
- m_nMaxSample = max;
- break;
- }
-
- }
-
- end:
- if(bAudioAvailable)
- AudioPlaybackStop(&sAudioPlayback);
- // Exit
- return 0;
- }
-
-
-
- void RenderMCSlider(HWND hDlg, int sliderID, int sliderDB, int value)
- {
- char szTemp[256];
-
- SendDlgItemMessage(hDlg, sliderID, TBM_SETRANGE,
- (WPARAM) TRUE, (LPARAM) MAKELONG(0, TAUDIOPROPERTIES_MCHANNEL_MAX_RANGE*2));
-
-
- sprintf(szTemp, "%s%1.2f dB", value>0?"+":"", ((float)(value)/(float)100));
- DlgSetText( hDlg, sliderDB, szTemp );
-
- value += TAUDIOPROPERTIES_MCHANNEL_MAX_RANGE;
- value = TAUDIOPROPERTIES_MCHANNEL_MAX_RANGE*2 - value;
- // Set the track position
- SendDlgItemMessage(hDlg, sliderID, TBM_SETPOS, (WPARAM) (BOOL) true,(LPARAM) (LONG) value);
- }
-
- // Activate, de-activate sliders
- void RenderSliders(HWND hDlg, TAudioProperties *pAudProps, TStatsStrings &st)
- {
- DlgCheck(hDlg, IDC_DRCCHECK, pAudProps->drc );
- DlgEnable(hDlg, IDC_DRCSLIDER, pAudProps->drc);
- DlgEnable(hDlg, IDC_NORMSLIDER, pAudProps->normalize);
-
- DlgCheck(hDlg, IDC_NORMCHECK, pAudProps->normalize );
- DlgEnable(hDlg, IDC_NORMSEARCH, pAudProps->normalize);
- DlgEnable(hDlg, IDC_NORMEDIT, pAudProps->normalize);
- DlgSetText(hDlg, IDC_NORMEDIT, pAudProps->normalize_value );
-
- // NORM slider
- SendDlgItemMessage(hDlg, IDC_NORMSLIDER, TBM_SETRANGE,
- (WPARAM) TRUE, (LPARAM) MAKELONG(0, NORMSLIDER_MAX));
-
- SendDlgItemMessage(hDlg, IDC_NORMSLIDER, TBM_SETPOS,
- (WPARAM) (BOOL) true,
- (LPARAM) (LONG) NORMSLIDER_MAX - pAudProps->normalize_value);
-
-
- DlgCheck(hDlg, IDC_DOLBYDOWNMIX, pAudProps->dolby_surround_downmix );
- DlgCheck(hDlg, IDC_MCCHECK, pAudProps->multichannel_volume );
- DlgEnable(hDlg, IDC_MCCENTER, pAudProps->multichannel_volume);
- DlgEnable(hDlg, IDC_MCFRONT, pAudProps->multichannel_volume);
- DlgEnable(hDlg, IDC_MCREAR, pAudProps->multichannel_volume);
- DlgEnable(hDlg, IDC_MCRESET, pAudProps->multichannel_volume);
-
- // Now set the value
-
- // DRC
- SendDlgItemMessage(hDlg, IDC_DRCSLIDER, TBM_SETRANGE,
- (WPARAM) TRUE, (LPARAM) MAKELONG(0, COMPRESSOR_STEPS));
-
- SendDlgItemMessage(hDlg, IDC_DRCSLIDER, TBM_SETPOS,
- (WPARAM) (BOOL) true,
- (LPARAM) (LONG) COMPRESSOR_STEPS - pAudProps->drc_value);
-
- DlgSetText( hDlg, IDC_PROPSFORMAT, st.InMedia.audio_format );
- DlgSetText( hDlg, IDC_PROPSBITRATE, st.InMedia.audio_bit_rate );
- DlgSetText( hDlg, IDC_PROPSMODE, st.InMedia.audio_channels );
- DlgSetText( hDlg, IDC_PROPSSAMPLEFREQ, st.InMedia.audio_sample_freq );
-
- // Finally set the values to the audio renderer
- rs.audio->SetAudioProperties(pAudProps);
- }
-
- void EndAudioProperties( HWND hDlg)
- {
- KillTimer(hDlg, 2);
-
- return;
- }
- LRESULT CALLBACK AudioPropertiesDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static DWORD lPosition;
- static ui64 nFilePos;
- static bool userIsTracking;
- static int nFirstAudioId;
- static TStatsStrings st;
- int i;
-
- switch (message)
- {
- case WM_TIMER:
- RenderInaudioStatsStrings( &st );
- RenderSliders(hDlg, &pprof.sAudioProperties, st );
- break;
- case WM_INITDIALOG:
- // First of all check to see that in fact there is audio here
- if(!rs.audio)
- return FALSE;
-
- RenderStatsStrings(&st);
-
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
-
- // Fill tracks list from working mism
- fmStreamId strId;
- GetFirstAudioId(&rs.sStreamIds, &strId, &nFirstAudioId);
- for(i=0; i<rs.sStreamIds.idCount; i++)
- {
- if( MismIsAudioId(&rs.sStreamIds.vIds[i]) )
- ListAddText(GetDlgItem(hDlg, IDC_TRACKS), rs.sStreamIds.vIds[i].streamName);
- }
-
- // select the default one
- ListSetCur(GetDlgItem(hDlg, IDC_TRACKS), rs.sStreamIds.idAudioDef - nFirstAudioId);
-
- // set as toolbar
- SetWindowLong( hDlg, GWL_EXSTYLE, WS_EX_TOOLWINDOW );
- // Create timer
- SetTimer(hDlg, 2, 500, NULL );
-
- return TRUE;
-
- case WM_VSCROLL:
- {
- int range = TAUDIOPROPERTIES_MCHANNEL_MAX_RANGE;
-
- pprof.sAudioProperties.drc_value =
- COMPRESSOR_STEPS - SendDlgItemMessage(hDlg, IDC_DRCSLIDER, TBM_GETPOS, 0, 0 );
-
- pprof.sAudioProperties.normalize_value =
- NORMSLIDER_MAX - SendDlgItemMessage(hDlg, IDC_NORMSLIDER, TBM_GETPOS, 0, 0 );
-
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- }
- break;
- case WM_COMMAND:
- switch( HIWORD(wParam))
- {
- case EN_UPDATE:
- pprof.sAudioProperties.normalize_value = DlgGetText(hDlg, IDC_NORMEDIT);
- rs.audio->SetAudioProperties( &pprof.sAudioProperties );
- break;
- case CBN_SELCHANGE:
- {
- int nSelected = ListGetCur(GetDlgItem(hDlg, IDC_TRACKS));
- rs.sAudioTrack.nStreamId = rs.sStreamIds.vIds[nSelected+nFirstAudioId].streamId;
- rs.sAudioTrack.nSubStreamId = rs.sStreamIds.vIds[nSelected+nFirstAudioId].subStreamId;
-
- pprof.sAudioProperties.sAudioTrack = rs.sAudioTrack;
-
- g_pAudioThread->SendCommand( CAudioThread::trackChange,
- (ui64)&rs.sAudioTrack );
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- }
- break;
- }
- switch( LOWORD(wParam))
- {
- case IDOK:
- CloseAudioPanel();
- break;
- case IDCANCEL:
- break;
-
- case IDC_DRCCHECK:
- pprof.sAudioProperties.drc = DlgIsChecked(hDlg, IDC_DRCCHECK);
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- break;
- case IDC_NORMCHECK:
- pprof.sAudioProperties.normalize = DlgIsChecked(hDlg, IDC_NORMCHECK);
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- break;
- case IDC_MCCHECK:
- pprof.sAudioProperties.multichannel_volume = DlgIsChecked(hDlg, IDC_MCCHECK);
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- break;
- case IDC_MCRESET:
- pprof.sAudioProperties.front =
- pprof.sAudioProperties.center =
- pprof.sAudioProperties.rear = 0;
-
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- break;
- case IDC_DOLBYDOWNMIX:
- pprof.sAudioProperties.dolby_surround_downmix = DlgIsChecked(hDlg, IDC_DOLBYDOWNMIX);
- RenderSliders(hDlg, &pprof.sAudioProperties, st);
- break;
- case IDC_NORMSEARCH:
- break;
- case IDC_SLIDER:
- break;
- case IDC_PLAY:
- break;
- case IDC_STOP:
- break;
- }
- break;
- }
- return FALSE;
- }
-
- void ShowAudioPanel(CAudioThread *pAudioThread)
- {
- if(!hPlayerDlg)
- {
- g_pAudioThread = pAudioThread;
-
- hPlayerDlg = CreateDialog( hInst,
- MAKEINTRESOURCE(IDD_AUDIOPROPERTIES),
- hMainWnd,
- (DLGPROC) AudioPropertiesDlg );
- ShowWindow( hPlayerDlg, SW_SHOW );
-
- }
- }
-
- void CloseAudioPanel()
- {
- if(hPlayerDlg)
- {
- EndAudioProperties( hPlayerDlg );
- DestroyWindow( hPlayerDlg );
- }
- hPlayerDlg = NULL;
- }
-