1159b3361Sopenharmony_ci/** 2159b3361Sopenharmony_ci * 3159b3361Sopenharmony_ci * Lame ACM wrapper, encode/decode MP3 based RIFF/AVI files in MS Windows 4159b3361Sopenharmony_ci * 5159b3361Sopenharmony_ci * Copyright (c) 2002 Steve Lhomme <steve.lhomme at free.fr> 6159b3361Sopenharmony_ci * 7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or 8159b3361Sopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either 10159b3361Sopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11159b3361Sopenharmony_ci * 12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful, 13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15159b3361Sopenharmony_ci * Lesser General Public License for more details. 16159b3361Sopenharmony_ci * 17159b3361Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18159b3361Sopenharmony_ci * License along with this library; if not, write to the Free Software 19159b3361Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20159b3361Sopenharmony_ci * 21159b3361Sopenharmony_ci */ 22159b3361Sopenharmony_ci 23159b3361Sopenharmony_ci/*! 24159b3361Sopenharmony_ci \author Steve Lhomme 25159b3361Sopenharmony_ci \version \$Id$ 26159b3361Sopenharmony_ci*/ 27159b3361Sopenharmony_ci 28159b3361Sopenharmony_ci#if !defined(STRICT) 29159b3361Sopenharmony_ci#define STRICT 30159b3361Sopenharmony_ci#endif // STRICT 31159b3361Sopenharmony_ci 32159b3361Sopenharmony_ci#include <algorithm> 33159b3361Sopenharmony_ci 34159b3361Sopenharmony_ci#include <windows.h> 35159b3361Sopenharmony_ci#include <windowsx.h> 36159b3361Sopenharmony_ci#include <intshcut.h> 37159b3361Sopenharmony_ci 38159b3361Sopenharmony_ci#include <mmreg.h> 39159b3361Sopenharmony_ci#include <msacm.h> 40159b3361Sopenharmony_ci#include <msacmdrv.h> 41159b3361Sopenharmony_ci 42159b3361Sopenharmony_ci#include <assert.h> 43159b3361Sopenharmony_ci 44159b3361Sopenharmony_ci#include <lame.h> 45159b3361Sopenharmony_ci 46159b3361Sopenharmony_ci#include "adebug.h" 47159b3361Sopenharmony_ci#include "resource.h" 48159b3361Sopenharmony_ci#include "ACMStream.h" 49159b3361Sopenharmony_ci 50159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 51159b3361Sopenharmony_ci#include "DecodeStream.h" 52159b3361Sopenharmony_ci#endif // ENABLE_DECODING 53159b3361Sopenharmony_ci 54159b3361Sopenharmony_ci#include "ACM.h" 55159b3361Sopenharmony_ci 56159b3361Sopenharmony_ci#ifndef IDC_HAND 57159b3361Sopenharmony_ci#define IDC_HAND MAKEINTRESOURCE(32649) 58159b3361Sopenharmony_ci#endif // IDC_HAND 59159b3361Sopenharmony_ci 60159b3361Sopenharmony_cichar ACM::VersionString[120]; 61159b3361Sopenharmony_ci 62159b3361Sopenharmony_ciconst char ACM_VERSION[] = "0.9.2"; 63159b3361Sopenharmony_ci 64159b3361Sopenharmony_ci#ifdef WIN32 65159b3361Sopenharmony_ci// 66159b3361Sopenharmony_ci// 32-bit versions 67159b3361Sopenharmony_ci// 68159b3361Sopenharmony_ci#if (WINVER >= 0x0400) 69159b3361Sopenharmony_ci #define VERSION_ACM_DRIVER MAKE_ACM_VERSION(4, 0, 0) 70159b3361Sopenharmony_ci#else 71159b3361Sopenharmony_ci#define VERSION_ACM_DRIVER MAKE_ACM_VERSION(3, 51, 0) 72159b3361Sopenharmony_ci#endif 73159b3361Sopenharmony_ci#define VERSION_MSACM MAKE_ACM_VERSION(3, 50, 0) 74159b3361Sopenharmony_ci 75159b3361Sopenharmony_ci#else 76159b3361Sopenharmony_ci// 77159b3361Sopenharmony_ci// 16-bit versions 78159b3361Sopenharmony_ci// 79159b3361Sopenharmony_ci#define VERSION_ACM_DRIVER MAKE_ACM_VERSION(1, 0, 0) 80159b3361Sopenharmony_ci#define VERSION_MSACM MAKE_ACM_VERSION(2, 1, 0) 81159b3361Sopenharmony_ci 82159b3361Sopenharmony_ci#endif 83159b3361Sopenharmony_ci 84159b3361Sopenharmony_ci#define PERSONAL_FORMAT WAVE_FORMAT_MPEGLAYER3 85159b3361Sopenharmony_ci#define SIZE_FORMAT_STRUCT sizeof(MPEGLAYER3WAVEFORMAT) 86159b3361Sopenharmony_ci//#define SIZE_FORMAT_STRUCT 0 87159b3361Sopenharmony_ci 88159b3361Sopenharmony_ci//static const char channel_mode[][13] = {"mono","stereo","joint stereo","dual channel"}; 89159b3361Sopenharmony_cistatic const char channel_mode[][13] = {"mono","stereo"}; 90159b3361Sopenharmony_cistatic const unsigned int mpeg1_freq[] = {48000,44100,32000}; 91159b3361Sopenharmony_cistatic const unsigned int mpeg2_freq[] = {24000,22050,16000,12000,11025,8000}; 92159b3361Sopenharmony_cistatic const unsigned int mpeg1_bitrate[] = {320, 256, 224, 192, 160, 128, 112, 96, 80, 64, 56, 48, 40, 32}; 93159b3361Sopenharmony_cistatic const unsigned int mpeg2_bitrate[] = {160, 144, 128, 112, 96, 80, 64, 56, 48, 40, 32, 24, 16, 8}; 94159b3361Sopenharmony_ci 95159b3361Sopenharmony_ci#define SIZE_CHANNEL_MODE (sizeof(channel_mode) / (sizeof(char) * 13)) 96159b3361Sopenharmony_ci#define SIZE_FREQ_MPEG1 (sizeof(mpeg1_freq) / sizeof(unsigned int)) 97159b3361Sopenharmony_ci#define SIZE_FREQ_MPEG2 (sizeof(mpeg2_freq) / sizeof(unsigned int)) 98159b3361Sopenharmony_ci#define SIZE_BITRATE_MPEG1 (sizeof(mpeg1_bitrate) / sizeof(unsigned int)) 99159b3361Sopenharmony_ci#define SIZE_BITRATE_MPEG2 (sizeof(mpeg2_bitrate) / sizeof(unsigned int)) 100159b3361Sopenharmony_ci 101159b3361Sopenharmony_cistatic const int FORMAT_TAG_MAX_NB = 2; // PCM and PERSONAL (mandatory to have at least PCM and your format) 102159b3361Sopenharmony_cistatic const int FILTER_TAG_MAX_NB = 0; // this is a codec, not a filter 103159b3361Sopenharmony_ci 104159b3361Sopenharmony_ci// number of supported PCM formats 105159b3361Sopenharmony_cistatic const int FORMAT_MAX_NB_PCM = 106159b3361Sopenharmony_ci 2 * // number of PCM channel mode (stereo/mono) 107159b3361Sopenharmony_ci (SIZE_FREQ_MPEG1 + // number of MPEG 1 sampling freq 108159b3361Sopenharmony_ci SIZE_FREQ_MPEG2); // number of MPEG 2 sampling freq 109159b3361Sopenharmony_ci 110159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 111159b3361Sopenharmony_ci// 112159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 113159b3361Sopenharmony_cibool bitrate_item::operator<(const bitrate_item & other_bitrate) const 114159b3361Sopenharmony_ci{ 115159b3361Sopenharmony_ci return (other_bitrate.frequency < frequency || 116159b3361Sopenharmony_ci (other_bitrate.frequency == frequency && 117159b3361Sopenharmony_ci (other_bitrate.bitrate < bitrate || 118159b3361Sopenharmony_ci (other_bitrate.bitrate == bitrate && 119159b3361Sopenharmony_ci (other_bitrate.channels < channels))))); 120159b3361Sopenharmony_ci} 121159b3361Sopenharmony_ci 122159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 123159b3361Sopenharmony_ci// Configuration Dialog 124159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 125159b3361Sopenharmony_ci/* 126159b3361Sopenharmony_cistatic CALLBACK ConfigProc( 127159b3361Sopenharmony_ci HWND hwndDlg, // handle to dialog box 128159b3361Sopenharmony_ciUINT uMsg, // message 129159b3361Sopenharmony_ciWPARAM wParam, // first message parameter 130159b3361Sopenharmony_ciLPARAM lParam // second message parameter 131159b3361Sopenharmony_ci) 132159b3361Sopenharmony_ci{ 133159b3361Sopenharmony_ci BOOL bResult; 134159b3361Sopenharmony_ci 135159b3361Sopenharmony_ci switch (uMsg) { 136159b3361Sopenharmony_ci case WM_COMMAND: 137159b3361Sopenharmony_ci UINT command; 138159b3361Sopenharmony_ci command = GET_WM_COMMAND_ID(wParam, lParam); 139159b3361Sopenharmony_ci if (IDOK == command) 140159b3361Sopenharmony_ci { 141159b3361Sopenharmony_ci EndDialog(hwndDlg, (IDOK == command)); 142159b3361Sopenharmony_ci } else if (IDCANCEL == command) 143159b3361Sopenharmony_ci { 144159b3361Sopenharmony_ci EndDialog(hwndDlg, (IDOK == command)); 145159b3361Sopenharmony_ci } 146159b3361Sopenharmony_ci bResult = FALSE; 147159b3361Sopenharmony_ci break; 148159b3361Sopenharmony_ci default: 149159b3361Sopenharmony_ci bResult = FALSE; // will be treated by DefWindowProc 150159b3361Sopenharmony_ci} 151159b3361Sopenharmony_ci return bResult; 152159b3361Sopenharmony_ci} 153159b3361Sopenharmony_ci 154159b3361Sopenharmony_ci 155159b3361Sopenharmony_ciinline DWORD ACM::Configure(HWND hParentWindow, LPDRVCONFIGINFO pConfig) 156159b3361Sopenharmony_ci{ 157159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM : Configure (Parent Window = 0x%08X)",hParentWindow); 158159b3361Sopenharmony_ci 159159b3361Sopenharmony_ci DialogBoxParam( my_hModule, MAKEINTRESOURCE(IDD_CONFIG), hParentWindow, ::ConfigProc , (LPARAM)this); 160159b3361Sopenharmony_ci 161159b3361Sopenharmony_ci return DRVCNF_OK; // Can also return 162159b3361Sopenharmony_ci // DRVCNF_CANCEL 163159b3361Sopenharmony_ci // and DRVCNF_RESTART 164159b3361Sopenharmony_ci} 165159b3361Sopenharmony_ci*/ 166159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 167159b3361Sopenharmony_ci// About Dialog 168159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 169159b3361Sopenharmony_ci 170159b3361Sopenharmony_cistatic BOOL CALLBACK AboutProc( 171159b3361Sopenharmony_ci HWND hwndDlg, // handle to dialog box 172159b3361Sopenharmony_ciUINT uMsg, // message 173159b3361Sopenharmony_ciWPARAM wParam, // first message parameter 174159b3361Sopenharmony_ciLPARAM lParam // second message parameter 175159b3361Sopenharmony_ci) 176159b3361Sopenharmony_ci{ 177159b3361Sopenharmony_ci static HBRUSH hBrushStatic = NULL; 178159b3361Sopenharmony_ci// static LOGFONT lf; // structure for font information 179159b3361Sopenharmony_ci// static HFONT hfnt; 180159b3361Sopenharmony_ci static HCURSOR hcOverCursor = NULL; 181159b3361Sopenharmony_ci BOOL bResult = FALSE; 182159b3361Sopenharmony_ci 183159b3361Sopenharmony_ci switch (uMsg) { 184159b3361Sopenharmony_ci case WM_INITDIALOG: 185159b3361Sopenharmony_ci char tmp[150]; 186159b3361Sopenharmony_ci wsprintf(tmp,"LAME MP3 codec v%s", ACM::GetVersionString()); 187159b3361Sopenharmony_ci ::SetWindowText(GetDlgItem( hwndDlg, IDC_STATIC_ABOUT_TITLE), tmp); 188159b3361Sopenharmony_ci 189159b3361Sopenharmony_ci/* 190159b3361Sopenharmony_ci ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lf); 191159b3361Sopenharmony_ci lf.lfUnderline = TRUE; 192159b3361Sopenharmony_ci 193159b3361Sopenharmony_ci hfnt = ::CreateFontIndirect(&lf); 194159b3361Sopenharmony_ci 195159b3361Sopenharmony_ci ::SendMessage(::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), WM_SETFONT, (WPARAM) hfnt, TRUE); 196159b3361Sopenharmony_ci* / 197159b3361Sopenharmony_ci hBrushStatic = ::CreateSolidBrush(::GetSysColor (COLOR_BTNFACE)); 198159b3361Sopenharmony_ci*/ hcOverCursor = ::LoadCursor(NULL,(LPCTSTR)IDC_HAND); 199159b3361Sopenharmony_ci if (hcOverCursor == NULL) 200159b3361Sopenharmony_ci hcOverCursor = ::LoadCursor(NULL,(LPCTSTR)IDC_CROSS); 201159b3361Sopenharmony_ci 202159b3361Sopenharmony_ci bResult = TRUE; 203159b3361Sopenharmony_ci break; 204159b3361Sopenharmony_ci/* 205159b3361Sopenharmony_ci case WM_CTLCOLORSTATIC: 206159b3361Sopenharmony_ci /// \todo only if there are URLs 207159b3361Sopenharmony_ci if ((HWND)lParam == ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL)) 208159b3361Sopenharmony_ci { 209159b3361Sopenharmony_ci ::SetTextColor((HDC)wParam, ::GetSysColor (COLOR_HIGHLIGHT)); 210159b3361Sopenharmony_ci ::SetBkColor((HDC)wParam, ::GetSysColor (COLOR_BTNFACE)); 211159b3361Sopenharmony_ci 212159b3361Sopenharmony_ci return (LRESULT) hBrushStatic; 213159b3361Sopenharmony_ci } 214159b3361Sopenharmony_ci else 215159b3361Sopenharmony_ci return (LRESULT) NULL; 216159b3361Sopenharmony_ci*/ 217159b3361Sopenharmony_ci case WM_MOUSEMOVE: 218159b3361Sopenharmony_ci { 219159b3361Sopenharmony_ci POINT pnt; 220159b3361Sopenharmony_ci ::GetCursorPos(&pnt); 221159b3361Sopenharmony_ci 222159b3361Sopenharmony_ci RECT rect; 223159b3361Sopenharmony_ci ::GetWindowRect( ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), &rect); 224159b3361Sopenharmony_ci 225159b3361Sopenharmony_ci if ( ::PtInRect(&rect,pnt) ) 226159b3361Sopenharmony_ci { 227159b3361Sopenharmony_ci ::SetCursor(hcOverCursor); 228159b3361Sopenharmony_ci } 229159b3361Sopenharmony_ci 230159b3361Sopenharmony_ci 231159b3361Sopenharmony_ci } 232159b3361Sopenharmony_ci break; 233159b3361Sopenharmony_ci 234159b3361Sopenharmony_ci case WM_LBUTTONUP: 235159b3361Sopenharmony_ci { 236159b3361Sopenharmony_ci POINT pnt; 237159b3361Sopenharmony_ci ::GetCursorPos(&pnt); 238159b3361Sopenharmony_ci 239159b3361Sopenharmony_ci RECT rect; 240159b3361Sopenharmony_ci ::GetWindowRect( ::GetDlgItem(hwndDlg,IDC_STATIC_ABOUT_URL), &rect); 241159b3361Sopenharmony_ci 242159b3361Sopenharmony_ci TCHAR Url[200]; 243159b3361Sopenharmony_ci bool bUrl = false; 244159b3361Sopenharmony_ci if (::PtInRect(&rect,pnt)) 245159b3361Sopenharmony_ci { 246159b3361Sopenharmony_ci wsprintf(Url,get_lame_url()); 247159b3361Sopenharmony_ci bUrl = true; 248159b3361Sopenharmony_ci } 249159b3361Sopenharmony_ci 250159b3361Sopenharmony_ci if (bUrl) 251159b3361Sopenharmony_ci { 252159b3361Sopenharmony_ci ::ShellExecute(hwndDlg,"open",Url,NULL,"",SW_SHOWMAXIMIZED ); 253159b3361Sopenharmony_ci } 254159b3361Sopenharmony_ci 255159b3361Sopenharmony_ci } 256159b3361Sopenharmony_ci break; 257159b3361Sopenharmony_ci 258159b3361Sopenharmony_ci case WM_COMMAND: 259159b3361Sopenharmony_ci UINT command; 260159b3361Sopenharmony_ci command = GET_WM_COMMAND_ID(wParam, lParam); 261159b3361Sopenharmony_ci if (IDOK == command) 262159b3361Sopenharmony_ci { 263159b3361Sopenharmony_ci EndDialog(hwndDlg, TRUE); 264159b3361Sopenharmony_ci } 265159b3361Sopenharmony_ci bResult = FALSE; 266159b3361Sopenharmony_ci break; 267159b3361Sopenharmony_ci 268159b3361Sopenharmony_ci case IDC_STATIC_ABOUT_URL: 269159b3361Sopenharmony_ci break; 270159b3361Sopenharmony_ci default: 271159b3361Sopenharmony_ci bResult = FALSE; // will be treated by DefWindowProc 272159b3361Sopenharmony_ci} 273159b3361Sopenharmony_ci return bResult; 274159b3361Sopenharmony_ci} 275159b3361Sopenharmony_ci 276159b3361Sopenharmony_ciinline DWORD ACM::About(HWND hParentWindow) 277159b3361Sopenharmony_ci{ 278159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM : About (Parent Window = 0x%08X)",hParentWindow); 279159b3361Sopenharmony_ci 280159b3361Sopenharmony_ci DialogBoxParam( my_hModule, MAKEINTRESOURCE(IDD_ABOUT), hParentWindow, ::AboutProc , (LPARAM)this); 281159b3361Sopenharmony_ci 282159b3361Sopenharmony_ci return DRVCNF_OK; // Can also return 283159b3361Sopenharmony_ci// DRVCNF_CANCEL 284159b3361Sopenharmony_ci// and DRVCNF_RESTART 285159b3361Sopenharmony_ci} 286159b3361Sopenharmony_ci 287159b3361Sopenharmony_ci 288159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 289159b3361Sopenharmony_ci// Construction/Destruction 290159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 291159b3361Sopenharmony_ci 292159b3361Sopenharmony_ciACM::ACM( HMODULE hModule ) 293159b3361Sopenharmony_ci :my_hModule(hModule), 294159b3361Sopenharmony_ci my_hIcon(NULL), 295159b3361Sopenharmony_ci my_debug(ADbg(DEBUG_LEVEL_CREATION)), 296159b3361Sopenharmony_ci my_EncodingProperties(hModule) 297159b3361Sopenharmony_ci{ 298159b3361Sopenharmony_ci my_EncodingProperties.ParamsRestore(); 299159b3361Sopenharmony_ci 300159b3361Sopenharmony_ci /// \todo get the debug level from the registry 301159b3361Sopenharmony_ci unsigned char DebugFileName[512]; 302159b3361Sopenharmony_ci 303159b3361Sopenharmony_ci char tmp[128]; 304159b3361Sopenharmony_ci wsprintf(tmp,"LAMEacm 0x%08X",this); 305159b3361Sopenharmony_ci my_debug.setPrefix(tmp); /// \todo get it from the registry 306159b3361Sopenharmony_ci my_debug.setIncludeTime(true); /// \todo get it from the registry 307159b3361Sopenharmony_ci 308159b3361Sopenharmony_ci // Check in the registry if we have to Output Debug information 309159b3361Sopenharmony_ci DebugFileName[0] = '\0'; 310159b3361Sopenharmony_ci 311159b3361Sopenharmony_ci HKEY OssKey; 312159b3361Sopenharmony_ci if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\MUKOLI", 0, KEY_READ , &OssKey ) == ERROR_SUCCESS) { 313159b3361Sopenharmony_ci DWORD DataType; 314159b3361Sopenharmony_ci DWORD DebugFileNameSize = 512; 315159b3361Sopenharmony_ci if (RegQueryValueEx( OssKey, "DebugFile", NULL, &DataType, DebugFileName, &DebugFileNameSize ) == ERROR_SUCCESS) { 316159b3361Sopenharmony_ci if (DataType == REG_SZ) { 317159b3361Sopenharmony_ci my_debug.setUseFile(true); 318159b3361Sopenharmony_ci my_debug.setDebugFile((char *)DebugFileName); 319159b3361Sopenharmony_ci my_debug.OutPut("Debug file is %s",(char *)DebugFileName); 320159b3361Sopenharmony_ci } 321159b3361Sopenharmony_ci } 322159b3361Sopenharmony_ci } 323159b3361Sopenharmony_ci wsprintf(VersionString,"%s - %s", ACM_VERSION, get_lame_version() ); 324159b3361Sopenharmony_ci BuildBitrateTable(); 325159b3361Sopenharmony_ci 326159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "New ACM Creation (0x%08X)",this); 327159b3361Sopenharmony_ci} 328159b3361Sopenharmony_ci 329159b3361Sopenharmony_ciACM::~ACM() 330159b3361Sopenharmony_ci{ 331159b3361Sopenharmony_ci// not used, it's done automatically when closing the driver if (my_hIcon != NULL) 332159b3361Sopenharmony_ci// CloseHandle(my_hIcon); 333159b3361Sopenharmony_ci 334159b3361Sopenharmony_ci bitrate_table.clear(); 335159b3361Sopenharmony_ci 336159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_START, "ACM Deleted (0x%08X)",this); 337159b3361Sopenharmony_ci} 338159b3361Sopenharmony_ci 339159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 340159b3361Sopenharmony_ci// Main message handler 341159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 342159b3361Sopenharmony_ci 343159b3361Sopenharmony_ciLONG ACM::DriverProcedure(const HDRVR hdrvr, const UINT msg, LONG lParam1, LONG lParam2) 344159b3361Sopenharmony_ci{ 345159b3361Sopenharmony_ci DWORD dwRes = 0L; 346159b3361Sopenharmony_ci 347159b3361Sopenharmony_ci//my_debug.OutPut(DEBUG_LEVEL_MSG, "message 0x%08X for ThisACM 0x%08X", msg, this); 348159b3361Sopenharmony_ci 349159b3361Sopenharmony_ciswitch (msg) { 350159b3361Sopenharmony_ci case DRV_INSTALL: 351159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_INSTALL"); 352159b3361Sopenharmony_ci // Sent when the driver is installed. 353159b3361Sopenharmony_ci dwRes = DRVCNF_OK; // Can also return 354159b3361Sopenharmony_ci break; // DRVCNF_CANCEL 355159b3361Sopenharmony_ci // and DRV_RESTART 356159b3361Sopenharmony_ci 357159b3361Sopenharmony_ci case DRV_REMOVE: 358159b3361Sopenharmony_ci // Sent when the driver is removed. 359159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_REMOVE"); 360159b3361Sopenharmony_ci dwRes = 1L; // return value ignored 361159b3361Sopenharmony_ci break; 362159b3361Sopenharmony_ci 363159b3361Sopenharmony_ci case DRV_QUERYCONFIGURE: 364159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_QUERYCONFIGURE"); 365159b3361Sopenharmony_ci // Sent to determine if the driver can be 366159b3361Sopenharmony_ci // configured. 367159b3361Sopenharmony_ci dwRes = 1L; // Zero indicates configuration 368159b3361Sopenharmony_ci break; // NOT supported 369159b3361Sopenharmony_ci 370159b3361Sopenharmony_ci case DRV_CONFIGURE: 371159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "DRV_CONFIGURE"); 372159b3361Sopenharmony_ci // Sent to display the configuration 373159b3361Sopenharmony_ci // dialog box for the driver. 374159b3361Sopenharmony_ci// dwRes = Configure( (HWND) lParam1, (LPDRVCONFIGINFO) lParam2 ); 375159b3361Sopenharmony_ci if (my_EncodingProperties.Config(my_hModule, (HWND) lParam1)) 376159b3361Sopenharmony_ci { 377159b3361Sopenharmony_ci dwRes = DRVCNF_OK; // Can also return 378159b3361Sopenharmony_ci // DRVCNF_CANCEL 379159b3361Sopenharmony_ci // and DRVCNF_RESTART 380159b3361Sopenharmony_ci } else { 381159b3361Sopenharmony_ci dwRes = DRVCNF_CANCEL; 382159b3361Sopenharmony_ci } 383159b3361Sopenharmony_ci break; 384159b3361Sopenharmony_ci 385159b3361Sopenharmony_ci /************************************** 386159b3361Sopenharmony_ci // ACM additional messages 387159b3361Sopenharmony_ci ***************************************/ 388159b3361Sopenharmony_ci 389159b3361Sopenharmony_ci case ACMDM_DRIVER_ABOUT: 390159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_DRIVER_ABOUT"); 391159b3361Sopenharmony_ci 392159b3361Sopenharmony_ci dwRes = About( (HWND) lParam1 ); 393159b3361Sopenharmony_ci 394159b3361Sopenharmony_ci break; 395159b3361Sopenharmony_ci 396159b3361Sopenharmony_ci case ACMDM_DRIVER_DETAILS: // acmDriverDetails 397159b3361Sopenharmony_ci // Fill-in general informations about the driver/codec 398159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_DRIVER_DETAILS"); 399159b3361Sopenharmony_ci 400159b3361Sopenharmony_ci dwRes = OnDriverDetails(hdrvr, (LPACMDRIVERDETAILS) lParam1); 401159b3361Sopenharmony_ci 402159b3361Sopenharmony_ci break; 403159b3361Sopenharmony_ci 404159b3361Sopenharmony_ci case ACMDM_FORMATTAG_DETAILS: // acmFormatTagDetails 405159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMATTAG_DETAILS"); 406159b3361Sopenharmony_ci 407159b3361Sopenharmony_ci dwRes = OnFormatTagDetails((LPACMFORMATTAGDETAILS) lParam1, lParam2); 408159b3361Sopenharmony_ci 409159b3361Sopenharmony_ci break; 410159b3361Sopenharmony_ci 411159b3361Sopenharmony_ci case ACMDM_FORMAT_DETAILS: // acmFormatDetails 412159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMAT_DETAILS"); 413159b3361Sopenharmony_ci 414159b3361Sopenharmony_ci dwRes = OnFormatDetails((LPACMFORMATDETAILS) lParam1, lParam2); 415159b3361Sopenharmony_ci 416159b3361Sopenharmony_ci break; 417159b3361Sopenharmony_ci 418159b3361Sopenharmony_ci case ACMDM_FORMAT_SUGGEST: // acmFormatSuggest 419159b3361Sopenharmony_ci // Sent to determine if the driver can be 420159b3361Sopenharmony_ci // configured. 421159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_FORMAT_SUGGEST"); 422159b3361Sopenharmony_ci dwRes = OnFormatSuggest((LPACMDRVFORMATSUGGEST) lParam1); 423159b3361Sopenharmony_ci break; 424159b3361Sopenharmony_ci 425159b3361Sopenharmony_ci /************************************** 426159b3361Sopenharmony_ci // ACM stream messages 427159b3361Sopenharmony_ci ***************************************/ 428159b3361Sopenharmony_ci 429159b3361Sopenharmony_ci case ACMDM_STREAM_OPEN: 430159b3361Sopenharmony_ci // Sent to determine if the driver can be 431159b3361Sopenharmony_ci // configured. 432159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_OPEN"); 433159b3361Sopenharmony_ci dwRes = OnStreamOpen((LPACMDRVSTREAMINSTANCE) lParam1); 434159b3361Sopenharmony_ci break; 435159b3361Sopenharmony_ci 436159b3361Sopenharmony_ci case ACMDM_STREAM_SIZE: 437159b3361Sopenharmony_ci // returns a recommended size for a source 438159b3361Sopenharmony_ci // or destination buffer on an ACM stream 439159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_SIZE"); 440159b3361Sopenharmony_ci dwRes = OnStreamSize((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMDRVSTREAMSIZE)lParam2); 441159b3361Sopenharmony_ci break; 442159b3361Sopenharmony_ci 443159b3361Sopenharmony_ci case ACMDM_STREAM_PREPARE: 444159b3361Sopenharmony_ci // prepares an ACMSTREAMHEADER structure for 445159b3361Sopenharmony_ci // an ACM stream conversion 446159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_PREPARE"); 447159b3361Sopenharmony_ci dwRes = OnStreamPrepareHeader((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMSTREAMHEADER) lParam2); 448159b3361Sopenharmony_ci break; 449159b3361Sopenharmony_ci 450159b3361Sopenharmony_ci case ACMDM_STREAM_UNPREPARE: 451159b3361Sopenharmony_ci // cleans up the preparation performed by 452159b3361Sopenharmony_ci // the ACMDM_STREAM_PREPARE message for an ACM stream 453159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_UNPREPARE"); 454159b3361Sopenharmony_ci dwRes = OnStreamUnPrepareHeader((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMSTREAMHEADER) lParam2); 455159b3361Sopenharmony_ci break; 456159b3361Sopenharmony_ci 457159b3361Sopenharmony_ci case ACMDM_STREAM_CONVERT: 458159b3361Sopenharmony_ci // perform a conversion on the specified conversion stream 459159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_CONVERT"); 460159b3361Sopenharmony_ci dwRes = OnStreamConvert((LPACMDRVSTREAMINSTANCE)lParam1, (LPACMDRVSTREAMHEADER) lParam2); 461159b3361Sopenharmony_ci 462159b3361Sopenharmony_ci break; 463159b3361Sopenharmony_ci 464159b3361Sopenharmony_ci case ACMDM_STREAM_CLOSE: 465159b3361Sopenharmony_ci // closes an ACM conversion stream 466159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACMDM_STREAM_CLOSE"); 467159b3361Sopenharmony_ci dwRes = OnStreamClose((LPACMDRVSTREAMINSTANCE)lParam1); 468159b3361Sopenharmony_ci break; 469159b3361Sopenharmony_ci 470159b3361Sopenharmony_ci /************************************** 471159b3361Sopenharmony_ci // Unknown message 472159b3361Sopenharmony_ci ***************************************/ 473159b3361Sopenharmony_ci 474159b3361Sopenharmony_ci default: 475159b3361Sopenharmony_ci // Process any other messages. 476159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_MSG, "ACM::DriverProc unknown message (0x%08X), lParam1 = 0x%08X, lParam2 = 0x%08X", msg, lParam1, lParam2); 477159b3361Sopenharmony_ci return DefDriverProc ((DWORD)this, hdrvr, msg, lParam1, lParam2); 478159b3361Sopenharmony_ci } 479159b3361Sopenharmony_ci 480159b3361Sopenharmony_ci return dwRes; 481159b3361Sopenharmony_ci} 482159b3361Sopenharmony_ci 483159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 484159b3361Sopenharmony_ci// Special message handlers 485159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////// 486159b3361Sopenharmony_ci/*! 487159b3361Sopenharmony_ci Retreive the config details of this ACM driver 488159b3361Sopenharmony_ci The index represent the specified format 489159b3361Sopenharmony_ci 490159b3361Sopenharmony_ci \param a_FormatDetails will be filled with all the corresponding data 491159b3361Sopenharmony_ci*/ 492159b3361Sopenharmony_ciinline DWORD ACM::OnFormatDetails(LPACMFORMATDETAILS a_FormatDetails, const LPARAM a_Query) 493159b3361Sopenharmony_ci{ 494159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 495159b3361Sopenharmony_ci 496159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILS a_Query = 0x%08X",a_Query); 497159b3361Sopenharmony_ci switch (a_Query & ACM_FORMATDETAILSF_QUERYMASK) { 498159b3361Sopenharmony_ci 499159b3361Sopenharmony_ci // Fill-in the informations corresponding to the FormatDetails->dwFormatTagIndex 500159b3361Sopenharmony_ci case ACM_FORMATDETAILSF_INDEX : 501159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "enter ACM_FORMATDETAILSF_INDEX for index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex); 502159b3361Sopenharmony_ci if (a_FormatDetails->dwFormatTag == PERSONAL_FORMAT) { 503159b3361Sopenharmony_ci if (a_FormatDetails->dwFormatIndex < GetNumberEncodingFormats()) { 504159b3361Sopenharmony_ci LPWAVEFORMATEX WaveExt; 505159b3361Sopenharmony_ci WaveExt = a_FormatDetails->pwfx; 506159b3361Sopenharmony_ci 507159b3361Sopenharmony_ci WaveExt->wFormatTag = PERSONAL_FORMAT; 508159b3361Sopenharmony_ci 509159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format in : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec); 510159b3361Sopenharmony_ci GetMP3FormatForIndex(a_FormatDetails->dwFormatIndex, *WaveExt, a_FormatDetails->szFormat); 511159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format out : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec); 512159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 513159b3361Sopenharmony_ci } 514159b3361Sopenharmony_ci else 515159b3361Sopenharmony_ci { 516159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILSF_INDEX unknown index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex); 517159b3361Sopenharmony_ci } 518159b3361Sopenharmony_ci } 519159b3361Sopenharmony_ci else if (a_FormatDetails->dwFormatTag == WAVE_FORMAT_PCM) { 520159b3361Sopenharmony_ci if (a_FormatDetails->dwFormatIndex < FORMAT_MAX_NB_PCM) { 521159b3361Sopenharmony_ci LPWAVEFORMATEX WaveExt; 522159b3361Sopenharmony_ci WaveExt = a_FormatDetails->pwfx; 523159b3361Sopenharmony_ci 524159b3361Sopenharmony_ci WaveExt->wFormatTag = WAVE_FORMAT_PCM; 525159b3361Sopenharmony_ci 526159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format in : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec); 527159b3361Sopenharmony_ci GetPCMFormatForIndex(a_FormatDetails->dwFormatIndex, *WaveExt, a_FormatDetails->szFormat); 528159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "format out : channels %d, sample rate %d", WaveExt->nChannels, WaveExt->nSamplesPerSec); 529159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 530159b3361Sopenharmony_ci } 531159b3361Sopenharmony_ci else 532159b3361Sopenharmony_ci { 533159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATDETAILSF_INDEX unknown index 0x%04X:%03d",a_FormatDetails->dwFormatTag,a_FormatDetails->dwFormatIndex); 534159b3361Sopenharmony_ci } 535159b3361Sopenharmony_ci } 536159b3361Sopenharmony_ci else 537159b3361Sopenharmony_ci { 538159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Unknown a_FormatDetails->dwFormatTag = 0x%08X",a_FormatDetails->dwFormatTag); 539159b3361Sopenharmony_ci } 540159b3361Sopenharmony_ci 541159b3361Sopenharmony_ci case ACM_FORMATDETAILSF_FORMAT : 542159b3361Sopenharmony_ci /// \todo we may output the corresponding strong (only for personal format) 543159b3361Sopenharmony_ci LPWAVEFORMATEX WaveExt; 544159b3361Sopenharmony_ci WaveExt = a_FormatDetails->pwfx; 545159b3361Sopenharmony_ci 546159b3361Sopenharmony_ci 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); 547159b3361Sopenharmony_ci 548159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 549159b3361Sopenharmony_ci break; 550159b3361Sopenharmony_ci 551159b3361Sopenharmony_ci default: 552159b3361Sopenharmony_ci Result = ACMERR_NOTPOSSIBLE; 553159b3361Sopenharmony_ci break; 554159b3361Sopenharmony_ci } 555159b3361Sopenharmony_ci 556159b3361Sopenharmony_ci a_FormatDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 557159b3361Sopenharmony_ci 558159b3361Sopenharmony_ci return Result; 559159b3361Sopenharmony_ci} 560159b3361Sopenharmony_ci 561159b3361Sopenharmony_ci/*! 562159b3361Sopenharmony_ci Retreive the details of each known format by this ACM driver 563159b3361Sopenharmony_ci The index represent the specified format (0 = MP3 / 1 = PCM) 564159b3361Sopenharmony_ci 565159b3361Sopenharmony_ci \param a_FormatTagDetails will be filled with all the corresponding data 566159b3361Sopenharmony_ci*/ 567159b3361Sopenharmony_ciinline DWORD ACM::OnFormatTagDetails(LPACMFORMATTAGDETAILS a_FormatTagDetails, const LPARAM a_Query) 568159b3361Sopenharmony_ci{ 569159b3361Sopenharmony_ci DWORD Result; 570159b3361Sopenharmony_ci DWORD the_format = WAVE_FORMAT_UNKNOWN; // the format to give details 571159b3361Sopenharmony_ci 572159b3361Sopenharmony_ci if (a_FormatTagDetails->cbStruct >= sizeof(*a_FormatTagDetails)) { 573159b3361Sopenharmony_ci 574159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACMDM_FORMATTAG_DETAILS, a_Query = 0x%08X",a_Query); 575159b3361Sopenharmony_ci switch(a_Query & ACM_FORMATTAGDETAILSF_QUERYMASK) { 576159b3361Sopenharmony_ci 577159b3361Sopenharmony_ci case ACM_FORMATTAGDETAILSF_INDEX: 578159b3361Sopenharmony_ci // Fill-in the informations corresponding to the a_FormatDetails->dwFormatTagIndex 579159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "get ACM_FORMATTAGDETAILSF_INDEX for index %03d",a_FormatTagDetails->dwFormatTagIndex); 580159b3361Sopenharmony_ci 581159b3361Sopenharmony_ci if (a_FormatTagDetails->dwFormatTagIndex < FORMAT_TAG_MAX_NB) { 582159b3361Sopenharmony_ci switch (a_FormatTagDetails->dwFormatTagIndex) 583159b3361Sopenharmony_ci { 584159b3361Sopenharmony_ci case 0: 585159b3361Sopenharmony_ci the_format = PERSONAL_FORMAT; 586159b3361Sopenharmony_ci break; 587159b3361Sopenharmony_ci default : 588159b3361Sopenharmony_ci the_format = WAVE_FORMAT_PCM; 589159b3361Sopenharmony_ci break; 590159b3361Sopenharmony_ci } 591159b3361Sopenharmony_ci } 592159b3361Sopenharmony_ci else 593159b3361Sopenharmony_ci { 594159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATTAGDETAILSF_INDEX for unsupported index %03d",a_FormatTagDetails->dwFormatTagIndex); 595159b3361Sopenharmony_ci Result = ACMERR_NOTPOSSIBLE; 596159b3361Sopenharmony_ci } 597159b3361Sopenharmony_ci break; 598159b3361Sopenharmony_ci 599159b3361Sopenharmony_ci case ACM_FORMATTAGDETAILSF_FORMATTAG: 600159b3361Sopenharmony_ci // Fill-in the informations corresponding to the a_FormatDetails->dwFormatTagIndex and hdrvr given 601159b3361Sopenharmony_ci switch (a_FormatTagDetails->dwFormatTag) 602159b3361Sopenharmony_ci { 603159b3361Sopenharmony_ci case WAVE_FORMAT_PCM: 604159b3361Sopenharmony_ci the_format = WAVE_FORMAT_PCM; 605159b3361Sopenharmony_ci break; 606159b3361Sopenharmony_ci case PERSONAL_FORMAT: 607159b3361Sopenharmony_ci the_format = PERSONAL_FORMAT; 608159b3361Sopenharmony_ci break; 609159b3361Sopenharmony_ci default: 610159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 611159b3361Sopenharmony_ci } 612159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "get ACM_FORMATTAGDETAILSF_FORMATTAG for index 0x%02X, cStandardFormats = %d",a_FormatTagDetails->dwFormatTagIndex,a_FormatTagDetails->cStandardFormats); 613159b3361Sopenharmony_ci break; 614159b3361Sopenharmony_ci case ACM_FORMATTAGDETAILSF_LARGESTSIZE: 615159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "ACM_FORMATTAGDETAILSF_LARGESTSIZE not used"); 616159b3361Sopenharmony_ci Result = 0L; 617159b3361Sopenharmony_ci break; 618159b3361Sopenharmony_ci default: 619159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails Unknown Format tag query"); 620159b3361Sopenharmony_ci Result = MMSYSERR_NOTSUPPORTED; 621159b3361Sopenharmony_ci break; 622159b3361Sopenharmony_ci } 623159b3361Sopenharmony_ci 624159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails the_format = 0x%08X",the_format); 625159b3361Sopenharmony_ci switch(the_format) 626159b3361Sopenharmony_ci { 627159b3361Sopenharmony_ci case WAVE_FORMAT_PCM: 628159b3361Sopenharmony_ci a_FormatTagDetails->dwFormatTag = WAVE_FORMAT_PCM; 629159b3361Sopenharmony_ci a_FormatTagDetails->dwFormatTagIndex = 0; 630159b3361Sopenharmony_ci a_FormatTagDetails->cbFormatSize = sizeof(PCMWAVEFORMAT); 631159b3361Sopenharmony_ci /// \note 0 may mean we don't know how to decode 632159b3361Sopenharmony_ci a_FormatTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 633159b3361Sopenharmony_ci a_FormatTagDetails->cStandardFormats = FORMAT_MAX_NB_PCM; 634159b3361Sopenharmony_ci // should be filled by Windows a_FormatTagDetails->szFormatTag[0] = '\0'; 635159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 636159b3361Sopenharmony_ci break; 637159b3361Sopenharmony_ci case PERSONAL_FORMAT: 638159b3361Sopenharmony_ci a_FormatTagDetails->dwFormatTag = PERSONAL_FORMAT; 639159b3361Sopenharmony_ci a_FormatTagDetails->dwFormatTagIndex = 1; 640159b3361Sopenharmony_ci a_FormatTagDetails->cbFormatSize = SIZE_FORMAT_STRUCT; 641159b3361Sopenharmony_ci a_FormatTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 642159b3361Sopenharmony_ci a_FormatTagDetails->cStandardFormats = GetNumberEncodingFormats(); 643159b3361Sopenharmony_ci lstrcpyW( a_FormatTagDetails->szFormatTag, L"Lame MP3" ); 644159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 645159b3361Sopenharmony_ci break; 646159b3361Sopenharmony_ci default: 647159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails Unknown format 0x%08X",the_format); 648159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 649159b3361Sopenharmony_ci } 650159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnFormatTagDetails %d possibilities for format 0x%08X",a_FormatTagDetails->cStandardFormats,the_format); 651159b3361Sopenharmony_ci } 652159b3361Sopenharmony_ci else 653159b3361Sopenharmony_ci { 654159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "a_FormatTagDetails->cbStruct < sizeof(*a_FormatDetails)"); 655159b3361Sopenharmony_ci Result = ACMERR_NOTPOSSIBLE; 656159b3361Sopenharmony_ci } 657159b3361Sopenharmony_ci 658159b3361Sopenharmony_ci return Result; 659159b3361Sopenharmony_ci} 660159b3361Sopenharmony_ci 661159b3361Sopenharmony_ci/*! 662159b3361Sopenharmony_ci Retreive the global details of this ACM driver 663159b3361Sopenharmony_ci 664159b3361Sopenharmony_ci \param a_DriverDetail will be filled with all the corresponding data 665159b3361Sopenharmony_ci*/ 666159b3361Sopenharmony_ciinline DWORD ACM::OnDriverDetails(const HDRVR hdrvr, LPACMDRIVERDETAILS a_DriverDetail) 667159b3361Sopenharmony_ci{ 668159b3361Sopenharmony_ci if (my_hIcon == NULL) 669159b3361Sopenharmony_ci my_hIcon = LoadIcon(GetDriverModuleHandle(hdrvr), MAKEINTRESOURCE(IDI_ICON)); 670159b3361Sopenharmony_ci a_DriverDetail->hicon = my_hIcon; 671159b3361Sopenharmony_ci 672159b3361Sopenharmony_ci a_DriverDetail->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC; 673159b3361Sopenharmony_ci a_DriverDetail->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED; 674159b3361Sopenharmony_ci 675159b3361Sopenharmony_ci /// \note this is an explicit hack of the FhG values 676159b3361Sopenharmony_ci /// \note later it could be a new value when the decoding is done 677159b3361Sopenharmony_ci a_DriverDetail->wMid = MM_FRAUNHOFER_IIS; 678159b3361Sopenharmony_ci a_DriverDetail->wPid = MM_FHGIIS_MPEGLAYER3; 679159b3361Sopenharmony_ci 680159b3361Sopenharmony_ci a_DriverDetail->vdwACM = VERSION_MSACM; 681159b3361Sopenharmony_ci a_DriverDetail->vdwDriver = VERSION_ACM_DRIVER; 682159b3361Sopenharmony_ci a_DriverDetail->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; 683159b3361Sopenharmony_ci a_DriverDetail->cFormatTags = FORMAT_TAG_MAX_NB; // 2 : MP3 and PCM 684159b3361Sopenharmony_ci// a_DriverDetail->cFormatTags = 1; // 2 : MP3 and PCM 685159b3361Sopenharmony_ci a_DriverDetail->cFilterTags = FILTER_TAG_MAX_NB; 686159b3361Sopenharmony_ci 687159b3361Sopenharmony_ci lstrcpyW( a_DriverDetail->szShortName, L"LAME MP3" ); 688159b3361Sopenharmony_ci char tmpStr[128]; 689159b3361Sopenharmony_ci wsprintf(tmpStr, "LAME MP3 Codec v%s", GetVersionString()); 690159b3361Sopenharmony_ci int u = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, tmpStr, -1, a_DriverDetail->szLongName, 0); 691159b3361Sopenharmony_ci MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, tmpStr, -1, a_DriverDetail->szLongName, u); 692159b3361Sopenharmony_ci lstrcpyW( a_DriverDetail->szCopyright, L"2002 Steve Lhomme" ); 693159b3361Sopenharmony_ci lstrcpyW( a_DriverDetail->szLicensing, L"LGPL (see gnu.org)" ); 694159b3361Sopenharmony_ci /// \todo update this part when the code changes 695159b3361Sopenharmony_ci lstrcpyW( a_DriverDetail->szFeatures , L"only CBR implementation" ); 696159b3361Sopenharmony_ci 697159b3361Sopenharmony_ci return MMSYSERR_NOERROR; // Can also return DRVCNF_CANCEL 698159b3361Sopenharmony_ci} 699159b3361Sopenharmony_ci 700159b3361Sopenharmony_ci/*! 701159b3361Sopenharmony_ci Suggest an output format for the specified input format 702159b3361Sopenharmony_ci 703159b3361Sopenharmony_ci \param a_FormatSuggest will be filled with all the corresponding data 704159b3361Sopenharmony_ci*/ 705159b3361Sopenharmony_ciinline DWORD ACM::OnFormatSuggest(LPACMDRVFORMATSUGGEST a_FormatSuggest) 706159b3361Sopenharmony_ci{ 707159b3361Sopenharmony_ci DWORD Result = MMSYSERR_NOTSUPPORTED; 708159b3361Sopenharmony_ci DWORD fdwSuggest = (ACM_FORMATSUGGESTF_TYPEMASK & a_FormatSuggest->fdwSuggest); 709159b3361Sopenharmony_ci 710159b3361Sopenharmony_cimy_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest %s%s%s%s (0x%08X)", 711159b3361Sopenharmony_ci (fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS) ? "channels, ":"", 712159b3361Sopenharmony_ci (fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC) ? "samples/sec, ":"", 713159b3361Sopenharmony_ci (fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE) ? "bits/sample, ":"", 714159b3361Sopenharmony_ci (fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) ? "format, ":"", 715159b3361Sopenharmony_ci fdwSuggest); 716159b3361Sopenharmony_ci 717159b3361Sopenharmony_cimy_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", 718159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->wFormatTag, 719159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->nChannels, 720159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->nSamplesPerSec, 721159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->nAvgBytesPerSec, 722159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->nBlockAlign, 723159b3361Sopenharmony_ci a_FormatSuggest->pwfxSrc->wBitsPerSample); 724159b3361Sopenharmony_ci 725159b3361Sopenharmony_cimy_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggested destination format = 0x%04X, channels = %d, Samples/s = %d, AvgB/s = %d, BlockAlign = %d, b/sample = %d", 726159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wFormatTag, 727159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nChannels, 728159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nSamplesPerSec, 729159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nAvgBytesPerSec, 730159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nBlockAlign, 731159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wBitsPerSample); 732159b3361Sopenharmony_ci 733159b3361Sopenharmony_ci switch (a_FormatSuggest->pwfxSrc->wFormatTag) 734159b3361Sopenharmony_ci { 735159b3361Sopenharmony_ci case WAVE_FORMAT_PCM: 736159b3361Sopenharmony_ci /// \todo handle here the decoding ? 737159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PCM source"); 738159b3361Sopenharmony_ci // 739159b3361Sopenharmony_ci // if the destination format tag is restricted, verify that 740159b3361Sopenharmony_ci // it is within our capabilities... 741159b3361Sopenharmony_ci // 742159b3361Sopenharmony_ci // this driver is able to decode to PCM 743159b3361Sopenharmony_ci // 744159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest) 745159b3361Sopenharmony_ci { 746159b3361Sopenharmony_ci if (PERSONAL_FORMAT != a_FormatSuggest->pwfxDst->wFormatTag) 747159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 748159b3361Sopenharmony_ci } 749159b3361Sopenharmony_ci else 750159b3361Sopenharmony_ci { 751159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wFormatTag = PERSONAL_FORMAT; 752159b3361Sopenharmony_ci } 753159b3361Sopenharmony_ci 754159b3361Sopenharmony_ci 755159b3361Sopenharmony_cimy_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed A"); 756159b3361Sopenharmony_ci // 757159b3361Sopenharmony_ci // if the destination channel count is restricted, verify that 758159b3361Sopenharmony_ci // it is within our capabilities... 759159b3361Sopenharmony_ci // 760159b3361Sopenharmony_ci // this driver is not able to change the number of channels 761159b3361Sopenharmony_ci // 762159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest) 763159b3361Sopenharmony_ci { 764159b3361Sopenharmony_ci if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels) 765159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 766159b3361Sopenharmony_ci } 767159b3361Sopenharmony_ci else 768159b3361Sopenharmony_ci { 769159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels; 770159b3361Sopenharmony_ci } 771159b3361Sopenharmony_ci 772159b3361Sopenharmony_ci if (a_FormatSuggest->pwfxSrc->nChannels != 1 && a_FormatSuggest->pwfxSrc->nChannels != 2) 773159b3361Sopenharmony_ci return MMSYSERR_INVALPARAM; 774159b3361Sopenharmony_ci 775159b3361Sopenharmony_ci 776159b3361Sopenharmony_cimy_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed B"); 777159b3361Sopenharmony_ci // 778159b3361Sopenharmony_ci // if the destination samples per second is restricted, verify 779159b3361Sopenharmony_ci // that it is within our capabilities... 780159b3361Sopenharmony_ci // 781159b3361Sopenharmony_ci // this driver is not able to change the sample rate 782159b3361Sopenharmony_ci // 783159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest) 784159b3361Sopenharmony_ci { 785159b3361Sopenharmony_ci if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec) 786159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 787159b3361Sopenharmony_ci } 788159b3361Sopenharmony_ci else 789159b3361Sopenharmony_ci { 790159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec; 791159b3361Sopenharmony_ci } 792159b3361Sopenharmony_ci 793159b3361Sopenharmony_ci 794159b3361Sopenharmony_cimy_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed C"); 795159b3361Sopenharmony_ci // 796159b3361Sopenharmony_ci // if the destination bits per sample is restricted, verify 797159b3361Sopenharmony_ci // that it is within our capabilities... 798159b3361Sopenharmony_ci // 799159b3361Sopenharmony_ci // We prefer decoding to 16-bit PCM. 800159b3361Sopenharmony_ci // 801159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest) 802159b3361Sopenharmony_ci { 803159b3361Sopenharmony_ci if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) ) 804159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 805159b3361Sopenharmony_ci } 806159b3361Sopenharmony_ci else 807159b3361Sopenharmony_ci { 808159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wBitsPerSample = 16; 809159b3361Sopenharmony_ci } 810159b3361Sopenharmony_ci 811159b3361Sopenharmony_ci // a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN; 812159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; 813159b3361Sopenharmony_ci 814159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nChannels * 64000 / 8; 815159b3361Sopenharmony_ci 816159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed"); 817159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 818159b3361Sopenharmony_ci 819159b3361Sopenharmony_ci 820159b3361Sopenharmony_ci break; 821159b3361Sopenharmony_ci case PERSONAL_FORMAT: 822159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest for PERSONAL source"); 823159b3361Sopenharmony_ci // 824159b3361Sopenharmony_ci // if the destination format tag is restricted, verify that 825159b3361Sopenharmony_ci // it is within our capabilities... 826159b3361Sopenharmony_ci // 827159b3361Sopenharmony_ci // this driver is able to decode to PCM 828159b3361Sopenharmony_ci // 829159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest) 830159b3361Sopenharmony_ci { 831159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM != a_FormatSuggest->pwfxDst->wFormatTag) 832159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 833159b3361Sopenharmony_ci } 834159b3361Sopenharmony_ci else 835159b3361Sopenharmony_ci { 836159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; 837159b3361Sopenharmony_ci } 838159b3361Sopenharmony_ci 839159b3361Sopenharmony_ci 840159b3361Sopenharmony_ci // 841159b3361Sopenharmony_ci // if the destination channel count is restricted, verify that 842159b3361Sopenharmony_ci // it is within our capabilities... 843159b3361Sopenharmony_ci // 844159b3361Sopenharmony_ci // this driver is not able to change the number of channels 845159b3361Sopenharmony_ci // 846159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest) 847159b3361Sopenharmony_ci { 848159b3361Sopenharmony_ci if (a_FormatSuggest->pwfxSrc->nChannels != a_FormatSuggest->pwfxDst->nChannels) 849159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 850159b3361Sopenharmony_ci } 851159b3361Sopenharmony_ci else 852159b3361Sopenharmony_ci { 853159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nChannels = a_FormatSuggest->pwfxSrc->nChannels; 854159b3361Sopenharmony_ci } 855159b3361Sopenharmony_ci 856159b3361Sopenharmony_ci 857159b3361Sopenharmony_ci // 858159b3361Sopenharmony_ci // if the destination samples per second is restricted, verify 859159b3361Sopenharmony_ci // that it is within our capabilities... 860159b3361Sopenharmony_ci // 861159b3361Sopenharmony_ci // this driver is not able to change the sample rate 862159b3361Sopenharmony_ci // 863159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest) 864159b3361Sopenharmony_ci { 865159b3361Sopenharmony_ci if (a_FormatSuggest->pwfxSrc->nSamplesPerSec != a_FormatSuggest->pwfxDst->nSamplesPerSec) 866159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 867159b3361Sopenharmony_ci } 868159b3361Sopenharmony_ci else 869159b3361Sopenharmony_ci { 870159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nSamplesPerSec = a_FormatSuggest->pwfxSrc->nSamplesPerSec; 871159b3361Sopenharmony_ci } 872159b3361Sopenharmony_ci 873159b3361Sopenharmony_ci 874159b3361Sopenharmony_ci // 875159b3361Sopenharmony_ci // if the destination bits per sample is restricted, verify 876159b3361Sopenharmony_ci // that it is within our capabilities... 877159b3361Sopenharmony_ci // 878159b3361Sopenharmony_ci // We prefer decoding to 16-bit PCM. 879159b3361Sopenharmony_ci // 880159b3361Sopenharmony_ci if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest) 881159b3361Sopenharmony_ci { 882159b3361Sopenharmony_ci if ( (16 != a_FormatSuggest->pwfxDst->wBitsPerSample) && (8 != a_FormatSuggest->pwfxDst->wBitsPerSample) ) 883159b3361Sopenharmony_ci return (ACMERR_NOTPOSSIBLE); 884159b3361Sopenharmony_ci } 885159b3361Sopenharmony_ci else 886159b3361Sopenharmony_ci { 887159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wBitsPerSample = 16; 888159b3361Sopenharmony_ci } 889159b3361Sopenharmony_ci 890159b3361Sopenharmony_ci // a_FormatSuggest->pwfxDst->nBlockAlign = FORMAT_BLOCK_ALIGN; 891159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nBlockAlign = a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; 892159b3361Sopenharmony_ci 893159b3361Sopenharmony_ci /// \todo this value must be a correct one ! 894159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nAvgBytesPerSec = a_FormatSuggest->pwfxDst->nSamplesPerSec * a_FormatSuggest->pwfxDst->nChannels * a_FormatSuggest->pwfxDst->wBitsPerSample / 8; 895159b3361Sopenharmony_ci 896159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Suggest succeed"); 897159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 898159b3361Sopenharmony_ci 899159b3361Sopenharmony_ci 900159b3361Sopenharmony_ci break; 901159b3361Sopenharmony_ci } 902159b3361Sopenharmony_ci 903159b3361Sopenharmony_ci 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", 904159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wFormatTag, 905159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nChannels, 906159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nSamplesPerSec, 907159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nAvgBytesPerSec, 908159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->nBlockAlign, 909159b3361Sopenharmony_ci a_FormatSuggest->pwfxDst->wBitsPerSample); 910159b3361Sopenharmony_ci 911159b3361Sopenharmony_ci return Result; 912159b3361Sopenharmony_ci} 913159b3361Sopenharmony_ci 914159b3361Sopenharmony_ci/*! 915159b3361Sopenharmony_ci Create a stream instance for decoding/encoding 916159b3361Sopenharmony_ci 917159b3361Sopenharmony_ci \param a_StreamInstance contain information about the stream desired 918159b3361Sopenharmony_ci*/ 919159b3361Sopenharmony_ciinline DWORD ACM::OnStreamOpen(LPACMDRVSTREAMINSTANCE a_StreamInstance) 920159b3361Sopenharmony_ci{ 921159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 922159b3361Sopenharmony_ci 923159b3361Sopenharmony_ci // 924159b3361Sopenharmony_ci // the most important condition to check before doing anything else 925159b3361Sopenharmony_ci // is that this ACM driver can actually perform the conversion we are 926159b3361Sopenharmony_ci // being opened for. this check should fail as quickly as possible 927159b3361Sopenharmony_ci // if the conversion is not possible by this driver. 928159b3361Sopenharmony_ci // 929159b3361Sopenharmony_ci // it is VERY important to fail quickly so the ACM can attempt to 930159b3361Sopenharmony_ci // find a driver that is suitable for the conversion. also note that 931159b3361Sopenharmony_ci // the ACM may call this driver several times with slightly different 932159b3361Sopenharmony_ci // format specifications before giving up. 933159b3361Sopenharmony_ci // 934159b3361Sopenharmony_ci // this driver first verifies that the source and destination formats 935159b3361Sopenharmony_ci // are acceptable... 936159b3361Sopenharmony_ci // 937159b3361Sopenharmony_ci switch (a_StreamInstance->pwfxSrc->wFormatTag) 938159b3361Sopenharmony_ci { 939159b3361Sopenharmony_ci case WAVE_FORMAT_PCM: 940159b3361Sopenharmony_ci 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); 941159b3361Sopenharmony_ci if (a_StreamInstance->pwfxDst->wFormatTag == PERSONAL_FORMAT) 942159b3361Sopenharmony_ci { 943159b3361Sopenharmony_ci unsigned int OutputFrequency; 944159b3361Sopenharmony_ci 945159b3361Sopenharmony_ci /// \todo Smart mode 946159b3361Sopenharmony_ci if (my_EncodingProperties.GetSmartOutputMode()) 947159b3361Sopenharmony_ci OutputFrequency = ACMStream::GetOutputSampleRate(a_StreamInstance->pwfxSrc->nSamplesPerSec,a_StreamInstance->pwfxDst->nAvgBytesPerSec,a_StreamInstance->pwfxDst->nChannels); 948159b3361Sopenharmony_ci else 949159b3361Sopenharmony_ci OutputFrequency = a_StreamInstance->pwfxSrc->nSamplesPerSec; 950159b3361Sopenharmony_ci 951159b3361Sopenharmony_ci 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); 952159b3361Sopenharmony_ci 953159b3361Sopenharmony_ci /// \todo add the possibility to have channel resampling (mono to stereo / stereo to mono) 954159b3361Sopenharmony_ci /// \todo support resampling ? 955159b3361Sopenharmony_ci /// \todo only do the test on OutputFrequency in "Smart Output" mode 956159b3361Sopenharmony_ci if (a_StreamInstance->pwfxDst->nSamplesPerSec != OutputFrequency || 957159b3361Sopenharmony_ci// a_StreamInstance->pwfxSrc->nSamplesPerSec != a_StreamInstance->pwfxDst->nSamplesPerSec || 958159b3361Sopenharmony_ci a_StreamInstance->pwfxSrc->nChannels != a_StreamInstance->pwfxDst->nChannels || 959159b3361Sopenharmony_ci a_StreamInstance->pwfxSrc->wBitsPerSample != 16) 960159b3361Sopenharmony_ci { 961159b3361Sopenharmony_ci Result = ACMERR_NOTPOSSIBLE; 962159b3361Sopenharmony_ci } else { 963159b3361Sopenharmony_ci if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0) 964159b3361Sopenharmony_ci { 965159b3361Sopenharmony_ci ACMStream * the_stream = ACMStream::Create(); 966159b3361Sopenharmony_ci a_StreamInstance->dwInstance = (DWORD) the_stream; 967159b3361Sopenharmony_ci 968159b3361Sopenharmony_ci if (the_stream != NULL) 969159b3361Sopenharmony_ci { 970159b3361Sopenharmony_ci MPEGLAYER3WAVEFORMAT * casted = (MPEGLAYER3WAVEFORMAT *) a_StreamInstance->pwfxDst; 971159b3361Sopenharmony_ci vbr_mode a_mode = (casted->fdwFlags-2 == 0)?vbr_abr:vbr_off; 972159b3361Sopenharmony_ci if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec, 973159b3361Sopenharmony_ci OutputFrequency, 974159b3361Sopenharmony_ci a_StreamInstance->pwfxDst->nChannels, 975159b3361Sopenharmony_ci a_StreamInstance->pwfxDst->nAvgBytesPerSec, 976159b3361Sopenharmony_ci a_mode)) 977159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 978159b3361Sopenharmony_ci else 979159b3361Sopenharmony_ci ACMStream::Erase( the_stream ); 980159b3361Sopenharmony_ci } 981159b3361Sopenharmony_ci } 982159b3361Sopenharmony_ci else 983159b3361Sopenharmony_ci { 984159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 985159b3361Sopenharmony_ci } 986159b3361Sopenharmony_ci } 987159b3361Sopenharmony_ci } 988159b3361Sopenharmony_ci break; 989159b3361Sopenharmony_ci case PERSONAL_FORMAT: 990159b3361Sopenharmony_ci 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); 991159b3361Sopenharmony_ci if (a_StreamInstance->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) 992159b3361Sopenharmony_ci { 993159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 994159b3361Sopenharmony_ci if ((a_StreamInstance->fdwOpen & ACM_STREAMOPENF_QUERY) == 0) 995159b3361Sopenharmony_ci { 996159b3361Sopenharmony_ci /// \todo create the decoding stream 997159b3361Sopenharmony_ci 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); 998159b3361Sopenharmony_ci 999159b3361Sopenharmony_ci DecodeStream * the_stream = DecodeStream::Create(); 1000159b3361Sopenharmony_ci a_StreamInstance->dwInstance = (DWORD) the_stream; 1001159b3361Sopenharmony_ci 1002159b3361Sopenharmony_ci if (the_stream != NULL) 1003159b3361Sopenharmony_ci { 1004159b3361Sopenharmony_ci if (the_stream->init(a_StreamInstance->pwfxDst->nSamplesPerSec, 1005159b3361Sopenharmony_ci a_StreamInstance->pwfxDst->nChannels, 1006159b3361Sopenharmony_ci a_StreamInstance->pwfxDst->nAvgBytesPerSec, 1007159b3361Sopenharmony_ci a_StreamInstance->pwfxSrc->nAvgBytesPerSec)) 1008159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1009159b3361Sopenharmony_ci else 1010159b3361Sopenharmony_ci DecodeStream::Erase( the_stream ); 1011159b3361Sopenharmony_ci } 1012159b3361Sopenharmony_ci } 1013159b3361Sopenharmony_ci else 1014159b3361Sopenharmony_ci { 1015159b3361Sopenharmony_ci /// \todo decoding verification 1016159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream is valid"); 1017159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1018159b3361Sopenharmony_ci } 1019159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1020159b3361Sopenharmony_ci } 1021159b3361Sopenharmony_ci break; 1022159b3361Sopenharmony_ci } 1023159b3361Sopenharmony_ci 1024159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Open stream Result = %d",Result); 1025159b3361Sopenharmony_ci return Result; 1026159b3361Sopenharmony_ci} 1027159b3361Sopenharmony_ci 1028159b3361Sopenharmony_ciinline DWORD ACM::OnStreamSize(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMDRVSTREAMSIZE the_StreamSize) 1029159b3361Sopenharmony_ci{ 1030159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 1031159b3361Sopenharmony_ci 1032159b3361Sopenharmony_ci switch (ACM_STREAMSIZEF_QUERYMASK & the_StreamSize->fdwSize) 1033159b3361Sopenharmony_ci { 1034159b3361Sopenharmony_ci case ACM_STREAMSIZEF_DESTINATION: 1035159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get source buffer size for destination size = %d",the_StreamSize->cbDstLength); 1036159b3361Sopenharmony_ci break; 1037159b3361Sopenharmony_ci case ACM_STREAMSIZEF_SOURCE: 1038159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "Get destination buffer size for source size = %d",the_StreamSize->cbSrcLength); 1039159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && 1040159b3361Sopenharmony_ci PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) 1041159b3361Sopenharmony_ci { 1042159b3361Sopenharmony_ci ACMStream * the_stream = (ACMStream *) a_StreamInstance->dwInstance; 1043159b3361Sopenharmony_ci if (the_stream != NULL) 1044159b3361Sopenharmony_ci { 1045159b3361Sopenharmony_ci the_StreamSize->cbDstLength = the_stream->GetOutputSizeForInput(the_StreamSize->cbSrcLength); 1046159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1047159b3361Sopenharmony_ci } 1048159b3361Sopenharmony_ci } 1049159b3361Sopenharmony_ci else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && 1050159b3361Sopenharmony_ci WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag) 1051159b3361Sopenharmony_ci { 1052159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 1053159b3361Sopenharmony_ci DecodeStream * the_stream = (DecodeStream *) a_StreamInstance->dwInstance; 1054159b3361Sopenharmony_ci if (the_stream != NULL) 1055159b3361Sopenharmony_ci { 1056159b3361Sopenharmony_ci the_StreamSize->cbDstLength = the_stream->GetOutputSizeForInput(the_StreamSize->cbSrcLength); 1057159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1058159b3361Sopenharmony_ci } 1059159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1060159b3361Sopenharmony_ci } 1061159b3361Sopenharmony_ci break; 1062159b3361Sopenharmony_ci default: 1063159b3361Sopenharmony_ci Result = MMSYSERR_INVALFLAG; 1064159b3361Sopenharmony_ci break; 1065159b3361Sopenharmony_ci } 1066159b3361Sopenharmony_ci 1067159b3361Sopenharmony_ci return Result; 1068159b3361Sopenharmony_ci} 1069159b3361Sopenharmony_ci 1070159b3361Sopenharmony_ciinline DWORD ACM::OnStreamClose(LPACMDRVSTREAMINSTANCE a_StreamInstance) 1071159b3361Sopenharmony_ci{ 1072159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 1073159b3361Sopenharmony_ci 1074159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamClose the stream 0x%X",a_StreamInstance->dwInstance); 1075159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && 1076159b3361Sopenharmony_ci PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) 1077159b3361Sopenharmony_ci { 1078159b3361Sopenharmony_ci ACMStream::Erase( (ACMStream *) a_StreamInstance->dwInstance ); 1079159b3361Sopenharmony_ci } 1080159b3361Sopenharmony_ci else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && 1081159b3361Sopenharmony_ci WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag) 1082159b3361Sopenharmony_ci { 1083159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 1084159b3361Sopenharmony_ci DecodeStream::Erase( (DecodeStream *) a_StreamInstance->dwInstance ); 1085159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1086159b3361Sopenharmony_ci } 1087159b3361Sopenharmony_ci 1088159b3361Sopenharmony_ci // nothing to do yet 1089159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1090159b3361Sopenharmony_ci 1091159b3361Sopenharmony_ci return Result; 1092159b3361Sopenharmony_ci} 1093159b3361Sopenharmony_ci 1094159b3361Sopenharmony_ciinline DWORD ACM::OnStreamPrepareHeader(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMSTREAMHEADER a_StreamHeader) 1095159b3361Sopenharmony_ci{ 1096159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 1097159b3361Sopenharmony_ci 1098159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, " prepare : Src : %d (0x%08X) / %d - Dst : %d (0x%08X) / %d" 1099159b3361Sopenharmony_ci , a_StreamHeader->cbSrcLength 1100159b3361Sopenharmony_ci , a_StreamHeader->pbSrc 1101159b3361Sopenharmony_ci , a_StreamHeader->cbSrcLengthUsed 1102159b3361Sopenharmony_ci , a_StreamHeader->cbDstLength 1103159b3361Sopenharmony_ci , a_StreamHeader->pbDst 1104159b3361Sopenharmony_ci , a_StreamHeader->cbDstLengthUsed 1105159b3361Sopenharmony_ci ); 1106159b3361Sopenharmony_ci 1107159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && 1108159b3361Sopenharmony_ci PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) 1109159b3361Sopenharmony_ci { 1110159b3361Sopenharmony_ci ACMStream * the_stream = (ACMStream *)a_StreamInstance->dwInstance; 1111159b3361Sopenharmony_ci 1112159b3361Sopenharmony_ci if (the_stream->open(my_EncodingProperties)) 1113159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1114159b3361Sopenharmony_ci } 1115159b3361Sopenharmony_ci else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && 1116159b3361Sopenharmony_ci WAVE_FORMAT_PCM == a_StreamInstance->pwfxDst->wFormatTag) 1117159b3361Sopenharmony_ci { 1118159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 1119159b3361Sopenharmony_ci DecodeStream * the_stream = (DecodeStream *)a_StreamInstance->dwInstance; 1120159b3361Sopenharmony_ci 1121159b3361Sopenharmony_ci if (the_stream->open()) 1122159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1123159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1124159b3361Sopenharmony_ci } 1125159b3361Sopenharmony_ci 1126159b3361Sopenharmony_ci return Result; 1127159b3361Sopenharmony_ci} 1128159b3361Sopenharmony_ci 1129159b3361Sopenharmony_ciinline DWORD ACM::OnStreamUnPrepareHeader(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMSTREAMHEADER a_StreamHeader) 1130159b3361Sopenharmony_ci{ 1131159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 1132159b3361Sopenharmony_ci 1133159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "unprepare : Src : %d / %d - Dst : %d / %d" 1134159b3361Sopenharmony_ci , a_StreamHeader->cbSrcLength 1135159b3361Sopenharmony_ci , a_StreamHeader->cbSrcLengthUsed 1136159b3361Sopenharmony_ci , a_StreamHeader->cbDstLength 1137159b3361Sopenharmony_ci , a_StreamHeader->cbDstLengthUsed 1138159b3361Sopenharmony_ci ); 1139159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && 1140159b3361Sopenharmony_ci PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) 1141159b3361Sopenharmony_ci { 1142159b3361Sopenharmony_ci ACMStream * the_stream = (ACMStream *)a_StreamInstance->dwInstance; 1143159b3361Sopenharmony_ci DWORD OutputSize = a_StreamHeader->cbDstLength; 1144159b3361Sopenharmony_ci 1145159b3361Sopenharmony_ci if (the_stream->close(a_StreamHeader->pbDst, &OutputSize) && (OutputSize <= a_StreamHeader->cbDstLength)) 1146159b3361Sopenharmony_ci { 1147159b3361Sopenharmony_ci a_StreamHeader->cbDstLengthUsed = OutputSize; 1148159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1149159b3361Sopenharmony_ci } 1150159b3361Sopenharmony_ci } 1151159b3361Sopenharmony_ci else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && 1152159b3361Sopenharmony_ci WAVE_FORMAT_PCM== a_StreamInstance->pwfxDst->wFormatTag) 1153159b3361Sopenharmony_ci { 1154159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 1155159b3361Sopenharmony_ci DecodeStream * the_stream = (DecodeStream *)a_StreamInstance->dwInstance; 1156159b3361Sopenharmony_ci DWORD OutputSize = a_StreamHeader->cbDstLength; 1157159b3361Sopenharmony_ci 1158159b3361Sopenharmony_ci if (the_stream->close(a_StreamHeader->pbDst, &OutputSize) && (OutputSize <= a_StreamHeader->cbDstLength)) 1159159b3361Sopenharmony_ci { 1160159b3361Sopenharmony_ci a_StreamHeader->cbDstLengthUsed = OutputSize; 1161159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1162159b3361Sopenharmony_ci } 1163159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1164159b3361Sopenharmony_ci } 1165159b3361Sopenharmony_ci 1166159b3361Sopenharmony_ci return Result; 1167159b3361Sopenharmony_ci} 1168159b3361Sopenharmony_ci 1169159b3361Sopenharmony_ciinline DWORD ACM::OnStreamConvert(LPACMDRVSTREAMINSTANCE a_StreamInstance, LPACMDRVSTREAMHEADER a_StreamHeader) 1170159b3361Sopenharmony_ci{ 1171159b3361Sopenharmony_ci DWORD Result = ACMERR_NOTPOSSIBLE; 1172159b3361Sopenharmony_ci 1173159b3361Sopenharmony_ci if (WAVE_FORMAT_PCM == a_StreamInstance->pwfxSrc->wFormatTag && 1174159b3361Sopenharmony_ci PERSONAL_FORMAT == a_StreamInstance->pwfxDst->wFormatTag) 1175159b3361Sopenharmony_ci { 1176159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert SRC = PCM (encode)"); 1177159b3361Sopenharmony_ci 1178159b3361Sopenharmony_ci ACMStream * the_stream = (ACMStream *) a_StreamInstance->dwInstance; 1179159b3361Sopenharmony_ci if (the_stream != NULL) 1180159b3361Sopenharmony_ci { 1181159b3361Sopenharmony_ci if (the_stream->ConvertBuffer( a_StreamHeader )) 1182159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1183159b3361Sopenharmony_ci } 1184159b3361Sopenharmony_ci } 1185159b3361Sopenharmony_ci else if (PERSONAL_FORMAT == a_StreamInstance->pwfxSrc->wFormatTag && 1186159b3361Sopenharmony_ci WAVE_FORMAT_PCM == a_StreamInstance->pwfxDst->wFormatTag) 1187159b3361Sopenharmony_ci { 1188159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert SRC = MP3 (decode)"); 1189159b3361Sopenharmony_ci 1190159b3361Sopenharmony_ci#ifdef ENABLE_DECODING 1191159b3361Sopenharmony_ci DecodeStream * the_stream = (DecodeStream *) a_StreamInstance->dwInstance; 1192159b3361Sopenharmony_ci if (the_stream != NULL) 1193159b3361Sopenharmony_ci { 1194159b3361Sopenharmony_ci if (the_stream->ConvertBuffer( a_StreamHeader )) 1195159b3361Sopenharmony_ci Result = MMSYSERR_NOERROR; 1196159b3361Sopenharmony_ci } 1197159b3361Sopenharmony_ci#endif // ENABLE_DECODING 1198159b3361Sopenharmony_ci } 1199159b3361Sopenharmony_ci else 1200159b3361Sopenharmony_ci my_debug.OutPut(DEBUG_LEVEL_FUNC_CODE, "OnStreamConvert unsupported conversion"); 1201159b3361Sopenharmony_ci 1202159b3361Sopenharmony_ci return Result; 1203159b3361Sopenharmony_ci} 1204159b3361Sopenharmony_ci 1205159b3361Sopenharmony_ci 1206159b3361Sopenharmony_civoid ACM::GetMP3FormatForIndex(const DWORD the_Index, WAVEFORMATEX & the_Format, unsigned short the_String[ACMFORMATDETAILS_FORMAT_CHARS]) const 1207159b3361Sopenharmony_ci{ 1208159b3361Sopenharmony_ci int Block_size; 1209159b3361Sopenharmony_ci char temp[ACMFORMATDETAILS_FORMAT_CHARS]; 1210159b3361Sopenharmony_ci 1211159b3361Sopenharmony_ci 1212159b3361Sopenharmony_ci if (the_Index < bitrate_table.size()) 1213159b3361Sopenharmony_ci { 1214159b3361Sopenharmony_ci // the_Format.wBitsPerSample = 16; 1215159b3361Sopenharmony_ci the_Format.wBitsPerSample = 0; 1216159b3361Sopenharmony_ci 1217159b3361Sopenharmony_ci /// \todo handle more channel modes (mono, stereo, joint-stereo, dual-channel) 1218159b3361Sopenharmony_ci // the_Format.nChannels = SIZE_CHANNEL_MODE - int(the_Index % SIZE_CHANNEL_MODE); 1219159b3361Sopenharmony_ci 1220159b3361Sopenharmony_ci the_Format.nBlockAlign = 1; 1221159b3361Sopenharmony_ci 1222159b3361Sopenharmony_ci the_Format.nSamplesPerSec = bitrate_table[the_Index].frequency; 1223159b3361Sopenharmony_ci the_Format.nAvgBytesPerSec = bitrate_table[the_Index].bitrate * 1000 / 8; 1224159b3361Sopenharmony_ci if (bitrate_table[the_Index].frequency >= mpeg1_freq[SIZE_FREQ_MPEG1-1]) 1225159b3361Sopenharmony_ci Block_size = 1152; 1226159b3361Sopenharmony_ci else 1227159b3361Sopenharmony_ci Block_size = 576; 1228159b3361Sopenharmony_ci 1229159b3361Sopenharmony_ci the_Format.nChannels = bitrate_table[the_Index].channels; 1230159b3361Sopenharmony_ci 1231159b3361Sopenharmony_ci the_Format.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX); 1232159b3361Sopenharmony_ci MPEGLAYER3WAVEFORMAT * tmpFormat = (MPEGLAYER3WAVEFORMAT *) &the_Format; 1233159b3361Sopenharmony_ci tmpFormat->wID = 1; 1234159b3361Sopenharmony_ci // this is the only way I found to know if we do CBR or ABR 1235159b3361Sopenharmony_ci tmpFormat->fdwFlags = 2 + ((bitrate_table[the_Index].mode == vbr_abr)?0:2); 1236159b3361Sopenharmony_ci tmpFormat->nBlockSize = Block_size * the_Format.nAvgBytesPerSec / the_Format.nSamplesPerSec; 1237159b3361Sopenharmony_ci tmpFormat->nFramesPerBlock = 1; 1238159b3361Sopenharmony_ci tmpFormat->nCodecDelay = 0; // 0x0571 on FHG 1239159b3361Sopenharmony_ci 1240159b3361Sopenharmony_ci /// \todo : generate the string with the appropriate stereo mode 1241159b3361Sopenharmony_ci if (bitrate_table[the_Index].mode == vbr_abr) 1242159b3361Sopenharmony_ci wsprintfA( temp, "%d Hz, %d kbps ABR, %s", the_Format.nSamplesPerSec, the_Format.nAvgBytesPerSec * 8 / 1000, (the_Format.nChannels == 1)?"Mono":"Stereo"); 1243159b3361Sopenharmony_ci else 1244159b3361Sopenharmony_ci wsprintfA( temp, "%d Hz, %d kbps CBR, %s", the_Format.nSamplesPerSec, the_Format.nAvgBytesPerSec * 8 / 1000, (the_Format.nChannels == 1)?"Mono":"Stereo"); 1245159b3361Sopenharmony_ci 1246159b3361Sopenharmony_ci MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, the_String, ACMFORMATDETAILS_FORMAT_CHARS); 1247159b3361Sopenharmony_ci } 1248159b3361Sopenharmony_ci } 1249159b3361Sopenharmony_ci 1250159b3361Sopenharmony_civoid ACM::GetPCMFormatForIndex(const DWORD the_Index, WAVEFORMATEX & the_Format, unsigned short the_String[ACMFORMATDETAILS_FORMAT_CHARS]) const 1251159b3361Sopenharmony_ci{ 1252159b3361Sopenharmony_ci the_Format.nChannels = SIZE_CHANNEL_MODE - int(the_Index % SIZE_CHANNEL_MODE); 1253159b3361Sopenharmony_ci the_Format.wBitsPerSample = 16; 1254159b3361Sopenharmony_ci the_Format.nBlockAlign = the_Format.nChannels * the_Format.wBitsPerSample / 8; 1255159b3361Sopenharmony_ci 1256159b3361Sopenharmony_ci 1257159b3361Sopenharmony_ci DWORD a_Channel_Independent = the_Index / SIZE_CHANNEL_MODE; 1258159b3361Sopenharmony_ci 1259159b3361Sopenharmony_ci // first MPEG1 frequencies 1260159b3361Sopenharmony_ci if (a_Channel_Independent < SIZE_FREQ_MPEG1) 1261159b3361Sopenharmony_ci { 1262159b3361Sopenharmony_ci the_Format.nSamplesPerSec = mpeg1_freq[a_Channel_Independent]; 1263159b3361Sopenharmony_ci } 1264159b3361Sopenharmony_ci else 1265159b3361Sopenharmony_ci { 1266159b3361Sopenharmony_ci a_Channel_Independent -= SIZE_FREQ_MPEG1; 1267159b3361Sopenharmony_ci the_Format.nSamplesPerSec = mpeg2_freq[a_Channel_Independent]; 1268159b3361Sopenharmony_ci } 1269159b3361Sopenharmony_ci 1270159b3361Sopenharmony_ci the_Format.nAvgBytesPerSec = the_Format.nSamplesPerSec * the_Format.nChannels * the_Format.wBitsPerSample / 8; 1271159b3361Sopenharmony_ci} 1272159b3361Sopenharmony_ci 1273159b3361Sopenharmony_ciDWORD ACM::GetNumberEncodingFormats() const 1274159b3361Sopenharmony_ci{ 1275159b3361Sopenharmony_ci return bitrate_table.size(); 1276159b3361Sopenharmony_ci} 1277159b3361Sopenharmony_ci 1278159b3361Sopenharmony_cibool ACM::IsSmartOutput(const int frequency, const int bitrate, const int channels) const 1279159b3361Sopenharmony_ci{ 1280159b3361Sopenharmony_ci double compression_ratio = double(frequency * 2 * channels) / double(bitrate * 100); 1281159b3361Sopenharmony_ci 1282159b3361Sopenharmony_ci//my_debug.OutPut(DEBUG_LEVEL_FUNC_DEBUG, "compression_ratio %f, freq %d, bitrate %d, channels %d", compression_ratio, frequency, bitrate, channels); 1283159b3361Sopenharmony_ci 1284159b3361Sopenharmony_ci if(my_EncodingProperties.GetSmartOutputMode()) 1285159b3361Sopenharmony_ci return (compression_ratio <= my_EncodingProperties.GetSmartRatio()); 1286159b3361Sopenharmony_ci else return true; 1287159b3361Sopenharmony_ci} 1288159b3361Sopenharmony_ci 1289159b3361Sopenharmony_civoid ACM::BuildBitrateTable() 1290159b3361Sopenharmony_ci{ 1291159b3361Sopenharmony_ci my_debug.OutPut("entering BuildBitrateTable"); 1292159b3361Sopenharmony_ci 1293159b3361Sopenharmony_ci // fill the table 1294159b3361Sopenharmony_ci unsigned int channel,bitrate,freq; 1295159b3361Sopenharmony_ci 1296159b3361Sopenharmony_ci bitrate_table.clear(); 1297159b3361Sopenharmony_ci 1298159b3361Sopenharmony_ci // CBR bitrates 1299159b3361Sopenharmony_ci for (channel = 0;channel < SIZE_CHANNEL_MODE;channel++) 1300159b3361Sopenharmony_ci { 1301159b3361Sopenharmony_ci // MPEG I 1302159b3361Sopenharmony_ci for (freq = 0;freq < SIZE_FREQ_MPEG1;freq++) 1303159b3361Sopenharmony_ci { 1304159b3361Sopenharmony_ci for (bitrate = 0;bitrate < SIZE_BITRATE_MPEG1;bitrate++) 1305159b3361Sopenharmony_ci { 1306159b3361Sopenharmony_ci 1307159b3361Sopenharmony_ci if (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg1_freq[freq], mpeg1_bitrate[bitrate], channel+1)) 1308159b3361Sopenharmony_ci { 1309159b3361Sopenharmony_ci bitrate_item bitrate_table_tmp; 1310159b3361Sopenharmony_ci 1311159b3361Sopenharmony_ci bitrate_table_tmp.frequency = mpeg1_freq[freq]; 1312159b3361Sopenharmony_ci bitrate_table_tmp.bitrate = mpeg1_bitrate[bitrate]; 1313159b3361Sopenharmony_ci bitrate_table_tmp.channels = channel+1; 1314159b3361Sopenharmony_ci bitrate_table_tmp.mode = vbr_off; 1315159b3361Sopenharmony_ci bitrate_table.push_back(bitrate_table_tmp); 1316159b3361Sopenharmony_ci } 1317159b3361Sopenharmony_ci } 1318159b3361Sopenharmony_ci } 1319159b3361Sopenharmony_ci // MPEG II / II.5 1320159b3361Sopenharmony_ci for (freq = 0;freq < SIZE_FREQ_MPEG2;freq++) 1321159b3361Sopenharmony_ci { 1322159b3361Sopenharmony_ci for (bitrate = 0;bitrate < SIZE_BITRATE_MPEG2;bitrate++) 1323159b3361Sopenharmony_ci { 1324159b3361Sopenharmony_ci if (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg2_freq[freq], mpeg2_bitrate[bitrate], channel+1)) 1325159b3361Sopenharmony_ci { 1326159b3361Sopenharmony_ci bitrate_item bitrate_table_tmp; 1327159b3361Sopenharmony_ci 1328159b3361Sopenharmony_ci bitrate_table_tmp.frequency = mpeg2_freq[freq]; 1329159b3361Sopenharmony_ci bitrate_table_tmp.bitrate = mpeg2_bitrate[bitrate]; 1330159b3361Sopenharmony_ci bitrate_table_tmp.channels = channel+1; 1331159b3361Sopenharmony_ci bitrate_table_tmp.mode = vbr_abr; 1332159b3361Sopenharmony_ci bitrate_table.push_back(bitrate_table_tmp); 1333159b3361Sopenharmony_ci } 1334159b3361Sopenharmony_ci } 1335159b3361Sopenharmony_ci } 1336159b3361Sopenharmony_ci } 1337159b3361Sopenharmony_ci 1338159b3361Sopenharmony_ci if (my_EncodingProperties.GetAbrOutputMode()) 1339159b3361Sopenharmony_ci // ABR bitrates 1340159b3361Sopenharmony_ci { 1341159b3361Sopenharmony_ci for (channel = 0;channel < SIZE_CHANNEL_MODE;channel++) 1342159b3361Sopenharmony_ci { 1343159b3361Sopenharmony_ci // MPEG I 1344159b3361Sopenharmony_ci for (freq = 0;freq < SIZE_FREQ_MPEG1;freq++) 1345159b3361Sopenharmony_ci { 1346159b3361Sopenharmony_ci for (bitrate = my_EncodingProperties.GetAbrBitrateMax(); 1347159b3361Sopenharmony_ci bitrate >= my_EncodingProperties.GetAbrBitrateMin(); 1348159b3361Sopenharmony_ci bitrate -= my_EncodingProperties.GetAbrBitrateStep()) 1349159b3361Sopenharmony_ci { 1350159b3361Sopenharmony_ci if (bitrate >= mpeg1_bitrate[SIZE_BITRATE_MPEG1-1] && (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg1_freq[freq], bitrate, channel+1))) 1351159b3361Sopenharmony_ci { 1352159b3361Sopenharmony_ci bitrate_item bitrate_table_tmp; 1353159b3361Sopenharmony_ci 1354159b3361Sopenharmony_ci bitrate_table_tmp.frequency = mpeg1_freq[freq]; 1355159b3361Sopenharmony_ci bitrate_table_tmp.bitrate = bitrate; 1356159b3361Sopenharmony_ci bitrate_table_tmp.channels = channel+1; 1357159b3361Sopenharmony_ci bitrate_table_tmp.mode = vbr_abr; 1358159b3361Sopenharmony_ci bitrate_table.push_back(bitrate_table_tmp); 1359159b3361Sopenharmony_ci } 1360159b3361Sopenharmony_ci } 1361159b3361Sopenharmony_ci } 1362159b3361Sopenharmony_ci // MPEG II / II.5 1363159b3361Sopenharmony_ci for (freq = 0;freq < SIZE_FREQ_MPEG2;freq++) 1364159b3361Sopenharmony_ci { 1365159b3361Sopenharmony_ci for (bitrate = my_EncodingProperties.GetAbrBitrateMax(); 1366159b3361Sopenharmony_ci bitrate >= my_EncodingProperties.GetAbrBitrateMin(); 1367159b3361Sopenharmony_ci bitrate -= my_EncodingProperties.GetAbrBitrateStep()) 1368159b3361Sopenharmony_ci { 1369159b3361Sopenharmony_ci if (bitrate >= mpeg2_bitrate[SIZE_BITRATE_MPEG2-1] && (!my_EncodingProperties.GetSmartOutputMode() || IsSmartOutput(mpeg2_freq[freq], bitrate, channel+1))) 1370159b3361Sopenharmony_ci { 1371159b3361Sopenharmony_ci bitrate_item bitrate_table_tmp; 1372159b3361Sopenharmony_ci 1373159b3361Sopenharmony_ci bitrate_table_tmp.frequency = mpeg2_freq[freq]; 1374159b3361Sopenharmony_ci bitrate_table_tmp.bitrate = bitrate; 1375159b3361Sopenharmony_ci bitrate_table_tmp.channels = channel+1; 1376159b3361Sopenharmony_ci bitrate_table_tmp.mode = vbr_abr; 1377159b3361Sopenharmony_ci bitrate_table.push_back(bitrate_table_tmp); 1378159b3361Sopenharmony_ci } 1379159b3361Sopenharmony_ci } 1380159b3361Sopenharmony_ci } 1381159b3361Sopenharmony_ci } 1382159b3361Sopenharmony_ci } 1383159b3361Sopenharmony_ci 1384159b3361Sopenharmony_ci // sorting by frequency/bitrate/channel 1385159b3361Sopenharmony_ci std::sort(bitrate_table.begin(), bitrate_table.end()); 1386159b3361Sopenharmony_ci 1387159b3361Sopenharmony_ci/* { 1388159b3361Sopenharmony_ci // display test 1389159b3361Sopenharmony_ci int i=0; 1390159b3361Sopenharmony_ci for (i=0; i<bitrate_table.size();i++) 1391159b3361Sopenharmony_ci { 1392159b3361Sopenharmony_ci my_debug.OutPut("bitrate_table[%d].frequency = %d",i,bitrate_table[i].frequency); 1393159b3361Sopenharmony_ci my_debug.OutPut("bitrate_table[%d].bitrate = %d",i,bitrate_table[i].bitrate); 1394159b3361Sopenharmony_ci my_debug.OutPut("bitrate_table[%d].channel = %d",i,bitrate_table[i].channels); 1395159b3361Sopenharmony_ci my_debug.OutPut("bitrate_table[%d].ABR = %s\n",i,(bitrate_table[i].mode == vbr_abr)?"ABR":"CBR"); 1396159b3361Sopenharmony_ci } 1397159b3361Sopenharmony_ci }*/ 1398159b3361Sopenharmony_ci 1399159b3361Sopenharmony_ci my_debug.OutPut("leaving BuildBitrateTable"); 1400159b3361Sopenharmony_ci} 1401