|
Packit |
47f805 |
/**
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* Lame ACM wrapper, encode/decode MP3 based RIFF/AVI files in MS Windows
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* Copyright (c) 2002 Steve Lhomme <steve.lhomme at free.fr>
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
47f805 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
47f805 |
* License as published by the Free Software Foundation; either
|
|
Packit |
47f805 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
47f805 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
47f805 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
47f805 |
* Lesser General Public License for more details.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
47f805 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
47f805 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
\author Steve Lhomme
|
|
Packit |
47f805 |
\version \$Id: ACM.cpp,v 1.20 2007/05/17 22:25:40 robert Exp $
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#if !defined(STRICT)
|
|
Packit |
47f805 |
#define STRICT
|
|
Packit |
47f805 |
#endif // STRICT
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <algorithm>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <windows.h>
|
|
Packit |
47f805 |
#include <windowsx.h>
|
|
Packit |
47f805 |
#include <intshcut.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <mmreg.h>
|
|
Packit |
47f805 |
#include <msacm.h>
|
|
Packit |
47f805 |
#include <msacmdrv.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <assert.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <lame.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include "adebug.h"
|
|
Packit |
47f805 |
#include "resource.h"
|
|
Packit |
47f805 |
#include "ACMStream.h"
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
#include "DecodeStream.h"
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include "ACM.h"
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifndef IDC_HAND
|
|
Packit |
47f805 |
#define IDC_HAND MAKEINTRESOURCE(32649)
|
|
Packit |
47f805 |
#endif // IDC_HAND
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
char ACM::VersionString[120];
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char ACM_VERSION[] = "0.9.2";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef WIN32
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// 32-bit versions
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
#if (WINVER >= 0x0400)
|
|
Packit |
47f805 |
#define VERSION_ACM_DRIVER MAKE_ACM_VERSION(4, 0, 0)
|
|
Packit |
47f805 |
#else
|
|
Packit |
47f805 |
#define VERSION_ACM_DRIVER MAKE_ACM_VERSION(3, 51, 0)
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
#define VERSION_MSACM MAKE_ACM_VERSION(3, 50, 0)
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#else
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// 16-bit versions
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
#define VERSION_ACM_DRIVER MAKE_ACM_VERSION(1, 0, 0)
|
|
Packit |
47f805 |
#define VERSION_MSACM MAKE_ACM_VERSION(2, 1, 0)
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define PERSONAL_FORMAT WAVE_FORMAT_MPEGLAYER3
|
|
Packit |
47f805 |
#define SIZE_FORMAT_STRUCT sizeof(MPEGLAYER3WAVEFORMAT)
|
|
Packit |
47f805 |
//#define SIZE_FORMAT_STRUCT 0
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//static const char channel_mode[][13] = {"mono","stereo","joint stereo","dual channel"};
|
|
Packit |
47f805 |
static const char channel_mode[][13] = {"mono","stereo"};
|
|
Packit |
47f805 |
static const unsigned int mpeg1_freq[] = {48000,44100,32000};
|
|
Packit |
47f805 |
static const unsigned int mpeg2_freq[] = {24000,22050,16000,12000,11025,8000};
|
|
Packit |
47f805 |
static const unsigned int mpeg1_bitrate[] = {320, 256, 224, 192, 160, 128, 112, 96, 80, 64, 56, 48, 40, 32};
|
|
Packit |
47f805 |
static const unsigned int mpeg2_bitrate[] = {160, 144, 128, 112, 96, 80, 64, 56, 48, 40, 32, 24, 16, 8};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define SIZE_CHANNEL_MODE (sizeof(channel_mode) / (sizeof(char) * 13))
|
|
Packit |
47f805 |
#define SIZE_FREQ_MPEG1 (sizeof(mpeg1_freq) / sizeof(unsigned int))
|
|
Packit |
47f805 |
#define SIZE_FREQ_MPEG2 (sizeof(mpeg2_freq) / sizeof(unsigned int))
|
|
Packit |
47f805 |
#define SIZE_BITRATE_MPEG1 (sizeof(mpeg1_bitrate) / sizeof(unsigned int))
|
|
Packit |
47f805 |
#define SIZE_BITRATE_MPEG2 (sizeof(mpeg2_bitrate) / sizeof(unsigned int))
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static const int FORMAT_TAG_MAX_NB = 2; // PCM and PERSONAL (mandatory to have at least PCM and your format)
|
|
Packit |
47f805 |
static const int FILTER_TAG_MAX_NB = 0; // this is a codec, not a filter
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// number of supported PCM formats
|
|
Packit |
47f805 |
static const int FORMAT_MAX_NB_PCM =
|
|
Packit |
47f805 |
2 * // number of PCM channel mode (stereo/mono)
|
|
Packit |
47f805 |
(SIZE_FREQ_MPEG1 + // number of MPEG 1 sampling freq
|
|
Packit |
47f805 |
SIZE_FREQ_MPEG2); // number of MPEG 2 sampling freq
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
bool bitrate_item::operator<(const bitrate_item & other_bitrate) const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return (other_bitrate.frequency < frequency ||
|
|
Packit |
47f805 |
(other_bitrate.frequency == frequency &&
|
|
Packit |
47f805 |
(other_bitrate.bitrate < bitrate ||
|
|
Packit |
47f805 |
(other_bitrate.bitrate == bitrate &&
|
|
Packit |
47f805 |
(other_bitrate.channels < channels)))));
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Configuration Dialog
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
static CALLBACK ConfigProc(
|
|
Packit |
47f805 |
HWND hwndDlg, // handle to dialog box
|
|
Packit |
47f805 |
UINT uMsg, // message
|
|
Packit |
47f805 |
WPARAM wParam, // first message parameter
|
|
Packit |
47f805 |
LPARAM lParam // second message parameter
|
|
Packit |
47f805 |
)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
BOOL bResult;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (uMsg) {
|
|
Packit |
47f805 |
case WM_COMMAND:
|
|
Packit |
47f805 |
UINT command;
|
|
Packit |
47f805 |
command = GET_WM_COMMAND_ID(wParam, lParam);
|
|
Packit |
47f805 |
if (IDOK == command)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
EndDialog(hwndDlg, (IDOK == command));
|
|
Packit |
47f805 |
} else if (IDCANCEL == command)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
EndDialog(hwndDlg, (IDOK == command));
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
bResult = FALSE;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
bResult = FALSE; // will be treated by DefWindowProc
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return bResult;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::Configure(HWND hParentWindow, LPDRVCONFIGINFO pConfig)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM : Configure (Parent Window = 0x%08X)",hParentWindow);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DialogBoxParam( my_hModule, MAKEINTRESOURCE(IDD_CONFIG), hParentWindow, ::ConfigProc , (LPARAM)this);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return DRVCNF_OK; // Can also return
|
|
Packit |
47f805 |
// DRVCNF_CANCEL
|
|
Packit |
47f805 |
// and DRVCNF_RESTART
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// About Dialog
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static BOOL CALLBACK AboutProc(
|
|
Packit |
47f805 |
HWND hwndDlg, // handle to dialog box
|
|
Packit |
47f805 |
UINT uMsg, // message
|
|
Packit |
47f805 |
WPARAM wParam, // first message parameter
|
|
Packit |
47f805 |
LPARAM lParam // second message parameter
|
|
Packit |
47f805 |
)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
static HBRUSH hBrushStatic = NULL;
|
|
Packit |
47f805 |
// static LOGFONT lf; // structure for font information
|
|
Packit |
47f805 |
// static HFONT hfnt;
|
|
Packit |
47f805 |
static HCURSOR hcOverCursor = NULL;
|
|
Packit |
47f805 |
BOOL bResult;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (uMsg) {
|
|
Packit |
47f805 |
case WM_INITDIALOG:
|
|
Packit |
47f805 |
char tmp[150];
|
|
Packit |
47f805 |
wsprintf(tmp,"LAME MP3 codec v%s", ACM::GetVersionString());
|
|
Packit |
47f805 |
::SetWindowText(GetDlgItem( hwndDlg, IDC_STATIC_ABOUT_TITLE), tmp);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf);
|
|
Packit |
47f805 |
lf.lfUnderline = TRUE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
hfnt = ::CreateFontIndirect(&lf);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
::SendMessage(::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), WM_SETFONT, (WPARAM) hfnt, TRUE);
|
|
Packit |
47f805 |
* /
|
|
Packit |
47f805 |
hBrushStatic = ::CreateSolidBrush(::GetSysColor (COLOR_BTNFACE));
|
|
Packit |
47f805 |
*/ hcOverCursor = ::LoadCursor(NULL,(LPCTSTR)IDC_HAND);
|
|
Packit |
47f805 |
if (hcOverCursor == NULL)
|
|
Packit |
47f805 |
hcOverCursor = ::LoadCursor(NULL,(LPCTSTR)IDC_CROSS);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bResult = TRUE;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
case WM_CTLCOLORSTATIC:
|
|
Packit |
47f805 |
/// \todo only if there are URLs
|
|
Packit |
47f805 |
if ((HWND)lParam == ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
::SetTextColor((HDC)wParam, ::GetSysColor (COLOR_HIGHLIGHT));
|
|
Packit |
47f805 |
::SetBkColor((HDC)wParam, ::GetSysColor (COLOR_BTNFACE));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return (LRESULT) hBrushStatic;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
return (LRESULT) NULL;
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
case WM_MOUSEMOVE:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
POINT pnt;
|
|
Packit |
47f805 |
::GetCursorPos(&pnt);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
RECT rect;
|
|
Packit |
47f805 |
::GetWindowRect( ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), &rect);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( ::PtInRect(&rect,pnt) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
::SetCursor(hcOverCursor);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case WM_LBUTTONUP:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
POINT pnt;
|
|
Packit |
47f805 |
::GetCursorPos(&pnt);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
RECT rect;
|
|
Packit |
47f805 |
::GetWindowRect( ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), &rect);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
TCHAR Url[200];
|
|
Packit |
47f805 |
bool bUrl = false;
|
|
Packit |
47f805 |
if (::PtInRect(&rect,pnt))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
wsprintf(Url,get_lame_url());
|
|
Packit |
47f805 |
bUrl = true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (bUrl)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
LPSTR tmpStr;
|
|
Packit |
47f805 |
HRESULT hresult = ::TranslateURL(Url, TRANSLATEURL_FL_GUESS_PROTOCOL|TRANSLATEURL_FL_GUESS_PROTOCOL, &tmpStr);
|
|
Packit |
47f805 |
if (hresult == S_OK)
|
|
Packit |
47f805 |
::ShellExecute(hwndDlg,"open",tmpStr,NULL,"",SW_SHOWMAXIMIZED );
|
|
Packit |
47f805 |
else if (hresult == S_FALSE)
|
|
Packit |
47f805 |
::ShellExecute(hwndDlg,"open",Url,NULL,"",SW_SHOWMAXIMIZED );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case WM_COMMAND:
|
|
Packit |
47f805 |
UINT command;
|
|
Packit |
47f805 |
command = GET_WM_COMMAND_ID(wParam, lParam);
|
|
Packit |
47f805 |
if (IDOK == command)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
EndDialog(hwndDlg, TRUE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
bResult = FALSE;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case IDC_STATIC_ABOUT_URL:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
bResult = FALSE; // will be treated by DefWindowProc
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return bResult;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::About(HWND hParentWindow)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM : About (Parent Window = 0x%08X)",hParentWindow);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DialogBoxParam( my_hModule, MAKEINTRESOURCE(IDD_ABOUT), hParentWindow, ::AboutProc , (LPARAM)this);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return DRVCNF_OK; // Can also return
|
|
Packit |
47f805 |
// DRVCNF_CANCEL
|
|
Packit |
47f805 |
// and DRVCNF_RESTART
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Construction/Destruction
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ACM::ACM( HMODULE hModule )
|
|
Packit |
47f805 |
:my_hModule(hModule),
|
|
Packit |
47f805 |
my_hIcon(NULL),
|
|
Packit |
47f805 |
my_debug(ADbg(DEBUG_LEVEL_CREATION)),
|
|
Packit |
47f805 |
my_EncodingProperties(hModule)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_EncodingProperties.ParamsRestore();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo get the debug level from the registry
|
|
Packit |
47f805 |
unsigned char DebugFileName[512];
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
char tmp[128];
|
|
Packit |
47f805 |
wsprintf(tmp,"LAMEacm 0x%08X",this);
|
|
Packit |
47f805 |
my_debug.setPrefix(tmp); /// \todo get it from the registry
|
|
Packit |
47f805 |
my_debug.setIncludeTime(true); /// \todo get it from the registry
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Check in the registry if we have to Output Debug information
|
|
Packit |
47f805 |
DebugFileName[0] = '\0';
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HKEY OssKey;
|
|
Packit |
47f805 |
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\MUKOLI", 0, KEY_READ , &OssKey ) == ERROR_SUCCESS) {
|
|
Packit |
47f805 |
DWORD DataType;
|
|
Packit |
47f805 |
DWORD DebugFileNameSize = 512;
|
|
Packit |
47f805 |
if (RegQueryValueEx( OssKey, "DebugFile", NULL, &DataType, DebugFileName, &DebugFileNameSize ) == ERROR_SUCCESS) {
|
|
Packit |
47f805 |
if (DataType == REG_SZ) {
|
|
Packit |
47f805 |
my_debug.setUseFile(true);
|
|
Packit |
47f805 |
my_debug.setDebugFile((char *)DebugFileName);
|
|
Packit |
47f805 |
my_debug.OutPut("Debug file is %s",(char *)DebugFileName);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
wsprintf(VersionString,"%s - %s", ACM_VERSION, get_lame_version() );
|
|
Packit |
47f805 |
BuildBitrateTable();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "New ACM Creation (0x%08X)",this);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ACM::~ACM()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// not used, it's done automatically when closing the driver if (my_hIcon != NULL)
|
|
Packit |
47f805 |
// CloseHandle(my_hIcon);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table.clear();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM Deleted (0x%08X)",this);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Main message handler
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
LONG ACM::DriverProcedure(const HDRVR hdrvr, const UINT msg, LONG lParam1, LONG lParam2)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD dwRes = 0L;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//my_debug.OutPut(DEBUG_LEVEL_MSG, "message 0x%08X for ThisACM 0x%08X", msg, this);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (msg) {
|
|
Packit |
47f805 |
case DRV_INSTALL:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_INSTALL");
|
|
Packit |
47f805 |
// Sent when the driver is installed.
|
|
Packit |
47f805 |
dwRes = DRVCNF_OK; // Can also return
|
|
Packit |
47f805 |
break; // DRVCNF_CANCEL
|
|
Packit |
47f805 |
// and DRV_RESTART
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case DRV_REMOVE:
|
|
Packit |
47f805 |
// Sent when the driver is removed.
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_REMOVE");
|
|
Packit |
47f805 |
dwRes = 1L; // return value ignored
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case DRV_QUERYCONFIGURE:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_QUERYCONFIGURE");
|
|
Packit |
47f805 |
// Sent to determine if the driver can be
|
|
Packit |
47f805 |
// configured.
|
|
Packit |
47f805 |
dwRes = 1L; // Zero indicates configuration
|
|
Packit |
47f805 |
break; // NOT supported
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case DRV_CONFIGURE:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_CONFIGURE");
|
|
Packit |
47f805 |
// Sent to display the configuration
|
|
Packit |
47f805 |
// dialog box for the driver.
|
|
Packit |
47f805 |
// dwRes = Configure( (HWND) lParam1, (LPDRVCONFIGINFO) lParam2 );
|
|
Packit |
47f805 |
if (my_EncodingProperties.Config(my_hModule, (HWND) lParam1))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
dwRes = DRVCNF_OK; // Can also return
|
|
Packit |
47f805 |
// DRVCNF_CANCEL
|
|
Packit |
47f805 |
// and DRVCNF_RESTART
|
|
Packit |
47f805 |
} else {
|
|
Packit |
47f805 |
dwRes = DRVCNF_CANCEL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/**************************************
|
|
Packit |
47f805 |
// ACM additional messages
|
|
Packit |
47f805 |
***************************************/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_DRIVER_ABOUT:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_DRIVER_ABOUT");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwRes = About( (HWND) lParam1 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_DRIVER_DETAILS: // acmDriverDetails
|
|
Packit |
47f805 |
// Fill-in general informations about the driver/codec
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_DRIVER_DETAILS");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwRes = OnDriverDetails(hdrvr, (LPACMDRIVERDETAILS) lParam1);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_FORMATTAG_DETAILS: // acmFormatTagDetails
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMATTAG_DETAILS");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwRes = OnFormatTagDetails((LPACMFORMATTAGDETAILS) lParam1, lParam2);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_FORMAT_DETAILS: // acmFormatDetails
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMAT_DETAILS");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwRes = OnFormatDetails((LPACMFORMATDETAILS) lParam1, lParam2);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_FORMAT_SUGGEST: // acmFormatSuggest
|
|
Packit |
47f805 |
// Sent to determine if the driver can be
|
|
Packit |
47f805 |
// configured.
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMAT_SUGGEST");
|
|
Packit |
47f805 |
dwRes = OnFormatSuggest((LPACMDRVFORMATSUGGEST) lParam1);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/**************************************
|
|
Packit |
47f805 |
// ACM stream messages
|
|
Packit |
47f805 |
***************************************/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_OPEN:
|
|
Packit |
47f805 |
// Sent to determine if the driver can be
|
|
Packit |
47f805 |
// configured.
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_OPEN");
|
|
Packit |
47f805 |
dwRes = OnStreamOpen((LPACMDRVSTREAMINSTANCE) lParam1);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_SIZE:
|
|
Packit |
47f805 |
// returns a recommended size for a source
|
|
Packit |
47f805 |
// or destination buffer on an ACM stream
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_SIZE");
|
|
Packit |
47f805 |
dwRes = OnStreamSize((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMDRVSTREAMSIZE)lParam2);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_PREPARE:
|
|
Packit |
47f805 |
// prepares an ACMSTREAMHEADER structure for
|
|
Packit |
47f805 |
// an ACM stream conversion
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_PREPARE");
|
|
Packit |
47f805 |
dwRes = OnStreamPrepareHeader((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMSTREAMHEADER) lParam2);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_UNPREPARE:
|
|
Packit |
47f805 |
// cleans up the preparation performed by
|
|
Packit |
47f805 |
// the ACMDM_STREAM_PREPARE message for an ACM stream
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_UNPREPARE");
|
|
Packit |
47f805 |
dwRes = OnStreamUnPrepareHeader((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMSTREAMHEADER) lParam2);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_CONVERT:
|
|
Packit |
47f805 |
// perform a conversion on the specified conversion stream
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_CONVERT");
|
|
Packit |
47f805 |
dwRes = OnStreamConvert((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMDRVSTREAMHEADER) lParam2);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACMDM_STREAM_CLOSE:
|
|
Packit |
47f805 |
// closes an ACM conversion stream
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_CLOSE");
|
|
Packit |
47f805 |
dwRes = OnStreamClose((LPACMDRVSTREAMINSTANCE)lParam1);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/**************************************
|
|
Packit |
47f805 |
// Unknown message
|
|
Packit |
47f805 |
***************************************/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
// Process any other messages.
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_MSG, "ACM::DriverProc unknown message (0x%08X), lParam1 = 0x%08X, lParam2 = 0x%08X", msg, lParam1, lParam2);
|
|
Packit |
47f805 |
return DefDriverProc ((DWORD)this, hdrvr, msg, lParam1, lParam2);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return dwRes;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Special message handlers
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
Retreive the config details of this ACM driver
|
|
Packit |
47f805 |
The index represent the specified format
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
\param a_FormatDetails will be filled with all the corresponding data
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
inline DWORD ACM::OnFormatDetails(LPACMFORMATDETAILS a_FormatDetails, const LPARAM a_Query)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILS a_Query = 0x%08X",a_Query);
|
|
Packit |
47f805 |
switch (a_Query & ACM_FORMATDETAILSF_QUERYMASK) {
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Fill-in the informations corresponding to the FormatDetails->dwFormatTagIndex
|
|
Packit |
47f805 |
case ACM_FORMATDETAILSF_INDEX :
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "enter ACM_FORMATDETAILSF_INDEX for index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex);
|
|
Packit |
47f805 |
if (a_FormatDetails->dwFormatTag == PERSONAL_FORMAT) {
|
|
Packit |
47f805 |
if (a_FormatDetails->dwFormatIndex < GetNumberEncodingFormats()) {
|
|
Packit |
47f805 |
LPWAVEFORMATEX WaveExt;
|
|
Packit |
47f805 |
WaveExt = a_FormatDetails->pwfx;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
WaveExt->wFormatTag = PERSONAL_FORMAT;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format in : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec);
|
|
Packit |
47f805 |
GetMP3FormatForIndex(a_FormatDetails->dwFormatIndex, *WaveExt, a_FormatDetails->szFormat);
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format out : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec);
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILSF_INDEX unknown index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (a_FormatDetails->dwFormatTag == WAVE_FORMAT_PCM) {
|
|
Packit |
47f805 |
if (a_FormatDetails->dwFormatIndex < FORMAT_MAX_NB_PCM) {
|
|
Packit |
47f805 |
LPWAVEFORMATEX WaveExt;
|
|
Packit |
47f805 |
WaveExt = a_FormatDetails->pwfx;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
WaveExt->wFormatTag = WAVE_FORMAT_PCM;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format in : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec);
|
|
Packit |
47f805 |
GetPCMFormatForIndex(a_FormatDetails->dwFormatIndex, *WaveExt, a_FormatDetails->szFormat);
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format out : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec);
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILSF_INDEX unknown index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Unknown a_FormatDetails->dwFormatTag = 0x%08X",a_FormatDetails->dwFormatTag);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACM_FORMATDETAILSF_FORMAT :
|
|
Packit |
47f805 |
/// \todo we may output the corresponding strong (only for personal format)
|
|
Packit |
47f805 |
LPWAVEFORMATEX WaveExt;
|
|
Packit |
47f805 |
WaveExt = a_FormatDetails->pwfx;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "enter ACM_FORMATDETAILSF_FORMAT : 0x%04X:%03d, format in : channels %d, sample rate %d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex, WaveExt->nChannels, WaveExt->nSamplesPerSec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
a_FormatDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
Retreive the details of each known format by this ACM driver
|
|
Packit |
47f805 |
The index represent the specified format (0 = MP3 / 1 = PCM)
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
\param a_FormatTagDetails will be filled with all the corresponding data
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
inline DWORD ACM::OnFormatTagDetails(LPACMFORMATTAGDETAILS a_FormatTagDetails, const LPARAM a_Query)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result;
|
|
Packit |
47f805 |
DWORD the_format = WAVE_FORMAT_UNKNOWN; // the format to give details
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (a_FormatTagDetails->cbStruct >= sizeof(*a_FormatTagDetails)) {
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACMDM_FORMATTAG_DETAILS, a_Query = 0x%08X",a_Query);
|
|
Packit |
47f805 |
switch(a_Query & ACM_FORMATTAGDETAILSF_QUERYMASK) {
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACM_FORMATTAGDETAILSF_INDEX:
|
|
Packit |
47f805 |
// Fill-in the informations corresponding to the a_FormatDetails->dwFormatTagIndex
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "get ACM_FORMATTAGDETAILSF_INDEX for index %03d",a_FormatTagDetails->dwFormatTagIndex);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (a_FormatTagDetails->dwFormatTagIndex < FORMAT_TAG_MAX_NB) {
|
|
Packit |
47f805 |
switch (a_FormatTagDetails->dwFormatTagIndex)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case 0:
|
|
Packit |
47f805 |
the_format = PERSONAL_FORMAT;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default :
|
|
Packit |
47f805 |
the_format = WAVE_FORMAT_PCM;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATTAGDETAILSF_INDEX for unsupported index %03d",a_FormatTagDetails->dwFormatTagIndex);
|
|
Packit |
47f805 |
Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
|
Packit |
47f805 |
// Fill-in the informations corresponding to the a_FormatDetails->dwFormatTagIndex and hdrvr given
|
|
Packit |
47f805 |
switch (a_FormatTagDetails->dwFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case WAVE_FORMAT_PCM:
|
|
Packit |
47f805 |
the_format = WAVE_FORMAT_PCM;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case PERSONAL_FORMAT:
|
|
Packit |
47f805 |
the_format = PERSONAL_FORMAT;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "get ACM_FORMATTAGDETAILSF_FORMATTAG for index 0x%02X, cStandardFormats = %d",a_FormatTagDetails->dwFormatTagIndex,a_FormatTagDetails->cStandardFormats);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATTAGDETAILSF_LARGESTSIZE not used");
|
|
Packit |
47f805 |
Result = 0L;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails Unknown Format tag query");
|
|
Packit |
47f805 |
Result = MMSYSERR_NOTSUPPORTED;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails the_format = 0x%08X",the_format);
|
|
Packit |
47f805 |
switch(the_format)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case WAVE_FORMAT_PCM:
|
|
Packit |
47f805 |
a_FormatTagDetails->dwFormatTag = WAVE_FORMAT_PCM;
|
|
Packit |
47f805 |
a_FormatTagDetails->dwFormatTagIndex = 0;
|
|
Packit |
47f805 |
a_FormatTagDetails->cbFormatSize = sizeof(PCMWAVEFORMAT);
|
|
Packit |
47f805 |
/// \note 0 may mean we don't know how to decode
|
|
Packit |
47f805 |
a_FormatTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
|
Packit |
47f805 |
a_FormatTagDetails->cStandardFormats = FORMAT_MAX_NB_PCM;
|
|
Packit |
47f805 |
// should be filled by Windows a_FormatTagDetails->szFormatTag[0] = '\0';
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case PERSONAL_FORMAT:
|
|
Packit |
47f805 |
a_FormatTagDetails->dwFormatTag = PERSONAL_FORMAT;
|
|
Packit |
47f805 |
a_FormatTagDetails->dwFormatTagIndex = 1;
|
|
Packit |
47f805 |
a_FormatTagDetails->cbFormatSize = SIZE_FORMAT_STRUCT;
|
|
Packit |
47f805 |
a_FormatTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
|
Packit |
47f805 |
a_FormatTagDetails->cStandardFormats = GetNumberEncodingFormats();
|
|
Packit |
47f805 |
lstrcpyW( a_FormatTagDetails->szFormatTag, L"Lame MP3" );
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails Unknown format 0x%08X",the_format);
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails %d possibilities for format 0x%08X",a_FormatTagDetails->cStandardFormats,the_format);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "a_FormatTagDetails->cbStruct < sizeof(*a_FormatDetails)");
|
|
Packit |
47f805 |
Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
Retreive the global details of this ACM driver
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
\param a_DriverDetail will be filled with all the corresponding data
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
inline DWORD ACM::OnDriverDetails(const HDRVR hdrvr, LPACMDRIVERDETAILS a_DriverDetail)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (my_hIcon == NULL)
|
|
Packit |
47f805 |
my_hIcon = LoadIcon(GetDriverModuleHandle(hdrvr), MAKEINTRESOURCE(IDI_ICON));
|
|
Packit |
47f805 |
a_DriverDetail->hicon = my_hIcon;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
a_DriverDetail->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
|
Packit |
47f805 |
a_DriverDetail->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \note this is an explicit hack of the FhG values
|
|
Packit |
47f805 |
/// \note later it could be a new value when the decoding is done
|
|
Packit |
47f805 |
a_DriverDetail->wMid = MM_FRAUNHOFER_IIS;
|
|
Packit |
47f805 |
a_DriverDetail->wPid = MM_FHGIIS_MPEGLAYER3;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
a_DriverDetail->vdwACM = VERSION_MSACM;
|
|
Packit |
47f805 |
a_DriverDetail->vdwDriver = VERSION_ACM_DRIVER;
|
|
Packit |
47f805 |
a_DriverDetail->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
|
Packit |
47f805 |
a_DriverDetail->cFormatTags = FORMAT_TAG_MAX_NB; // 2 : MP3 and PCM
|
|
Packit |
47f805 |
// a_DriverDetail->cFormatTags = 1; // 2 : MP3 and PCM
|
|
Packit |
47f805 |
a_DriverDetail->cFilterTags = FILTER_TAG_MAX_NB;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
lstrcpyW( a_DriverDetail->szShortName, L"LAME MP3" );
|
|
Packit |
47f805 |
char tmpStr[128];
|
|
Packit |
47f805 |
wsprintf(tmpStr, "LAME MP3 Codec v%s", GetVersionString());
|
|
Packit |
47f805 |
int u = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, tmpStr, -1, a_DriverDetail->szLongName, 0);
|
|
Packit |
47f805 |
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, tmpStr, -1, a_DriverDetail->szLongName, u);
|
|
Packit |
47f805 |
lstrcpyW( a_DriverDetail->szCopyright, L"2002 Steve Lhomme" );
|
|
Packit |
47f805 |
lstrcpyW( a_DriverDetail->szLicensing, L"LGPL (see gnu.org)" );
|
|
Packit |
47f805 |
/// \todo update this part when the code changes
|
|
Packit |
47f805 |
lstrcpyW( a_DriverDetail->szFeatures , L"only CBR implementation" );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return MMSYSERR_NOERROR; // Can also return DRVCNF_CANCEL
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
Suggest an output format for the specified input format
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
\param a_FormatSuggest will be filled with all the corresponding data
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
inline DWORD ACM::OnFormatSuggest(LPACMDRVFORMATSUGGEST a_FormatSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = MMSYSERR_NOTSUPPORTED;
|
|
Packit |
47f805 |
DWORD fdwSuggest = (ACM_FORMATSUGGESTF_TYPEMASK & a_FormatSuggest->fdwSuggest);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest %s%s%s%s (0x%08X)",
|
|
Packit |
47f805 |
(fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS) ? "channels, ":"",
|
|
Packit |
47f805 |
(fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC) ? "samples/sec, ":"",
|
|
Packit |
47f805 |
(fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE) ? "bits/sample, ":"",
|
|
Packit |
47f805 |
(fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) ? "format, ":"",
|
|
Packit |
47f805 |
fdwSuggest);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for source format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d",
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->wFormatTag,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->nChannels,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->nSamplesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->nAvgBytesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->nBlockAlign,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxSrc->wBitsPerSample);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggested destination format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d",
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wFormatTag,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nChannels,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nSamplesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nAvgBytesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nBlockAlign,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wBitsPerSample);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (a_FormatSuggest->pwfxSrc->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case WAVE_FORMAT_PCM:
|
|
Packit |
47f805 |
/// \todo handle here the decoding ?
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PCM source");
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination format tag is restricted, verify that
|
|
Packit |
47f805 |
// it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is able to decode to PCM
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (PERSONAL_FORMAT != a_FormatSuggest->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wFormatTag = PERSONAL_FORMAT;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed A");
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination channel count is restricted, verify that
|
|
Packit |
47f805 |
// it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is not able to change the number of channels
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (a_FormatSuggest->pwfxSrc->nChannels != 1 && a_FormatSuggest->pwfxSrc->nChannels != 2)
|
|
Packit |
47f805 |
return MMSYSERR_INVALPARAM;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed B");
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination samples per second is restricted, verify
|
|
Packit |
47f805 |
// that it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is not able to change the sample rate
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed C");
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination bits per sample is restricted, verify
|
|
Packit |
47f805 |
// that it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// We prefer decoding to 16-bit PCM.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) )
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wBitsPerSample = 16;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN;
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nChannels * 64000 / 8;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed");
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case PERSONAL_FORMAT:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PERSONAL source");
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination format tag is restricted, verify that
|
|
Packit |
47f805 |
// it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is able to decode to PCM
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM != a_FormatSuggest->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination channel count is restricted, verify that
|
|
Packit |
47f805 |
// it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is not able to change the number of channels
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination samples per second is restricted, verify
|
|
Packit |
47f805 |
// that it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver is not able to change the sample rate
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec)
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// if the destination bits per sample is restricted, verify
|
|
Packit |
47f805 |
// that it is within our capabilities...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// We prefer decoding to 16-bit PCM.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) )
|
|
Packit |
47f805 |
return (ACMERR_NOTPOSSIBLE);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wBitsPerSample = 16;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN;
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo this value must be a correct one !
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nSamplesPerSec * a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed");
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggested destination format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d",
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wFormatTag,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nChannels,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nSamplesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nAvgBytesPerSec,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->nBlockAlign,
|
|
Packit |
47f805 |
a_FormatSuggest->pwfxDst->wBitsPerSample);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*!
|
|
Packit |
47f805 |
Create a stream instance for decoding/encoding
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
\param a_StreamInstance contain information about the stream desired
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamOpen(LPACMDRVSTREAMINSTANCE a_StreamInstance)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// the most important condition to check before doing anything else
|
|
Packit |
47f805 |
// is that this ACM driver can actually perform the conversion we are
|
|
Packit |
47f805 |
// being opened for. this check should fail as quickly as possible
|
|
Packit |
47f805 |
// if the conversion is not possible by this driver.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// it is VERY important to fail quickly so the ACM can attempt to
|
|
Packit |
47f805 |
// find a driver that is suitable for the conversion. also note that
|
|
Packit |
47f805 |
// the ACM may call this driver several times with slightly different
|
|
Packit |
47f805 |
// format specifications before giving up.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// this driver first verifies that the source and destination formats
|
|
Packit |
47f805 |
// are acceptable...
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
switch (a_StreamInstance->pwfxSrc->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case WAVE_FORMAT_PCM:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PCM source (%05d samples %d channels %d bits/sample)",a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxSrc->nChannels,a_StreamInstance->pwfxSrc->wBitsPerSample);
|
|
Packit |
47f805 |
if (a_StreamInstance->pwfxDst->wFormatTag == PERSONAL_FORMAT)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
unsigned int OutputFrequency;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo Smart mode
|
|
Packit |
47f805 |
if (my_EncodingProperties.GetSmartOutputMode())
|
|
Packit |
47f805 |
OutputFrequency = ACMStream::GetOutputSampleRate(a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxDst->nAvgBytesPerSec,a_StreamInstance->pwfxDst->nChannels);
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
OutputFrequency = a_StreamInstance->pwfxSrc->nSamplesPerSec;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PERSONAL output (%05d samples %d channels %d bits/sample %d kbps)",a_StreamInstance->pwfxDst->nSamplesPerSec,a_StreamInstance->pwfxDst->nChannels,a_StreamInstance->pwfxDst->wBitsPerSample,8 * a_StreamInstance->pwfxDst->nAvgBytesPerSec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo add the possibility to have channel resampling (mono to stereo / stereo to mono)
|
|
Packit |
47f805 |
/// \todo support resampling ?
|
|
Packit |
47f805 |
/// \todo only do the test on OutputFrequency in "Smart Output" mode
|
|
Packit |
47f805 |
if (a_StreamInstance->pwfxDst->nSamplesPerSec != OutputFrequency ||
|
|
Packit |
47f805 |
// a_StreamInstance->pwfxSrc->nSamplesPerSec != a_StreamInstance->pwfxDst->nSamplesPerSec ||
|
|
Packit |
47f805 |
a_StreamInstance->pwfxSrc->nChannels != a_StreamInstance->pwfxDst->nChannels ||
|
|
Packit |
47f805 |
a_StreamInstance->pwfxSrc->wBitsPerSample != 16)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
} else {
|
|
Packit |
47f805 |
if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ACMStream * the_stream = ACMStream::Create();
|
|
Packit |
47f805 |
a_StreamInstance->dwInstance = (DWORD) the_stream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEGLAYER3WAVEFORMAT * casted = (MPEGLAYER3WAVEFORMAT *) a_StreamInstance->pwfxDst;
|
|
Packit |
47f805 |
vbr_mode a_mode = (casted->fdwFlags-2 == 0)?vbr_abr:vbr_off;
|
|
Packit |
47f805 |
if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec,
|
|
Packit |
47f805 |
OutputFrequency,
|
|
Packit |
47f805 |
a_StreamInstance->pwfxDst->nChannels,
|
|
Packit |
47f805 |
a_StreamInstance->pwfxDst->nAvgBytesPerSec,
|
|
Packit |
47f805 |
a_mode))
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
ACMStream::Erase( the_stream );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case PERSONAL_FORMAT:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PERSONAL source (%05d samples %d channels %d bits/sample %d kbps)",a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxSrc->nChannels,a_StreamInstance->pwfxSrc->wBitsPerSample,8 * a_StreamInstance->pwfxSrc->nAvgBytesPerSec);
|
|
Packit |
47f805 |
if (a_StreamInstance->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/// \todo create the decoding stream
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream for PCM output (%05d samples %d channels %d bits/sample %d B/s)",a_StreamInstance->pwfxDst->nSamplesPerSec,a_StreamInstance->pwfxDst->nChannels,a_StreamInstance->pwfxDst->wBitsPerSample,a_StreamInstance->pwfxDst->nAvgBytesPerSec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DecodeStream * the_stream = DecodeStream::Create();
|
|
Packit |
47f805 |
a_StreamInstance->dwInstance = (DWORD) the_stream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec,
|
|
Packit |
47f805 |
a_StreamInstance->pwfxDst->nChannels,
|
|
Packit |
47f805 |
a_StreamInstance->pwfxDst->nAvgBytesPerSec,
|
|
Packit |
47f805 |
a_StreamInstance->pwfxSrc->nAvgBytesPerSec))
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
DecodeStream::Erase( the_stream );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/// \todo decoding verification
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream is valid");
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream Result = %d",Result);
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamSize(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMDRVSTREAMSIZE the_StreamSize)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (ACM_STREAMSIZEF_QUERYMASK & the_StreamSize->fdwSize)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case ACM_STREAMSIZEF_DESTINATION:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get source buffer size for destination size = %d",the_StreamSize->cbDstLength);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case ACM_STREAMSIZEF_SOURCE:
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get destination buffer size for source size = %d",the_StreamSize->cbSrcLength);
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ACMStream * the_stream = (ACMStream *) a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
the_StreamSize->cbDstLength = the_stream->GetOutputSizeForInput(the_StreamSize->cbSrcLength);
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
DecodeStream * the_stream = (DecodeStream *) a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
the_StreamSize->cbDstLength = the_stream->GetOutputSizeForInput(the_StreamSize->cbSrcLength);
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
Result = MMSYSERR_INVALFLAG;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamClose(LPACMDRVSTREAMINSTANCE a_StreamInstance)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamClose the stream 0x%X",a_StreamInstance->dwInstance);
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ACMStream::Erase( (ACMStream *) a_StreamInstance->dwInstance );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
DecodeStream::Erase( (DecodeStream *) a_StreamInstance->dwInstance );
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// nothing to do yet
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamPrepareHeader(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMSTREAMHEADER a_StreamHeader)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, " prepare : Src : %d (0x%08X) / %d - Dst : %d (0x%08X) / %d"
|
|
Packit |
47f805 |
, a_StreamHeader->cbSrcLength
|
|
Packit |
47f805 |
, a_StreamHeader->pbSrc
|
|
Packit |
47f805 |
, a_StreamHeader->cbSrcLengthUsed
|
|
Packit |
47f805 |
, a_StreamHeader->cbDstLength
|
|
Packit |
47f805 |
, a_StreamHeader->pbDst
|
|
Packit |
47f805 |
, a_StreamHeader->cbDstLengthUsed
|
|
Packit |
47f805 |
);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ACMStream * the_stream = (ACMStream *)a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream->open(my_EncodingProperties))
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
WAVE_FORMAT_PCM == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
DecodeStream * the_stream = (DecodeStream *)a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream->open())
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamUnPrepareHeader(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMSTREAMHEADER a_StreamHeader)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "unprepare : Src : %d / %d - Dst : %d / %d"
|
|
Packit |
47f805 |
, a_StreamHeader->cbSrcLength
|
|
Packit |
47f805 |
, a_StreamHeader->cbSrcLengthUsed
|
|
Packit |
47f805 |
, a_StreamHeader->cbDstLength
|
|
Packit |
47f805 |
, a_StreamHeader->cbDstLengthUsed
|
|
Packit |
47f805 |
);
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ACMStream * the_stream = (ACMStream *)a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
DWORD OutputSize = a_StreamHeader->cbDstLength;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream->close(a_StreamHeader->pbDst, &OutputSize) && (OutputSize <= a_StreamHeader->cbDstLength))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_StreamHeader->cbDstLengthUsed = OutputSize;
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
DecodeStream * the_stream = (DecodeStream *)a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
DWORD OutputSize = a_StreamHeader->cbDstLength;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_stream->close(a_StreamHeader->pbDst, &OutputSize) && (OutputSize <= a_StreamHeader->cbDstLength))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_StreamHeader->cbDstLengthUsed = OutputSize;
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
inline DWORD ACM::OnStreamConvert(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMDRVSTREAMHEADER a_StreamHeader)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DWORD Result = ACMERR_NOTPOSSIBLE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert SRC = PCM (encode)");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ACMStream * the_stream = (ACMStream *) a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (the_stream->ConvertBuffer( a_StreamHeader ))
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag &&
|
|
Packit |
47f805 |
WAVE_FORMAT_PCM == a_StreamInstance->pwfxDst->wFormatTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert SRC = MP3 (decode)");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef ENABLE_DECODING
|
|
Packit |
47f805 |
DecodeStream * the_stream = (DecodeStream *) a_StreamInstance->dwInstance;
|
|
Packit |
47f805 |
if (the_stream != NULL)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (the_stream->ConvertBuffer( a_StreamHeader ))
|
|
Packit |
47f805 |
Result = MMSYSERR_NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
#endif // ENABLE_DECODING
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert unsupported conversion");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return Result;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void ACM::GetMP3FormatForIndex(const DWORD the_Index, WAVEFORMATEX & the_Format, unsigned short the_String[ACMFORMATDETAILS_FORMAT_CHARS]) const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int Block_size;
|
|
Packit |
47f805 |
char temp[ACMFORMATDETAILS_FORMAT_CHARS];
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (the_Index < bitrate_table.size())
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// the_Format.wBitsPerSample = 16;
|
|
Packit |
47f805 |
the_Format.wBitsPerSample = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo handle more channel modes (mono, stereo, joint-stereo, dual-channel)
|
|
Packit |
47f805 |
// the_Format.nChannels = SIZE_CHANNEL_MODE - int(the_Index % SIZE_CHANNEL_MODE);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
the_Format.nBlockAlign = 1;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
the_Format.nSamplesPerSec = bitrate_table[the_Index].frequency;
|
|
Packit |
47f805 |
the_Format.nAvgBytesPerSec = bitrate_table[the_Index].bitrate * 1000 / 8;
|
|
Packit |
47f805 |
if (bitrate_table[the_Index].frequency >= mpeg1_freq[SIZE_FREQ_MPEG1-1])
|
|
Packit |
47f805 |
Block_size = 1152;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
Block_size = 576;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
the_Format.nChannels = bitrate_table[the_Index].channels;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
the_Format.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);
|
|
Packit |
47f805 |
MPEGLAYER3WAVEFORMAT * tmpFormat = (MPEGLAYER3WAVEFORMAT *) &the_Format;
|
|
Packit |
47f805 |
tmpFormat->wID = 1;
|
|
Packit |
47f805 |
// this is the only way I found to know if we do CBR or ABR
|
|
Packit |
47f805 |
tmpFormat->fdwFlags = 2 + ((bitrate_table[the_Index].mode == vbr_abr)?0:2);
|
|
Packit |
47f805 |
tmpFormat->nBlockSize = Block_size * the_Format.nAvgBytesPerSec / the_Format.nSamplesPerSec;
|
|
Packit |
47f805 |
tmpFormat->nFramesPerBlock = 1;
|
|
Packit |
47f805 |
tmpFormat->nCodecDelay = 0; // 0x0571 on FHG
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/// \todo : generate the string with the appropriate stereo mode
|
|
Packit |
47f805 |
if (bitrate_table[the_Index].mode == vbr_abr)
|
|
Packit |
47f805 |
wsprintfA( temp, "%d Hz, %d kbps ABR, %s", the_Format.nSamplesPerSec, the_Format.nAvgBytesPerSec * 8 / 1000, (the_Format.nChannels == 1)?"Mono":"Stereo");
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
wsprintfA( temp, "%d Hz, %d kbps CBR, %s", the_Format.nSamplesPerSec, the_Format.nAvgBytesPerSec * 8 / 1000, (the_Format.nChannels == 1)?"Mono":"Stereo");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, the_String, ACMFORMATDETAILS_FORMAT_CHARS);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void ACM::GetPCMFormatForIndex(const DWORD the_Index, WAVEFORMATEX & the_Format, unsigned short the_String[ACMFORMATDETAILS_FORMAT_CHARS]) const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
the_Format.nChannels = SIZE_CHANNEL_MODE - int(the_Index % SIZE_CHANNEL_MODE);
|
|
Packit |
47f805 |
the_Format.wBitsPerSample = 16;
|
|
Packit |
47f805 |
the_Format.nBlockAlign = the_Format.nChannels * the_Format.wBitsPerSample / 8;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DWORD a_Channel_Independent = the_Index / SIZE_CHANNEL_MODE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// first MPEG1 frequencies
|
|
Packit |
47f805 |
if (a_Channel_Independent < SIZE_FREQ_MPEG1)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
the_Format.nSamplesPerSec = mpeg1_freq[a_Channel_Independent];
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
a_Channel_Independent -= SIZE_FREQ_MPEG1;
|
|
Packit |
47f805 |
the_Format.nSamplesPerSec = mpeg2_freq[a_Channel_Independent];
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
the_Format.nAvgBytesPerSec = the_Format.nSamplesPerSec * the_Format.nChannels * the_Format.wBitsPerSample / 8;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DWORD ACM::GetNumberEncodingFormats() const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return bitrate_table.size();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bool ACM::IsSmartOutput(const int frequency, const int bitrate, const int channels) const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
double compression_ratio = double(frequency * 2 * channels) / double(bitrate * 100);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//my_debug.OutPut(DEBUG_LEVEL_FUNC_DEBUG, "compression_ratio %f, freq %d, bitrate %d, channels %d", compression_ratio, frequency, bitrate, channels);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(my_EncodingProperties.GetSmartOutputMode())
|
|
Packit |
47f805 |
return (compression_ratio <= my_EncodingProperties.GetSmartRatio());
|
|
Packit |
47f805 |
else return true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void ACM::BuildBitrateTable()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut("entering BuildBitrateTable");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// fill the table
|
|
Packit |
47f805 |
unsigned int channel,bitrate,freq;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table.clear();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// CBR bitrates
|
|
Packit |
47f805 |
for (channel = 0;channel < SIZE_CHANNEL_MODE;channel++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// MPEG I
|
|
Packit |
47f805 |
for (freq = 0;freq < SIZE_FREQ_MPEG1;freq++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for (bitrate = 0;bitrate < SIZE_BITRATE_MPEG1;bitrate++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg1_freq[freq], mpeg1_bitrate[bitrate], channel+1))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
bitrate_item bitrate_table_tmp;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table_tmp.frequency = mpeg1_freq[freq];
|
|
Packit |
47f805 |
bitrate_table_tmp.bitrate = mpeg1_bitrate[bitrate];
|
|
Packit |
47f805 |
bitrate_table_tmp.channels = channel+1;
|
|
Packit |
47f805 |
bitrate_table_tmp.mode = vbr_off;
|
|
Packit |
47f805 |
bitrate_table.push_back(bitrate_table_tmp);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// MPEG II / II.5
|
|
Packit |
47f805 |
for (freq = 0;freq < SIZE_FREQ_MPEG2;freq++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for (bitrate = 0;bitrate < SIZE_BITRATE_MPEG2;bitrate++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg2_freq[freq], mpeg2_bitrate[bitrate], channel+1))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
bitrate_item bitrate_table_tmp;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table_tmp.frequency = mpeg2_freq[freq];
|
|
Packit |
47f805 |
bitrate_table_tmp.bitrate = mpeg2_bitrate[bitrate];
|
|
Packit |
47f805 |
bitrate_table_tmp.channels = channel+1;
|
|
Packit |
47f805 |
bitrate_table_tmp.mode = vbr_abr;
|
|
Packit |
47f805 |
bitrate_table.push_back(bitrate_table_tmp);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (my_EncodingProperties.GetAbrOutputMode())
|
|
Packit |
47f805 |
// ABR bitrates
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for (channel = 0;channel < SIZE_CHANNEL_MODE;channel++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// MPEG I
|
|
Packit |
47f805 |
for (freq = 0;freq < SIZE_FREQ_MPEG1;freq++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for (bitrate = my_EncodingProperties.GetAbrBitrateMax();
|
|
Packit |
47f805 |
bitrate >= my_EncodingProperties.GetAbrBitrateMin();
|
|
Packit |
47f805 |
bitrate -= my_EncodingProperties.GetAbrBitrateStep())
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (bitrate >= mpeg1_bitrate[SIZE_BITRATE_MPEG1-1] && (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg1_freq[freq], bitrate, channel+1)))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
bitrate_item bitrate_table_tmp;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table_tmp.frequency = mpeg1_freq[freq];
|
|
Packit |
47f805 |
bitrate_table_tmp.bitrate = bitrate;
|
|
Packit |
47f805 |
bitrate_table_tmp.channels = channel+1;
|
|
Packit |
47f805 |
bitrate_table_tmp.mode = vbr_abr;
|
|
Packit |
47f805 |
bitrate_table.push_back(bitrate_table_tmp);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// MPEG II / II.5
|
|
Packit |
47f805 |
for (freq = 0;freq < SIZE_FREQ_MPEG2;freq++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for (bitrate = my_EncodingProperties.GetAbrBitrateMax();
|
|
Packit |
47f805 |
bitrate >= my_EncodingProperties.GetAbrBitrateMin();
|
|
Packit |
47f805 |
bitrate -= my_EncodingProperties.GetAbrBitrateStep())
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (bitrate >= mpeg2_bitrate[SIZE_BITRATE_MPEG2-1] && (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg2_freq[freq], bitrate, channel+1)))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
bitrate_item bitrate_table_tmp;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bitrate_table_tmp.frequency = mpeg2_freq[freq];
|
|
Packit |
47f805 |
bitrate_table_tmp.bitrate = bitrate;
|
|
Packit |
47f805 |
bitrate_table_tmp.channels = channel+1;
|
|
Packit |
47f805 |
bitrate_table_tmp.mode = vbr_abr;
|
|
Packit |
47f805 |
bitrate_table.push_back(bitrate_table_tmp);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// sorting by frequency/bitrate/channel
|
|
Packit |
47f805 |
std::sort(bitrate_table.begin(), bitrate_table.end());
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* {
|
|
Packit |
47f805 |
// display test
|
|
Packit |
47f805 |
int i=0;
|
|
Packit |
47f805 |
for (i=0; i
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
my_debug.OutPut("bitrate_table[%d].frequency = %d",i,bitrate_table[i].frequency);
|
|
Packit |
47f805 |
my_debug.OutPut("bitrate_table[%d].bitrate = %d",i,bitrate_table[i].bitrate);
|
|
Packit |
47f805 |
my_debug.OutPut("bitrate_table[%d].channel = %d",i,bitrate_table[i].channels);
|
|
Packit |
47f805 |
my_debug.OutPut("bitrate_table[%d].ABR = %s\n",i,(bitrate_table[i].mode == vbr_abr)?"ABR":"CBR");
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
my_debug.OutPut("leaving BuildBitrateTable");
|
|
Packit |
47f805 |
}
|