C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[892] WMA TO MP3 lame_enc.dll + bass.dll,basswma.dll 사용법
박영목.월천 [gsbsoft] 11031 읽음    2009-05-12 16:20
월천 박영목입니다...  ㅋㅋㅋ 행복하시지요... 저도 행복합니다..  감사합니다.

(소스, dll, 실행파일 올렸습니다...  수정했음..)

지금...  매장음악방송 쪽에서 일합니다. 면접 볼 때 프로그램 조금만 하고 관리만 한번씩 하면 된다..

그래서 월급도 많이 깍아주고.. 이제 노년을 좀 편히 보내자 하고 그냥 들어왔는데.. 이거 뭐...

제가 보니 할 것이 엉청나게 많군요... ㅋㅋㅋ 플레이어도 다 다시 만들어야 할 판...... ㅋㅋㅋ

매장들이 인터넷 환경이 않좋아 실시간 플레이가 힘던 곳이 제법 있고..  그런데 core쪽 소스는

dll로 다 감추어져 있고(외주, Win32, 다음에도 VC로 해야함) 수정하려고 해도... 인터페이스 약간...

모니터링 쪽은 실시간도 힘들고..

다른 일들이 바빠서...  그런데 음원 파일을 변환하는 것도 장난이 아니더군요... 몇 만곡씩 되니..

MP3도 Bitrate별로 있어야 하고...  이것도 일반적인 변환프로그램으로 돌리는 데... 신경이 너무 쓰인

다고.. ㅋㅋㅋ 그래서 그런 것 만들면 되는 데..  했더니 만들어라고... ㅋㅋㅋ   괘히 말했나...

이것 만들어 주니... WMA도 .. 쩝 그래서.. WMA도 ffmpeg로 간단히 만들어 주었더니... 나는 하나만

돌리는 줄 알았는데.. 이것을 8개를 돌리고 있더군요.. 서버가 죽어요...ㅋㅋㅋ.  기가 막힘... 그래서..

좀 더 효율 좋게... 그러면서 이쪽으로 공부 했습니다. 음악도 들어가며 음질 TEST도 하고...

소스에 적혀 있으니 참고 하시기 바랍니다....  아참 그리고 가변 비트레이드 VBR  사용하지 마세요..

64K 에서는 쇠소리가 더 납니다. CBR로 하세요.. 용량도 그렇게 차이가 안납니다...

VBR은 가변이라 파일 용량적인 효과는 있겠지만... CPU가 힘들겠지요...

여러가지 호환적인 문제도 있고... 저는 사용하지 않았습니다.

그리고 64kbps 에서 모노나 스트레오.. 용량 차이가 거의 없습니다.   제가 모노로 하면 용량이 더 줄

것인데.. 하니..  팀장이 그러더라구요.. 하실 수 있으면 해보시라고... 그래서 용량을 더 줄려 보려고

변환 프로그램으로 모노로 해도 거의 차이가 없었습니다. 왜 그렇지... 팀장도 이유는 모른다고 나도

생각 안남... 그래서 1시간 후에 화장실에 들어가는 순간 그 냄새가... 그 비밀을 알려 주었습니다.

ㅋㅋㅋ  화장실 자주 가세요,,,  안되면 ㅋㅋㅋ   분명한 효과가 있습니다.   ㅋㅋㅋ 간단한 것인데...

MP3은 손실 압축이지요... 그런데 64K까지 내리면서 톡톡 튀는 놈들은 둘글게 깎여서... 2개의 파형

값이 거의 동일하게 바뀌게 되지요... 그리고 여기에 압축을 해버리니... 1+1 = 거의 1 이 되지요...

압축이니.. 같은 것은 1개로 만들어 버리니..   간단한 것인데... ㅋㅋㅋ....

그런데 음질은 모노가 더 좋았습니다. 스테레오보다.,.. 그런데 JSTEREO로 하니 동일한 것으로

들렸음....  ㅋㅋㅋ    ... 에고 부산역 분수 프로그램은 언제 만드나,.,, 날짜는 다가 오고... ㅋㅋㅋ


물러갑니다... 부산에서....   월천 박영목 올렸습니다.   다들 행복하세요.. ^^



//---------------------------------------------------------------------------

#include <vcl.h>
#include <process.h>
#include <stdio.h>
#pragma hdrstop

#include "basswma.h"
#include "lame.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "bass.lib"
#pragma link "basswma.lib"
#pragma link "lame_enc.lib"
#pragma link "CGAUGES"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

bool __fastcall DeleteFilePerfect( AnsiString asDes )
{
  FileSetReadOnly( asDes, false );      //파일속성을 Normal로 바꾸고
  bool bRet = DeleteFile( asDes );

  return bRet;
}

void __fastcall TForm1::ShowStatus( AnsiString Msg )
{
  if( MemoStatus->Lines->Count>50 )
    MemoStatus->Lines->Delete( 0 );

  MemoStatus->Lines->Add( Msg );
}

void __fastcall TForm1::WMStartConv( TMessage msg )
{
  switch( msg.WParam )
  {
    /*
    case 192 :                                //이렇게 변환할 분들은 하시고..
               CGauge192->MaxValue = 100;
               CGauge192->MinValue = 0;
               CGauge192->Progress = 0;
               break;

    case 128 :
               CGauge128->MaxValue = 100;
               CGauge128->MinValue = 0;
               CGauge128->Progress = 0;
               break;
    case 64  :
               CGauge64->MaxValue = 100;
               CGauge64->MinValue = 0;
               CGauge64->Progress = 0;
               break;
    */

    CGauge1->MinValue = 0;
    CGauge1->Progress = 0;
  }
}

void __fastcall TForm1::WMCurConv( TMessage msg )
{
  switch( msg.WParam )
  {
    CGauge1->Progress = msg.LParam;
  }

}

void __fastcall TForm1::WMEndConv( TMessage msg )
{
  //TListItems *ltItems;
  AnsiString asMsg;

  //switch( msg.WParam )
  //{
    if( msg.LParam==1 )
      ShowStatus( "INF: OK" );
    else
      ShowStatus( "ERR: Failure" );
   // break;
  //}
}

void __fastcall SendPostMsg( HWND hMain, DWORD dwMsg, DWORD dwBitrate, DWORD dwStatus )
{
  int i=15;
  while( i-- )
  {
    if( ::PostMessage( hMain, dwMsg, (DWORD)dwBitrate, dwStatus )==true )
      break;

    Sleep( 100 );
  }
}

typedef struct ST_CONV
{
  HWND       hMain;
  AnsiString asInFile;
  AnsiString asOutFile;

  DWORD      dwBitrate;
  DWORD      dwSampleRate;
} stConv;



static unsigned __stdcall FuncThreadConv( void* lParam )
{
  stConv *stData = (stConv*)lParam;

  HWND hMain = stData->hMain;
  AnsiString asInFullFileName  = stData->asInFile;
  AnsiString asOutFullFileName = stData->asOutFile;

  DWORD dwWantBitrate          = stData->dwBitrate;
  DWORD dwSampleRate           = stData->dwSampleRate;

  delete stData;
  //----------------------------------------------------------------------------

  int iSleep = 4;
  if( dwWantBitrate==64 ) iSleep = 2;                                           //이것은 쓰레드로 돌릴 떄 64rk 더 오래 걸려서... 좀 빠르게 한 것입니다. 빼셔도 됨... 회사에 맞게 맞추다 보니 들어갔네요...

  DWORD dwStatus = 0;

  //BE_VERSION    Version        = { 0, };
  BE_CONFIG    beConfig    = { 0, };

  DWORD    dwSamples        = 0;
  DWORD    dwMP3Buffer        = 0;

  BE_ERR    err        = 0;
  FILE*    pFileOut        = NULL;
  HBE_STREAM    hbeStream    = 0;

  PBYTE    pMP3Buffer        = NULL;
  PSHORT    pWAVBuffer        = NULL;

  DWORD chan;
  //----------------------------------------------------------------------------

  float time;
  int iPlayTime=0;

  chan = BASS_WMA_StreamCreateFile( false, asInFullFileName.c_str(),0,0,BASS_STREAM_DECODE );

  if( chan==0 )
  {
    SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );

    _endthreadex( GetCurrentThreadId() );
    return -11;                                                                 //입력 MP3 열기 실패
  }

  time = BASS_ChannelBytes2Seconds( chan, BASS_ChannelGetLength( chan, BASS_POS_BYTE ) );        // playback duration

  iPlayTime = (time*1000) + 0.5;                                                //MP3 연주전체시간

  if( iPlayTime==0 )
  {
    if( chan )
      BASS_StreamFree( chan );

    SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );

    _endthreadex( GetCurrentThreadId() );

    return -11;                                                                 //입력 MP3 열기 실패
  }
  //---------------------------------------------------------------------------

  BASS_INFO        bass_info;
  BASS_CHANNELINFO bass_channel_info;

  bool bRet          = BASS_GetInfo( &bass_info );
  DWORD len          = BASS_StreamGetFilePosition( chan, BASS_FILEPOS_END );    //file length
  DWORD BitrateOfMP3 = (DWORD)(len/(125*time)+0.5);                             //bitrate (Kbps)  125가 뭔지 모르겠음... 아는 사람 연락바람... ㅋㅋㅋ
  //---------------------------------------------------------------------------

  //아래까지 내려오면 만약에 iBitRate의 값에 근접한다면 그냥 파일을 복사한다.
  //근접한다는 범위를 어떻게 결정할 것인가?
  //비트레이트가 낮은 것은 아래 것은
  //파일의 비트레이트를 가지고 온 것이 192짜리이다.
  //그러면 192는 그냥 복사를 한다. 128, 64는 변환을 한다.
  //128이다  192, 128 그냥 복사, 64변환....
  //64보다 더 낮은 것은 그냥 다 복사를 한다.
  //16 이상 차이가 나야 한다.


  //int iCab = BitrateOfMP3 - dwWantBitrate;                                      //현재 파일의 Bitrate - 바꾸기를 원하는 Bitrate
  //if( iCab<0 ) iCab *= -1;

  //if( (iCab<=16) || (dwWantBitrate>BitrateOfMP3) )                              //bitrate의 차가 16보다 작거나 변환하고자 하는 bitrate가 더 클 경우 그냥 복사한다.
  //{
  //  if( chan )
  //    BASS_StreamFree( chan );
  //  bool bSuccess=false;
  //DeleteFilePerfect( asOutFullFileName );
  //  bSuccess = CopyFileTo( asInFullFileName, asOutFullFileName );               //bSuccess 믿을 수 없음...

  //  if( GetLargeFileSize( asInFullFileName ) == GetLargeFileSize( asOutFullFileName ) )
  //    dwStatus = 1;
  //  SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );
  //  _endthreadex( GetCurrentThreadId() );
  //  return 1;                                                                   //성공: 파일 복사 or Thread 시작
  //}
  //else

  {
    bRet = BASS_ChannelGetInfo( chan, &bass_channel_info );
    //---------------------------------------------------------------------------

    // use the LAME config structure
    beConfig.dwConfig                           = BE_CONFIG_LAME;

    // this are the default settings for testcase.wav
    beConfig.format.LHV1.dwStructVersion    = 1;
    beConfig.format.LHV1.dwStructSize        = sizeof(beConfig);
    beConfig.format.LHV1.dwSampleRate        = bass_channel_info.freq;       //현재 원본 파일의 SampleRate이다. 여기에 dwSampleRate 이 값을 넣을 경우 나도 넣었다. ㅋㅋㅋ 바꿀 샘플레이트가 동일하면 아무 이상 없지만 원본이 클 경우 연주 시간이 늘어나게 된다. 물론 음도 모두 늘어나게 된다.

    if( dwWantBitrate<=64 ) beConfig.format.LHV1.dwReSampleRate = 0;
    else beConfig.format.LHV1.dwReSampleRate    = dwSampleRate;                 //64이하 일 경우는 '0'으로 주어 Encoder가 알아서 하게 두면 음질이 더 좋습니다. 그렇지 않고 강제로 조정할 경우 음질이 약간 쇠소리를가 흐르게 된다. 물론 자세히 들어야 하지만 그러나 느낌이 싱글럽다는 느낌을 느낄 수 있다.

    if( bass_channel_info.chans==1 )
      beConfig.format.LHV1.nMode                = BE_MP3_MODE_MONO;
    else
      beConfig.format.LHV1.nMode                = BE_MP3_MODE_JSTEREO;        

    beConfig.format.LHV1.dwBitrate        = dwWantBitrate;
    beConfig.format.LHV1.nPreset            = LQP_NOPRESET;
    beConfig.format.LHV1.nQuality               = LQP_VERYHIGH_QUALITY;
    beConfig.format.LHV1.dwMpegVersion        = MPEG1;            // MPEG VERSION (I or II)
    beConfig.format.LHV1.dwPsyModel        = 0;                // USE DEFAULT PSYCHOACOUSTIC MODEL
    beConfig.format.LHV1.dwEmphasis        = 0;                // NO EMPHASIS TURNED ON
    beConfig.format.LHV1.bOriginal        = FALSE;                        //TRUE;                    // SET ORIGINAL FLAG
    beConfig.format.LHV1.bWriteVBRHeader    = FALSE;                        //TRUE;                    // Write INFO tag

    beConfig.format.LHV1.dwMaxBitrate        = dwWantBitrate;                //128; //320;                // MAXIMUM BIT RATE
    beConfig.format.LHV1.bCRC            = FALSE;                        //TRUE;                    // INSERT CRC
    beConfig.format.LHV1.bCopyright        = FALSE;                        //TRUE;                    // SET COPYRIGHT FLAG
    beConfig.format.LHV1.bPrivate        = FALSE;                        //TRUE;                    // SET PRIVATE FLAG
    beConfig.format.LHV1.bWriteVBRHeader            = FALSE;                //TRUE;                    // YES, WRITE THE XING VBR HEADER
    beConfig.format.LHV1.bEnableVBR        = FALSE;                        //TRUE;                    // USE VBR
    beConfig.format.LHV1.nVBRQuality        = 0;                            //5;                             // SET VBR QUALITY

    beConfig.format.LHV1.bNoRes                = FALSE;                        //TRUE;                    // No Bit resorvoir


    // Init the MP3 Stream
    err = beInitStream( &beConfig, &dwSamples, &dwMP3Buffer, &hbeStream );

    // Check result
    if( err != BE_ERR_SUCCESSFUL )
    {
      SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );
      _endthreadex( GetCurrentThreadId() );
      return -21;                                                               //Failure... MP3 출력 beInitStream
    }
    //--------------------------------------------------------------------------

    // Allocate MP3 buffer
    pMP3Buffer = new BYTE[dwMP3Buffer+10];
    //------------------------------------

    // Allocate WAV buffer
    pWAVBuffer = new SHORT[dwSamples+1];

    // Check if Buffer are allocated properly
    if( !pMP3Buffer || !pWAVBuffer )                                            //메모리 확보를 못했으면.... 빠져나감..
    {
      if( pMP3Buffer ) delete []pMP3Buffer;
      if( pWAVBuffer ) delete []pWAVBuffer;

      if( chan )
        BASS_StreamFree( chan );

      if( hbeStream )
        beCloseStream( hbeStream );

      SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );

      _endthreadex( GetCurrentThreadId() );

      return 0;  //일반적인 실패
    }
   //---------------------------------------------------------------------------

   pFileOut= fopen( asOutFullFileName.c_str() ,"wb+");

   // Check file open result
   if( pFileOut==NULL )
   {
     if( pMP3Buffer ) delete []pMP3Buffer;
     if( pWAVBuffer ) delete []pWAVBuffer;

     if( chan )
       BASS_StreamFree( chan );

     if( hbeStream )
       beCloseStream( hbeStream );

     SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );

     _endthreadex( GetCurrentThreadId() );
     return -1;    //Failure Open OutFile
   }
  }
  //----------------------------------------------------------------------------

  //메인에게 변환을 시작한다고 알린다.  그리고 시작한다.
  SendPostMsg( hMain, WM_USER_START_PROCESS, (DWORD)dwWantBitrate, dwStatus );

  bool bStart = true;                                                           //쓰레드 공유
  //----------------------------------------------------------------------------

  DWORD nr, dwWrite;
  DWORD inc=0;
  QWORD c, pos;
  QWORD qwTotLength = BASS_ChannelGetLength(chan, BASS_POS_BYTE);
  int   iProcess;

  float dwDDD = 0;

  int iStore=0;

  int i=1;
  while( 1 )                                                                    //BASS_ChannelIsActive( chan ) )  //BASS_ChannelGetData( chan, pWAVBuffer, dwSamples * 2 )>0 )  //SizeOf(SmallInt));
  {
    if( bStart==true )
    {
      if( BASS_ChannelIsActive( chan ) )
      {
        c = BASS_ChannelGetData( chan, pWAVBuffer, dwSamples * 2 );          //c = BASS_ChannelGetData( chan, pWAVBuffer, dwSamples * 2 );   pIMSIWAVBuffer

        if( c==-1 )
        {
          bStart = false;
          continue;
        }

        err = beEncodeChunk( hbeStream, dwSamples, pWAVBuffer, pMP3Buffer, &dwWrite );   // dwSamples

        if( err==BE_ERR_SUCCESSFUL )
        {
          if( fwrite(pMP3Buffer,1,dwWrite,pFileOut) != dwWrite )
          {
            bStart = false;
            continue;
          }
          else
          {
            dwDDD += c;
            iProcess = (dwDDD/qwTotLength) * 100;

            ::PostMessage( hMain, WM_USER_CUR_PROCESS, (DWORD)dwWantBitrate, iProcess );
          }
        }
        else
        {
          bStart = false;
          continue;
        }

        ::Sleep( iSleep );
     }
     else
     {
       err = beDeinitStream( hbeStream, pMP3Buffer, &dwWrite );

       if( err!=BE_ERR_SUCCESSFUL )
       {
         bStart = false;
         continue;
       }
       else
       {
         if( dwWrite )
         {
           if( fwrite( pMP3Buffer,1,dwWrite,pFileOut ) != dwWrite )
           {
             bStart = false;
             continue;
           }
         }
       }

       fclose( pFileOut );
       pFileOut = NULL;

       ::Sleep(1000);     //이것은 파일을 닫는 부분을 윈도우에서 일을 잘 처리하라고 주는 것입니다.  한번씩 이런 것 주세요...
       ::Sleep(1000);     //전전 회사에서 설치프로그램(NSIS)에 이런 것 넣지 않아 제가 들어간 후 3일만에 팀장 짤렸습니다. 분명이 파일을 지우고 떺어 쉬우게 해 두었는데.
                          //지우자 말자 바로 쓰니... 쓰지지 않지... 이것 때문에 짤렸으니... 자기도 어떤 때는 되고  어떤 때는 안된다고... 소스 좀 봐달라고 하면 봐주었을 것인데..
                          //마우스도 못만지게 하니... 그때 생각하면 마음이 아픔.....  지금 팀장은 논리적이고 사람이 좋음... ㅋㅋㅋ
       //-----------------------------------------------------------------------

       float fplaytime = 0;
       int   iTotTime  = 0;

       DWORD dwchan;

       dwchan = BASS_StreamCreateFile( false, asOutFullFileName.c_str(),0,0,BASS_STREAM_DECODE );
       if( dwchan==0 )
       {
         dwchan = BASS_MusicLoad( false, asOutFullFileName.c_str(), 0, 0, BASS_MUSIC_DECODE|BASS_MUSIC_RAMP|BASS_MUSIC_PRESCAN, 0 );         //BASS_MUSIC_RAMPS|BASS_MUSIC_POSRESET|BASS_MUSIC_PRESCAN
       }

       if( dwchan )
       {
         fplaytime = BASS_ChannelBytes2Seconds( dwchan, BASS_ChannelGetLength(dwchan, BASS_POS_BYTE) ); // playback duration
         iTotTime = (fplaytime * 1000) + 0.5;

         if( iTotTime>0 )
         {
           int iTimeCap = iPlayTime - iTotTime;

           if( iTimeCap<0 )     iTimeCap *= -1;
           if( iTimeCap<=2000 ) dwStatus=1;
         }

         BASS_StreamFree( dwchan );
       }

       bStart = false;
       continue;
     }
   }
   else  //bStart
   {
     break;
   }
  }
  //----------------------------------------------------------------------------

  if( pMP3Buffer!=NULL )
    delete []pMP3Buffer;

  if( pWAVBuffer!=NULL )
    delete []pWAVBuffer;
  //----------------------------------------------------------------------------

  if( chan )
  {
    BASS_StreamFree( chan );
    chan = 0;
  }

  if( hbeStream )
  {
    beCloseStream( hbeStream );
    hbeStream = 0;
  }

  if( pFileOut )
  {
    fclose( pFileOut );
    pFileOut=NULL;
  }

  if( dwStatus==0 )
  {
    ::Sleep( 1000 );
    ::Sleep( 1000 );

    DeleteFilePerfect( asOutFullFileName );
  }


  SendPostMsg( hMain, WM_USER_END_PROCESS, dwWantBitrate, dwStatus );


  _endthreadex( GetCurrentThreadId() );

  return 0;
}



//FuncThreadConv  이 함수 보면 안에 같은 것들이 계속 나올 것입니다. 왜 이렇게 했는지. 묻지 마세요..
//빨리 만들어야 하는데... 반복되는 것 다 빼서 예쁘게 함수를 따로 만드니...  계속 Error가 발생,...
//그래서 겁이 나서 다 풀어 헤쳐 놓았음....  1개는 잘 돌아는데 쓰레드 돌리면.. 이게 죽어... lame_enc 때문인 것 같은데...
//그래서 Error 안 나는 까지.. 다 넣어 버렸음.... ㅋㅋㅋㅋ  이유는 담에 알아봐요지요... 중첩인지.. 뭔지...
//지금은 바빠서....  참 그리고 쓰레드       _beginthreadex으로 하세요... TThread로 하지 마시고  이것 때문에... 좀 힘들었음.. ㅋㅋㅋ
//이것도  lame_enc  때문인 것 같은데... ㅋㅋㅋㅋ 그레도 쓰레드 돌리니.. 잘 됩니다.


void __fastcall TForm1::Button1Click(TObject *Sender)
{

  #define NTHREADS  1
  HANDLE hThreads[NTHREADS];


   int i;
   unsigned threadId;
   SECURITY_ATTRIBUTES  sa = {
          sizeof(SECURITY_ATTRIBUTES), /* structure size */
          0,      /* No security descriptor */
          TRUE    /* Thread handle is inheritable */
   };
   //---------------------------------------------------------------------------

   stConv *pData192        = new stConv;
   pData192->hMain         = this->Handle;
   pData192->asInFile      = edWMAFile->Text;  //"D:\\WMA_MP3\\3DM00137205.wma";     //"D:\\CurProject\\CBuilder\\FTP\\Temp\\0de4ec607098343e5bc3122dbcf10edb.mp3";
   pData192->asOutFile     = edMP3File->Text;  //"D:\\WMA_MP3\\3DM00137205_128.mp3";   //D:\\files\\bank97\\musics\\0de4ec607098343e5bc3122dbcf10edb.mp3";

   pData192->dwBitrate     = 128;
   pData192->dwSampleRate  = 44100;

   hThreads[0] = (HANDLE)_beginthreadex(
         &sa,          /* Thread security */
         10240,         /* Thread stack size */
         FuncThreadConv,   /* Thread starting address */
         (void *)pData192,    /* Thread start argument */
         CREATE_SUSPENDED,  /* Create in suspended state */
         &threadId);   /* Thread ID */

   ResumeThread(hThreads[0]);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    if( BASS_Init(0,44100,0,Application->Handle,NULL)==false )                  //변환 프로그램은 사운드카드가 필요없다. 그래서 이렇게 했는데... 서버에는  Remote Desktop Protocol (RDP) 잡혀 있다. 이것은 어떤 가상 드라이버로 보여진다. BASS에서는 이것을 지원하지 않는 것으로 보인다.
    {
      MessageBox( this->Handle, "Can''t initialize device", "Warning", MB_OK );

      ::PostMessage( this->Handle, WM_CLOSE, 0, 0 );
      return;
    }
    //--------------------------------------------------------------------------
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  BASS_Free();
}
//---------------------------------------------------------------------------
nicekr.황경록 [mpbox]   2009-05-21 16:26 X
항상 좋은 경험 공유해 주셔서 감사드립니다 ^^*
박영목.월천 [gsbsoft]   2009-05-21 20:28 X
ㅋㅋㅋ  아... 황선생님... 올만입니다... 감사합니다....  잘 지내시지요.... ^^

+ -

관련 글 리스트
892 WMA TO MP3 lame_enc.dll + bass.dll,basswma.dll 사용법 박영목.월천 11031 2009/05/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.