Convert Sounds with ACM

Windows specific forum
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Convert Sounds with ACM

Post by zapman* »

I'm getting mad with Audio Compression Manager (ACM) !

The following code works well to convert PCM to PCM (changing the sampling rate, for exemple). But when I want to use it to convert an MP3 file to a WAV file, I get the message "NO DRIVER". If anyone can help me, he will save my life !


If you want to try it to convert PCM files, just replace

afc\fdwEnum = #ACM_FORMATENUMF_SUGGEST (comment it)

by

afc\fdwEnum = #ACM_FORMATENUMF_WFORMATTAG (uncomment it)

Code: Select all


; Convert a Sound with ACM
; by Zapman
; WORK IN PROGRESS !

#WAVE_FORMAT_ADPCM = 2
#WAVE_FORMAT_ALAW = 6
#WAVE_FORMAT_MULAW = 7
#WAVE_FORMAT_DVI_ADPCM = 17
#WAVE_FORMAT_G723_ADPCM         = $0014
#WAVE_FORMAT_DIALOGIC_OKI_ADPCM = $0017
#WAVE_FORMAT_TRUESPEECH         = $0022
#WAVE_FORMAT_GSM610             = $0031
#WAVE_FORMAT_G721_ADPCM         = $0040 ;* Antex Electronics G.721 */
#WAVE_FORMAT_G728_CELP          = $0041
#WAVE_FORMAT_MSG723             = $0042
#WAVE_FORMAT_MPEG               = $0050 ;/* MPEG Layer 1,2 */
#WAVE_FORMAT_MPEGLAYER3         = $0055 ;/* MPEG Layer 3 (MP3)*/
#WAVE_FORMAT_VOXWARE            = $0062
#WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = $0069
#WAVE_FORMAT_VOXWARE_RT24       = $0074
#WAVE_FORMAT_VOXWARE_RT29       = $0075
#ACM_DRIVERENUMF_NOLOCAL  = $40000000
#ACM_DRIVERENUMF_DISABLED = $80000000

;

#ACMERR_NOTPOSSIBLE = 512
#ACM_METRIC_MAX_SIZE_FORMAT = 50

;

#ACMDRIVERDETAILS_SHORTNAME_CHARS    =32
#ACMDRIVERDETAILS_LONGNAME_CHARS     =128
#ACMDRIVERDETAILS_COPYRIGHT_CHARS    =80
#ACMDRIVERDETAILS_LICENSING_CHARS    =128
#ACMDRIVERDETAILS_FEATURES_CHARS     =512
#ACMFORMATTAGDETAILS_FORMATTAG_CHARS =48

;

#ACMFILTERDETAILS_FILTER_CHARS       =128
#ACM_FILTERENUMF_DWFILTERTAG         =$00010000

;

#ACMFORMATDETAILS_FORMAT_CHARS       =128
#ACMFILTERTAGDETAILS_FILTERTAG_CHARS =48
#ACM_FORMATTAGDETAILSF_INDEX         =0
#ACM_STREAMCONVERTF_BLOCKALIGN       =$00000004
#ACM_STREAMCONVERTF_START            =$00000010
#ACM_STREAMCONVERTF_END              =$00000020
#ACM_STREAMOPENF_NONREALTIME         =4
#WAVE_FILTER_UNKNOWN = 0
#WAVE_FORMAT_UNKNOWN = 0

;

#ACMDRIVERDETAILS_SUPPORTF_CODEC     =$00000001
#ACMDRIVERDETAILS_SUPPORTF_CONVERTER =$00000002
#ACMDRIVERDETAILS_SUPPORTF_FILTER    =$00000004
#ACMDRIVERDETAILS_SUPPORTF_HARDWARE  =$00000008
#ACMDRIVERDETAILS_SUPPORTF_ASYNC     =$00000010
#ACMDRIVERDETAILS_SUPPORTF_LOCAL     =$40000000
#ACMDRIVERDETAILS_SUPPORTF_DISABLED  =$80000000

;

#ACM_FORMATENUMF_WFORMATTAG       =$00010000
#ACM_FORMATENUMF_NCHANNELS        =$00020000
#ACM_FORMATENUMF_NSAMPLESPERSEC   =$00040000
#ACM_FORMATENUMF_WBITSPERSAMPLE   =$00080000
#ACM_FORMATENUMF_CONVERT          =$00100000
#ACM_FORMATENUMF_SUGGEST          =$00200000
#ACM_FORMATENUMF_HARDWARE         =$00400000
#ACM_FORMATENUMF_INPUT            =$00800000
#ACM_FORMATENUMF_OUTPUT           =$01000000

;

#MPEGLAYER3_WFX_EXTRA_BYTES  =  2
#MPEGLAYER3_FLAG_PADDING_ISO =  $00000000
#MPEGLAYER3_FLAG_PADDING_ON  =  $00000001
#MPEGLAYER3_FLAG_PADDING_OFF =  $00000002
#MPEGLAYER3_ID_UNKNOWN       =  0
#MPEGLAYER3_ID_MPEG          =  1
#MPEGLAYER3_ID_CONSTANTFRAMESIZE = 2
#MP3_BLOCK_SIZE = 522
#ACM_STREAMSIZEF_SOURCE       =   $00000000
#ACM_STREAMSIZEF_DESTINATION  =   $00000001
#ACM_STREAMSIZEF_QUERYMASK    =   $0000000F
Structure ACMDRIVERDETAILS
  cbStruct.l
  fccType.l
  fccComp.l
  wMid.w
  wPid.w
  vdwACM.l
  vdwDriver.l
  fdwSupport.l
  cFormatTags.l
  cFilterTags.l
  hicon.l
  szShortName.b[#ACMDRIVERDETAILS_SHORTNAME_CHARS];
  szLongName.b[#ACMDRIVERDETAILS_LONGNAME_CHARS];
  szCopyright.b[#ACMDRIVERDETAILS_COPYRIGHT_CHARS];
  szLicensing.b[#ACMDRIVERDETAILS_LICENSING_CHARS];
  szFeatures.b[#ACMDRIVERDETAILS_FEATURES_CHARS];
EndStructure
Structure ACMFILTERDETAILS
  cbStruct.l
  dwFilterIndex.l
  dwFilterTag.l
  fdwSupport.l
  pwfltr.l
  cbwfltr.l
  szFilter.b[#ACMFILTERDETAILS_FILTER_CHARS];
EndStructure
Structure ACMFORMATTAGDETAILS
  cbStruct.l
  dwFormatTagIndex.l
  dwFormatTag.l
  cbFormatSize.l
  fdwSupport.l
  cStandardFormats.l
  szFormatTag.b[#ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
EndStructure
Structure ACMFILTERTAGDETAILS
  cbStruct.l
  dwFilterTagIndex.l
  dwFilterTag.l
  cbFilterSize.l
  fdwSupport.l
  cStandardFilters.l
  szFilterTag.b[#ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
EndStructure
Structure ACMFORMATDETAILS
  cbStruct.l
  dwFormatIndex.l
  dwFormatTag.l
  fdwSupport.l
  pwfx.l
  cbwfx.l
  szFormat.b[#ACMFORMATDETAILS_FORMAT_CHARS];
EndStructure
Structure WAVEFILTER
  cbStruct.l
  dwFilterTag.l
  fdwFilter.l
  dwReserved.l[5];
EndStructure
Structure WAVEFORMATEX
  wFormatTag.w        ; Waveform-audio format type. A complete list of format tags can be found in the Mmreg.h header file. For one- Or two-channel PCM data, this value should be WAVE_FORMAT_PCM.
  nChannels.w         ; Number of channels in the waveform-audio data. Monaural data uses one channel and stereo data uses two channels.
  nSamplesPerSec.l    ; Sample rate, in samples per second (hertz). If wFormatTag is WAVE_FORMAT_PCM, then common values for nSamplesPerSec are 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.
  nAvgBytesPerSec.l   ; Required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec should be equal to the product of nSamplesPerSec and nBlockAlign. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.
  nBlockAlign.w       ; Block alignment, in bytes. The block alignment is the minimum atomic unit of data for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE, nBlockAlign must be equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte). For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.  :Software must process a multiple of nBlockAlign bytes of Data at a time. Data written To And Read from a device must always start at the beginning of a block. For example, it is illegal To start playback of PCM Data in the middle of a sample (that is, on a non-block-aligned boundary).
  wBitsPerSample.w    ; Bits per sample for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16. For non-PCM formats, this member must be set according to the manufacturer's specification of the format tag. If wFormatTag is WAVE_FORMAT_EXTENSIBLE, this value can be any integer multiple of 8. Some compression schemes cannot define a value for wBitsPerSample, so this member can be zero.
  cbSize.l            ; Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. This information can be used by non-PCM formats to store extra attributes for the wFormatTag. If no extra information is required by the wFormatTag, this member must be set to zero. For WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored.
EndStructure
Structure MPEGLAYER3WAVEFORMAT
  wfx.WAVEFORMATEX
  wID.w
  fdwFlags.l
  nBlockSize.w
  nFramesPerBlock.w
  nCodecDelay.w
EndStructure
Structure ACMSTREAMHEADER
  cbStruct.l  ;       sizeof(ACMSTREAMHEADER)
  fdwStatus.l ;       ACMSTREAMHEADER_STATUSF_*
  dwUser.l    ;       user instance data for hdr
  pbSrc.l
  cbSrcLength.l
  cbSrcLengthUsed.l
  dwSrcUser.l ;       user instance Data For src
  pbDst.l
  cbDstLength.l
  cbDstLengthUsed.l
  dwDstUser.l ;       user instance Data For dst
  dwReservedDriver.l[10] ;driver reserved work space
EndStructure
Structure ACMFORMATCHOOSE
  cbStruct.l
  fdwStyle.l
  hwndOwner.l
  pwfx.l
  cbwfx.l
  pszTitle.l
  szFormatTag.b[#ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
  szFormat.b[#ACMFORMATDETAILS_FORMAT_CHARS];
  pszName.l
  cchName.l
  fdwEnum.l
  pwfxEnum.l
  hInstance.l
  pszTemplateName.l
  lCustData.l
  pfnHook.l
EndStructure
Structure ACMFILTERCHOOSE
  cbStruct.l;
  fdwStyle.l;
  hwndOwner.l;
  pwfltr.l;
  cbwfltr.l;
  pszTitle.l;
  szFilterTag.b[#ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
  szFilter.b[#ACMFILTERDETAILS_FILTER_CHARS];
  pszName.l;
  cchName.l;
  fdwEnum.l;
  pwfltrEnum.l;
  hInstance.l;
  pszTemplateName.l;
  lCustData.l;
  pfnHook.l;
EndStructure
Procedure DebugError(e.l)
  tx.s = ""
  Select e
  Case #MMSYSERR_INVALFLAG
    tx = "INVALIDE FLAG"
  Case #MMSYSERR_INVALHANDLE
    tx = "INVALIDE HANDLE"
  Case #MMSYSERR_INVALPARAM
    tx = "INVALIDE PARAM"
  Case #MMSYSERR_NODRIVER
    tx = "NO DRIVER"
  Case #ACMERR_NOTPOSSIBLE
    tx = "The operation is not possible or the details requested are not available."
  EndSelect
  If tx
    Debug tx
  EndIf
EndProcedure
Procedure acmFiltTagCallBack (*hadid.l,*paftd.ACMFILTERTAGDETAILS  ,dwInstance.l,fdwSupport.l)
  Debug "******** "+PeekS(@*paftd\szFilterTag[0])
  ProcedureReturn #true
EndProcedure
Procedure acmFiltCallBack (*hadid.l,*pafd.ACMFILTERDETAILS  ,dwInstance.l,fdwSupport.l)
  Debug "********   "+PeekS(@*pafd\szFilter[0])
  ProcedureReturn #true
EndProcedure
Procedure.s GetFormatName (FormatNum)
  Select FormatNum
  Case #WAVE_FORMAT_PCM
    tx.s = "PCM"
  Case #WAVE_FORMAT_ALAW
    tx =  "ALAW"
  Case #WAVE_FORMAT_MULAW
    tx = "MULAW"
  Case #WAVE_FORMAT_ADPCM
    tx = "ADPCM"
  Case #WAVE_FORMAT_DVI_ADPCM
    tx = "DVI ADPCM"
  Case #WAVE_FORMAT_DVI_ADPCM
    tx = "Dialogic OKI ADPCM"
  Case #WAVE_FORMAT_GSM610
    tx = "GSM610"
  Case #WAVE_FORMAT_TRUESPEECH
    tx = "TRUESPEECH"
  Case #WAVE_FORMAT_G723_ADPCM
    tx = "G723 ADPCM"
  Case #WAVE_FORMAT_MPEG
    tx = "MPEG"
  Case #WAVE_FORMAT_MSG723
    tx = "MSG723"
  Case #WAVE_FORMAT_MPEGLAYER3
    tx = "MP3"
  Case #WAVE_FORMAT_VOXWARE
    tx = "VOXWARE"
  Case #WAVE_FORMAT_VOXWARE_BYTE_ALIGNED
    tx = "VOXWARE BYTEALIGNED"
  Case #WAVE_FORMAT_VOXWARE_RT24
    tx = "VOXWARE RT24"
  Case #WAVE_FORMAT_VOXWARE_RT29
    tx = "VOXWARE RT29"
  Case 304
    tx = "ACELP.net"
  Default
    tx = "FormatTag #"+Str(FormatNum)
  EndSelect
  ProcedureReturn tx
EndProcedure 

Procedure acmFmtCallBack (*hadid.l,*pafd2.ACMFORMATDETAILS,dwInstance.l,fdwSupport.l)
  tx.s = GetFormatName (*pafd2\dwFormatTag)
  Debug "   "+Str(*pafd2\dwFormatIndex)+"- "+tx +" : "+PeekS(@*pafd2\szFormat[0])
  ProcedureReturn #true
EndProcedure
;
Global MP3CodecFound.l
MP3CodecFound=0
;
Procedure acmCallback(*hadid.l,dwInstance.l,fdwSupport.l)
  Result = 1
  If (fdwSupport & #ACMDRIVERDETAILS_SUPPORTF_CODEC)
    fdwDetails.l = 0 ; reserved - must be 0
    padd.ACMDRIVERDETAILS\cbStruct = SizeOf(ACMDRIVERDETAILS)
    If acmDriverDetails_(*hadid,@padd,fdwDetails) = 0
      If acmDriverOpen_(@*Driver,*hadid, 0) = 0
        For i = 0 To padd\cFormatTags
          fmtDetails.ACMFORMATTAGDETAILS
          RtlZeroMemory_(@fmtDetails, SizeOf(ACMFORMATTAGDETAILS));
          fmtDetails\cbStruct = SizeOf(ACMFORMATTAGDETAILS)
          fmtDetails\dwFormatTagIndex = i
          mmr = acmFormatTagDetails_(*Driver, @fmtDetails, #ACM_FORMATTAGDETAILSF_INDEX)
          If mmr = 0
            If(fmtDetails\dwFormatTag = #WAVE_FORMAT_MPEGLAYER3 )
              MP3CodecFound = 1
              Result = 0
            EndIf 
          EndIf
        Next
        acmDriverClose_(*Driver, 0 )
      Else
        Debug "acmDriverOpen didn't success ! "
      EndIf 
    Else
      Debug "acmDriverDetails didn't success !"
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

acmDriverEnum_(@acmCallback(),0,0 ) ; just for info, this is not used by the conversion process

If MP3CodecFound = 0
  Debug "No MP3 decoders found!"
endif
  ;
  ;find the biggest format size
  ;
  maxFormatSize = 0;
  acmMetrics_(0, #ACM_METRIC_MAX_SIZE_FORMAT,@maxFormatSize)
  ;
  ; define desired OUTPUT format (this will be changed by acmFormatChoose)
  ;
  OutputFormat.MPEGLAYER3WAVEFORMAT\wfx\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES ; can suit for PCM or MP3
  OutputFormat\wfx\wFormatTag = #WAVE_FORMAT_PCM
  OutputFormat\wfx\nChannels = 2; // stereo
  OutputFormat\wfx\nSamplesPerSec = 8000; // 8kHz
  OutputFormat\wfx\wBitsPerSample = 8; // 8 bits
  OutputFormat\wfx\nBlockAlign = OutputFormat\wfx\nChannels*OutputFormat\wfx\wBitsPerSample/8; // bytes of data at a time (1 sample)
  OutputFormat\wfx\nAvgBytesPerSec = OutputFormat\wfx\nBlockAlign * OutputFormat\wfx\nSamplesPerSec; // byte-rate
  OutputFormat\wfx\cbSize = 0; // no more data to follow
  ;
  FileName$ = OpenFileRequester("Open a sound file", "", "*.*", 0)
  If FileName$
    If OpenFile(1, FileName$)
      If LCase(Right(FileName$,3))="wav"
        *hmem=AllocateMemory(36)
        ReadData(*hmem,36)
        CloseFile(1)
        CopyMemory(*hmem+20,@InputFormat.MPEGLAYER3WAVEFORMAT,16) ; copy nChannels, nSamplesPerSec, wBitsPerSample, nBlockAlign and nAvgBytesPerSec from the open file
        block_size_in = 512*InputFormat\wfx\nBlockAlign ; it could be 1024 or anything else instead of 512
      EndIf
      If LCase(Right(FileName$,3))="mp3"
        ;
        ; define mp3 input format
        ;
        InputFormat.MPEGLAYER3WAVEFORMAT\wfx\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
        InputFormat\wfx\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
        InputFormat\wfx\nChannels = 2
        InputFormat\wfx\nAvgBytesPerSec = 128 * (1024 / 8);   not really used but must be one of 64, 96, 112, 128, 160kbps
        InputFormat\wfx\wBitsPerSample = 0;                   MUST BE ZERO
        InputFormat\wfx\nBlockAlign = 1;                      MUST BE ONE
        InputFormat\wfx\nSamplesPerSec = 44100;               44.1kHz
        InputFormat\fdwFlags = #MPEGLAYER3_FLAG_PADDING_OFF
        InputFormat\nBlockSize = #MP3_BLOCK_SIZE ;            voodoo value #1
        InputFormat\nFramesPerBlock = 1;                      MUST BE ONE
        InputFormat\nCodecDelay = 1393;                       voodoo value #2
        InputFormat\wID = #MPEGLAYER3_ID_MPEG
        block_size_in = InputFormat\nBlockSize
      EndIf 
      ;
      Debug "-----------------------------"
      Debug "Open File format : "+ GetFormatName (InputFormat\wfx\wFormatTag)
      Debug "-----------------------------"
      Debug "nChannels : "+Str(InputFormat\wfx\nChannels)
      Debug "nSamplesPerSec : "+Str(InputFormat\wfx\nSamplesPerSec)
      Debug "wBitsPerSample : "+Str(InputFormat\wfx\wBitsPerSample)
      Debug "nBlockAlign : "+Str(InputFormat\wfx\nBlockAlign)
      Debug "nnAvgBytesPerSec : "+Str(InputFormat\wfx\nAvgBytesPerSec)
      ;
      ; Initialize the ACMFORMATCHOOSE members.
      ;
      afc.ACMFORMATCHOOSE\cbStruct    = SizeOf(ACMFORMATCHOOSE);
      afc\fdwStyle    = 0;            no special style flags
      afc\hwndOwner   = 0;            hwnd of parent window
      afc\pwfx        = @OutputFormat
      afc\cbwfx       = SizeOf(MPEGLAYER3WAVEFORMAT)
      afc\pszTitle    = @"Select the new format"
     ; afc\fdwEnum =     #ACM_FORMATENUMF_WFORMATTAG
      afc\fdwEnum =     #ACM_FORMATENUMF_SUGGEST
      afc\pwfxEnum = @InputFormat
      ;
      mmr = acmFormatChoose_(@afc)
      If mmr
        Debug "acmFormatChoose didn't success ! "
        DebugError(mmr)
      EndIf 
      ;
      Debug "--------------------------"
      Debug "Choosen format : " + GetFormatName (OutputFormat\wfx\wFormatTag)
      Debug "--------------------------"
      Debug "nChannels : "+Str(OutputFormat\wfx\nChannels)
      Debug "nSamplesPerSec : "+Str(OutputFormat\wfx\nSamplesPerSec)
      Debug "wBitsPerSample : "+Str(OutputFormat\wfx\wBitsPerSample)
      Debug "nBlockAlign : "+Str(OutputFormat\wfx\nBlockAlign)
      Debug "nnAvgBytesPerSec : "+Str(OutputFormat\wfx\nAvgBytesPerSec)
      Debug "--------------------------"
      ;
      ConversionStream = 0
      mmr=acmStreamOpen_(@ConversionStream,#NULL,@InputFormat,@OutputFormat,0,0,0,#ACM_STREAMOPENF_NONREALTIME)
      If mmr
        Debug "acmStreamOpen didn't success ! "
        DebugError(mmr)
      Else 
        ;
        ;Stream converter opened correctly
        ;now, let's open a file, read in a bunch of data, and convert it!
        ;
        If OpenFile(1, FileName$)
          DataInTotSize = 0
          If InputFormat\wfx\wFormatTag = #WAVE_FORMAT_PCM ; source
            posInFile = 16
            tx$=ReadString()
            While Left(tx$,4)<>"data" And posInFile <Lof() ; look for the data chunck
              FileSeek(posInFile)
              ReadData(@chunckLenght.l,4)
              posInFile = posInFile + chunckLenght + 4
              FileSeek(posInFile)
              tx$=ReadString()
            Wend
            posInFile + 4
            FileSeek(posInFile)
            ReadData(@DataInTotSize.l,4)
            posInFile + 4
            FileSeek(posInFile)
          EndIf
          ;
          ; find out how big the decoded buffer will be
          ;
          block_size_out = 0;
          mmr = acmStreamSize_(ConversionStream, block_size_in, @block_size_out, #ACM_STREAMSIZEF_SOURCE)
          If mmr<>0 Or block_size_out=0
            Debug "acmStreamSize didn't success ! "
            DebugError(mmr)
          Else 
            ;
            ; allocate our I/O buffers
            ;
            Sourcebuf = AllocateMemory(block_size_in)
            Destbuf   = AllocateMemory(block_size_out)
            ;
            ; prepare the decoder
            ;
            StreamHead.ACMSTREAMHEADER
            RtlZeroMemory_(@StreamHead, SizeOf(ACMSTREAMHEADER))
            StreamHead\cbStruct = SizeOf(ACMSTREAMHEADER )
            StreamHead\pbSrc = Sourcebuf
            StreamHead\cbSrcLength = block_size_in
            StreamHead\pbDst = Destbuf 
            StreamHead\cbDstLength = block_size_out
            mmr=0
            mmr = acmStreamPrepareHeader_(ConversionStream, @StreamHead, 0)
            If mmr = 0
              ;
              ; Dump this data off to disk
              ;
              While Right(FileName$,1)<>"."
                FileName$=Left(FileName$,Len(FileName$)-1)
              Wend
              FileName$=Left(FileName$,Len(FileName$)-1)
              Select OutputFormat\wfx\wFormatTag ; destination
                Case #WAVE_FORMAT_PCM 
                  FileName$+"2.wav"
                Case #WAVE_FORMAT_MPEGLAYER3
                  FileName$+"2.mp3"
                Default
                  FileName$+"2.???"
              EndSelect 
              If  OpenFile(2, FileName$)
                If OutputFormat\wfx\wFormatTag = #WAVE_FORMAT_PCM ; destination
                  ;
                  ; Generate the header
                  ;
                  Hdata$="RIFF"
                  WriteData (@Hdata$,4)
                  NData.l=0 ; Total size (this will be updated later)
                  WriteData (@NData,4)
                  Hdata$="WAVEfmt "
                  WriteData (@Hdata$,8)
                  NData.l=16 ; Header size
                  WriteData (@NData,4)
                  WriteData (@OutputFormat,16)
                  Hdata$="data"
                  WriteData (@Hdata$,4)
                  NData.l=0
                  WriteData (@NData,4) ; datas size (this will be updated later)
                EndIf
                DataOutSize = 0
                DataInSize = 0
                cont = 1
                UseFile(1)
                While cont
                  ;
                  ; Suck in some Source Data
                  ;
                  UseFile(1)
                  If DataInTotSize 
                    If DataInSize + block_size_in > DataInTotSize 
                      block_size_in = DataInTotSize - DataInSize
                      StreamHead\cbSrcLength = block_size_in
                    EndIf
                  EndIf
                  count = ReadData(Sourcebuf,block_size_in)
                  DataInSize + count
                  If DataInTotSize And DataInSize = DataInTotSize
                    cont = 0
                  EndIf 
                  If (count <> block_size_in)
                    cont = 0
                  EndIf
                  ;
                  ; Convert the Data
                  ;
                  mmr = acmStreamConvert_(ConversionStream,@StreamHead, 0);#ACM_STREAMCONVERTF_BLOCKALIGN)
                  DebugError(mmr)
                  ;
                  ; Write the decoded datas To disk
                  ;
                  If mmr=0 And StreamHead\cbDstLengthUsed
                    UseFile (2)
                    WriteData (Destbuf , StreamHead\cbDstLengthUsed)
                    DataOutSize + StreamHead\cbDstLengthUsed
                  EndIf 
                Wend
                ;
                DebugError(mmr)
                UseFile (2)
                FileSeek(4)
                NData=DataOutSize + 44
                WriteData (@NData,4) ; Update total size
                FileSeek(40)
                NData=DataOutSize 
                WriteData (@NData,4) ; Update datas size
                CloseFile(2)
              EndIf
              ;
              ; Clean up after yourself like a good little boy
              ;
              acmStreamUnprepareHeader_(ConversionStream, @StreamHead,0)
            Else
              Debug "acmStreamPrepareHeader didn't success ! "
              DebugError(mmr)
            EndIf
          EndIf 
          CloseFile(1)
          FreeMemory(Destbuf)
          FreeMemory(Sourcebuf)
        EndIf
        acmStreamClose_(ConversionStream, 0)
      EndIf
    EndIf
  EndIf

End
Don't try - DO it !
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

Buuuuhhhuuuu...

Nobody wants to help me...

Buuuuuuhhuuhhuuuu
Don't try - DO it !
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

..

Post by NoahPhense »

zapman* wrote:Buuuuhhhuuuu...

Nobody wants to help me...

Buuuuuuhhuuhhuuuu
Let bump this.. I beleive there are a couple people that could help with
this.

- np
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

So, where are those two people ??

Go out from behind the trees, now. It's not funny !
Don't try - DO it !
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

I did it, but it's a beta (but it seems to work well):

http://www.freesoundeditor.com/download ... er_acm.zip

Any comeback is very appreciated
Don't try - DO it !
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

What kind of audio can be handled?

- np
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

This enables you to convert MP3 to Wave files (or vice versa). The target is not just to listen them, but, for exemple, to open them, apply a numeric filter or split them and then save them.

Because MP3 is a very complex code, as far as I know it was'nt possible (until that tip) to make any transformation on these files with PB.

ACM also allows to make sampling rate conversions.

Many more soundfile conversions (OGG, WMA,...) could be done with ACM but I did'nt test all of them and this code needs probably to be enhanced for that.

It would be fantastic for me to find anybody else interrested by this type of work. Contact me if you are.
Don't try - DO it !
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

zapman* wrote:Because MP3 is a very complex code, as far as I know it was'nt possible (until that tip) to make any transformation on these files with PB.
As i said in the french forum, the mp3 decoder is ready to be used with SoundEditor ;)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

zapman* wrote:So, where are those two people ??

Go out from behind the trees, now. It's not funny !
lol. Too funny.

Tried it, went ok with mp3->wav, just select & save then test play.

You (and KarLKox) are a master at this sort of stuff!
@}--`--,-- A rose by any other name ..
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

This is very nice.. what are your full plans for its usage?

oh and...

Code: Select all

Data.s "Porn Groove"
;)

- np
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

I'll add it to SoundEditor to enable this editor to work on MP3 files (at the moment it can only open, edit and save Wave files)
If you don't know the SoundEditor Project (an open PureBasic dev project) just have a look at http://www.freesoundeditor.com/incagene ... .html~main
KarlKox has also made a fantastic work to enable SoundEditor to support the VST plugin standard. This stuff need very high and specialized abilities. The young KarlKox is so good in that type of job that I have some doubts about the fact that he's born on the same planet as us. Sure that he is a master!

At all events, these two major updates are not yet integrated in the downloadable version or SoundEditor. You'll have to wait a couple of month for that... I'm very busy with another private project.
NoahPhense wrote:

Code: Select all

Data.s "Porn Groove"
;)
I promise I didn't invent that. It was in the list!
Don't try - DO it !
Post Reply