📄 dlgsrc.cpp
字号:
/*
* Copyright (c) Microsoft Corportation. All rights reserved.
*/
// DlgSrc.cpp : implementation file
//
/*
* preprocessor section
*/
#include <guiddef.h>
#include "stdafx.h"
#include "multichan.h"
#include "childview.h"
#include "DlgSrc.h"
#include <ks.h>
#include <ksmedia.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*
* definition section
*/
CONST_DWORD_REP cdrSpeakers[] =
{
{SPEAKER_FRONT_LEFT, "SPEAKER_FRONT_LEFT" } ,
{SPEAKER_FRONT_RIGHT, "SPEAKER_FRONT_RIGHT" } ,
{SPEAKER_FRONT_CENTER, "SPEAKER_FRONT_CENTER" } ,
{SPEAKER_LOW_FREQUENCY, "SPEAKER_LOW_FREQUENCY" } ,
{SPEAKER_BACK_LEFT, "SPEAKER_BACK_LEFT" } ,
{SPEAKER_BACK_RIGHT, "SPEAKER_BACK_RIGHT" } ,
{SPEAKER_FRONT_LEFT_OF_CENTER, "SPEAKER_FRONT_LEFT_OF_CENTER" } ,
{SPEAKER_FRONT_RIGHT_OF_CENTER, "SPEAKER_FRONT_RIGHT_OF_CENTER" } ,
{SPEAKER_BACK_CENTER, "SPEAKER_BACK_CENTER" } ,
{SPEAKER_SIDE_LEFT, "SPEAKER_SIDE_LEFT" } ,
{SPEAKER_SIDE_RIGHT, "SPEAKER_SIDE_RIGHT" } ,
{SPEAKER_TOP_CENTER, "SPEAKER_TOP_CENTER" } ,
{SPEAKER_TOP_FRONT_LEFT, "SPEAKER_TOP_FRONT_LEFT" } ,
{SPEAKER_TOP_FRONT_CENTER, "SPEAKER_TOP_FRONT_CENTER" } ,
{SPEAKER_TOP_FRONT_RIGHT, "SPEAKER_TOP_FRONT_RIGHT" } ,
{SPEAKER_TOP_BACK_LEFT, "SPEAKER_TOP_BACK_LEFT" } ,
{SPEAKER_TOP_BACK_CENTER, "SPEAKER_TOP_BACK_CENTER" } ,
{SPEAKER_TOP_BACK_RIGHT, "SPEAKER_TOP_BACK_RIGHT" } ,
{SPEAKER_NOT_SPECIFIED, "No specified speaker" }
};
/////////////////////////////////////////////////////////////////////////////
// CDlgSrc dialog
/*
* MFC mechanisms
*/
void
CDlgSrc::DoDataExchange
(
CDataExchange* pDX
)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgSrc)
DDX_Control(pDX, IDOK, m_butClose);
DDX_Control( pDX, IDC_PLAY, m_butPlay );
DDX_Control( pDX, IDC_STOP, m_butStop );
DDX_Control(pDX, IDC_INPUT, m_cInput);
DDX_Control(pDX, IDC_COMBO_SPEAKER, m_comboSpeaker);
DDX_Check(pDX, IDC_USE, m_fUse);
DDX_CBIndex(pDX, IDC_COMBO_SPEAKER, m_nSpeaker);
DDX_Text(pDX, IDC_INPUT, m_strName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgSrc, CDialog)
//{{AFX_MSG_MAP(CDlgSrc)
ON_CBN_SELENDOK(IDC_COMBO_SPEAKER, OnComboSpeaker)
ON_BN_CLICKED(IDC_PLAY, OnPlay)
ON_BN_CLICKED(IDC_STOP, OnStop)
ON_WM_CTLCOLOR()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
/*
* Constructors
*/
// ----------------------------------------------------------------------------------
// CDlgSrc::CDlgSrc
// constructor
// ----------------------------------------------------------------------------------
CDlgSrc::CDlgSrc
(
CWnd* pParent /*=NULL*/
)
: CDialog(CDlgSrc::IDD, pParent),
m_strName(TEXT("")),
m_pwndParent(pParent),
m_cSamples(0),
m_cbData(0),
m_nChannel(0),
m_dwChannelMask(SPEAKER_FRONT_LEFT),
m_fDragging(FALSE),
m_fPlayable( FALSE ),
m_lpwhdr( 0 )
{
//{{AFX_DATA_INIT(CDlgSrc)
m_fUse = TRUE;
m_nSpeaker = 0;
m_strName = _T("");
//}}AFX_DATA_INIT
ZeroMemory( &m_wfx, sizeof( WAVEFORMATEX ) );
}
// ----------------------------------------------------------------------------------
// CDlgSrc::~CDlgSrc
// destructor
// ----------------------------------------------------------------------------------
CDlgSrc::~CDlgSrc
()
{
//
// update speaker mask
//
if( g_pdlgDest )
g_pdlgDest->m_wfExt.dwChannelMask ^= m_dwChannelMask;
//
// release memory
//
SafeLocalFree( m_pvData );
SafeLocalFree( m_lpwhdr );
}
// ----------------------------------------------------------------------------------
// CDlgSrc::Create
// creates an SRC dialog whose title is strName, position is sizeInitPos, and
// channel mask is dwChannelMask
// ----------------------------------------------------------------------------------
void
CDlgSrc::Create
(
LPCSTR strName,
SIZE sizeInitPos,
DWORD dwChannelMask
)
{
CDialog::Create( CDlgSrc::IDD, m_pwndParent );
//
// position the dialog for that nice cascade effect
//
CRect rect;
GetClientRect( &rect );
rect.OffsetRect( *(LPPOINT(&sizeInitPos)) );
rect.right += 4;
rect.bottom += 4;
MoveWindow( &rect, TRUE );
//
// set window text
//
m_strName = strName;
//
// populate the speakers combo
// speaker positions are defined in KSMedia.h or in MMReg.h
//
int i;
int c;
for( c = 0; c < ARRAY_ELEMENTS( cdrSpeakers ); c++ )
{
i = m_comboSpeaker.AddString( cdrSpeakers[c].pstrRep ); // friendly name
m_comboSpeaker.SetItemData( i, cdrSpeakers[c].dwConstant ); // index
if( cdrSpeakers[c].dwConstant == dwChannelMask ) // check out of range
m_nSpeaker = c;
}
m_dwChannelMask = dwChannelMask; // overall channel mask
//
// make playable
//
m_fPlayable = TRUE;
m_butPlay.EnableWindow( m_fPlayable );
m_butStop.EnableWindow( !m_fPlayable );
//
// update controls
//
UpdateData( FALSE );
} // CDglSrc::Create
/*
* Accessors
*/
// ----------------------------------------------------------------------------------
// AquireData
// This fn extracts a single channel (nChannelFrom) from the wave data specified by
// pwfx, pvData, and cbData
// ----------------------------------------------------------------------------------
BOOL
CDlgSrc::AquireData
(
WAVEFORMATEX* pwfx,
PVOID pvData,
ULONG cbData,
UINT nChannelFrom
)
{
ASSERT( pwfx );
if (! (pwfx && (pwfx->cbSize == 0) && pvData && cbData))
return FALSE;
CopyMemory(&m_wfx, pwfx, sizeof(m_wfx));
GUID guid = (( WAVEFORMATEXTENSIBLE * )pwfx)->SubFormat;
if( IS_VALID_WAVEFORMATEX_GUID( &guid ) )
{
m_wfx.wFormatTag = EXTRACT_WAVEFORMATEX_ID( &guid );
}
//
// else no op
//
m_wfx.nChannels = 1;
m_wfx.nBlockAlign = m_wfx.wBitsPerSample / 8;
m_wfx.nAvgBytesPerSec = m_wfx.nBlockAlign * m_wfx.nSamplesPerSec;
// a little more UI
char sz[100];
_snprintf(sz, 100, "%d", pwfx->wBitsPerSample);
SetDlgItemText(IDC_BITDEPTH, sz);
_snprintf(sz, 100, "%d", pwfx->nSamplesPerSec);
SetDlgItemText(IDC_SAMPLERATE, sz);
//
// extract nChannelFrom-th channel from the data
// should be pretty much a no-op for already-mono formats
//
ULONG nSample;
USHORT nBytes = pwfx->wBitsPerSample / 8;
m_cSamples = cbData / pwfx->nBlockAlign;
m_cbData = m_wfx.nBlockAlign * m_cSamples;
m_pvData = LocalAlloc(LPTR, m_cbData);
if( 0 == m_pvData)
{
MessageBox( "Insufficient memory to complete the task.", "MultiChan : Error", MB_OK | MB_ICONSTOP );
return( FALSE );
}
//
// Adding support for multi-channel input
//
if( 1 == pwfx->nChannels )
{
//
// trivial copy
//
ASSERT(m_cbData == cbData);
CopyMemory( m_pvData, pvData, m_cbData );
}
else
{
//
// m channels, n bit depth
// extract out every other m-th group of n bits
// repeat for m_cSamples
//
BYTE * pbDest = (BYTE * )m_pvData;
BYTE * pbSrc = ( BYTE * )pvData;
//
// start with the appropriate channel; channels are 0-based
//
pbSrc+= nChannelFrom * ( pwfx->wBitsPerSample / 8 );
for( nSample = 0; nSample < m_cSamples; nSample++ )
{
USHORT nCount = nBytes;
while( nCount-- )
*pbDest++ = *pbSrc++;
pbSrc+= (pwfx->nChannels - 1) * nBytes;
}
}
return( TRUE );
} // CDglSrc::AcquireData
/*
* UI triggered procedures
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -