Advertisement
pwray

Use lame encoder from python

Dec 18th, 2011
364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.90 KB | None | 0 0
  1. from ctypes import *
  2. import sys
  3. import wave
  4. import os
  5.  
  6.  
  7. BE_CONFIG_MP3, BE_CONFIG_LAME = (0, 256)
  8. BE_ERR_SUCCESSFUL, BE_ERR_INVALID_FORMAT, BE_ERR_INVALID_FORMAT_PARAMETERS, \
  9.       BE_ERR_NO_MORE_HANDLES, BE_ERR_INVALID_HANDLE, BE_ERR_BUFFER_TOO_SMALL = range(6)
  10.  
  11. BE_MAX_HOMEPAGE = 128
  12. BE_MP3_MODE_STEREO, BE_MP3_MODE_JSTEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO = range(4)
  13. MPEG2, MPEG1 = range(2)
  14.  
  15. CURRENT_STRUCT_VERSION = 1
  16. #CURRENT_STRUCT_SIZE sizeof(BE_CONFIG)    # is currently 331 bytes
  17.  
  18. VBR_METHOD_NONE,  VBR_METHOD_DEFAULT, VBR_METHOD_OLD, VBR_METHOD_NEW, VBR_METHOD_MTRH, VBR_METHOD_ABR = range(-1, 5)
  19. LQP_PHONE, LQP_SW, LQP_AM, LQP_FM, LQP_VOICE, LQP_RADIO, LQP_TAPE, LQP_HIFI, LQP_CD, LQP_STUDIO = [x * 1000 for x in range(1, 11)]
  20.  
  21. class BE_VERSION(Structure):
  22.     _fields_ = [
  23.         ('byDLLMajorVersion', c_byte),  # BladeEnc DLL Version number
  24.         ('byDLLMinorVersion', c_byte),
  25.         ('byMajorVersion', c_byte),    # BladeEnc Engine Version Number
  26.         ('byMinorVersion', c_byte),
  27.         ('byDay', c_byte),             # DLL Release date
  28.         ('byMonth', c_byte),
  29.         ('wYear', c_short),
  30.         ('zHomepage', c_char * 129),    # BladeEnc Homepage URL
  31.         ('byAlphaLevel', c_byte),
  32.         ('byBetaLevel', c_byte),
  33.         ('byMMXEnabled', c_byte),
  34.         ('btReserved', c_byte * 125)                
  35.     ]
  36.     _pack_ = 1
  37.  
  38.  
  39. class BE_CONFIG(Structure):
  40.     _fields_ = [
  41.         ('dwConfig', c_ulong),          # BE_CONFIG_XXXXX, Currently only BE_CONFIG_MP3 is supported
  42.         ('dwStructVersion', c_ulong),  
  43.         ('dwStructSize', c_ulong),
  44.         ('dwSampleRate', c_ulong),      # SAMPLERATE OF INPUT FILE
  45.         ('dwReSampleRate', c_ulong),    # DOWNSAMPLERATE, 0=ENCODER DECIDES
  46.         ('nMode', c_long),              # BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
  47.         ('dwBitrate', c_ulong),         # CBR bitrate, VBR min bitrate
  48.         ('dwMaxBitrate', c_ulong),      # CBR ignored, VBR Max bitrate
  49.         ('nPreset', c_long),            # Quality preset, use one of the settings of the LAME_QUALITY_PRESET enum
  50.         ('dwMpegVersion', c_ulong),     # FUTURE USE, MPEG-1 OR MPEG-2
  51.         ('dwPsyModel', c_ulong),        # FUTURE USE, SET TO 0
  52.         ('dwEmphasis', c_ulong),        # FUTURE USE, SET TO 0
  53.    
  54.         # BIT STREAM SETTINGS
  55.         ('bPrivate', c_long),           # Set Private Bit (True/FALSE)
  56.         ('bCRC', c_long),               # Insert CRC (True/FALSE)
  57.         ('bCopyright', c_long),         # Set Copyright Bit (True/FALSE)
  58.         ('bOriginal', c_long),          # Set Original Bit (True/FALSE)
  59.        
  60.         # VBR STUFF
  61.        
  62.         ('bWriteVBRHeader', c_long),    # WRITE XING VBR HEADER (True/FALSE)
  63.         ('bEnableVBR', c_long),         # USE VBR ENCODING (True/FALSE)
  64.         ('nVBRQuality', c_int),         # VBR QUALITY 0..9
  65.         ('dwVbrAbr_bps', c_ulong),      # Use ABR instead of nVBRQuality
  66.        
  67.         ('nVbrMethod', c_int),        
  68.         ('bNoRes', c_long),             # bool Disable Bit reservoir (True/FALSE)
  69.    
  70.         # MISC SETTINGS
  71.         ('bStrictIso', c_long),         # Use strict ISO encoding rules (True/FALSE)
  72.         ('nQuality', c_ushort),         # Quality Setting, HIGH BYTE should be NOT LOW byte, otherwhise quality=5
  73.    
  74.         # FUTURE USE, SET TO 0, align structure to 331 bytes
  75.         ('btReserved', c_byte * (255 - 4*4 - 2 ) )
  76.     ]
  77.  
  78.     _packed_ = 1
  79.  
  80. lame = cdll.lame_enc
  81.  
  82. #version = BE_VERSION()
  83. #print version.zHomepage
  84. #lame.beVersion(byref(version))  
  85. #print version.byDay, version.byMonth
  86.  
  87.  
  88. samplesPerChunk = c_ulong()
  89. mp3BufSize = c_ulong()
  90. mp3Bytes = c_ulong()
  91. stream = c_int()
  92.  
  93.  
  94. wavFile = wave.open('test.wav', 'rb')
  95. mp3File = open('test.mp3', 'wb')
  96.  
  97. beConfig = BE_CONFIG()
  98.  
  99. beConfig.dwConfig = BE_CONFIG_LAME;
  100. beConfig.dwStructVersion    = 1
  101. beConfig.dwStructSize       = sizeof(beConfig)    
  102. beConfig.dwSampleRate       = wavFile.getframerate() # INPUT FREQUENCY
  103. beConfig.dwReSampleRate     = 0                    # LET ENCODER DECIDE
  104.  
  105. nChannels = wavFile.getnchannels()
  106. if nChannels == 1:
  107.     beConfig.nMode              = BE_MP3_MODE_MONO
  108. else:
  109.     beConfig.nMode              = BE_MP3_MODE_STEREO
  110.    
  111. beConfig.dwBitrate          = 128                  # MINIMUM BIT RATE
  112. beConfig.dwMaxBitrate       = 320                  # MAXIMUM BIT RATE
  113. beConfig.nPreset            = LQP_CD               # QUALITY PRESET SETTING
  114. beConfig.dwMpegVersion      = MPEG1               # MPEG VERSION (I or II)
  115. beConfig.dwPsyModel         = 0                    # USE DEFAULT PSYCHOACOUSTIC MODEL
  116. beConfig.dwEmphasis         = 0                    # NO EMPHASIS TURNED ON
  117.  
  118.  
  119. beConfig.bPrivate           = True                # SET PRIVATE FLAG
  120. beConfig.bCRC               = True                # INSERT CRC
  121. beConfig.bCopyright         = False                # SET COPYRIGHT FLAG
  122. beConfig.bOriginal          = True                 # SET ORIGINAL FLAG
  123.  
  124. beConfig.bWriteVBRHeader    = True                # YES, WRITE THE XING VBR HEADER
  125. beConfig.bEnableVBR         = True                # USE VBR
  126.  
  127. beConfig.nVBRQuality        = 5                    # SET VBR QUALITY
  128. #beConfig.dwVbrAbr_bps       = 100                 # Average bit rate - if specified, used instead of quality
  129. beConfig.nVBRMethod = VBR_METHOD_DEFAULT
  130. beConfig.bNoRes             = False                 # No Bit reservoir
  131. beConfig.bStrictIso         = True
  132. beConfig.nQuality = 5
  133.  
  134.  
  135. err = lame.beInitStream(byref(beConfig), byref(samplesPerChunk), byref(mp3BufSize), byref(stream))
  136.  
  137. if err:
  138.     print 'Error', err
  139.     sys.exit(0)
  140.  
  141. mp3Buf = create_string_buffer(mp3BufSize.value)
  142.  
  143.  
  144. # Using the python wave module we need to read in frame units
  145. # it seems a reasonable assumption that lame chunks will always start/end on frame boundaries
  146. # and so the frames per chunk should always be integer
  147.  
  148. bytesPerSample = wavFile.getsampwidth()
  149. samplesPerFrame = nChannels
  150. framesPerChunk = samplesPerChunk.value / samplesPerFrame
  151. assert samplesPerChunk.value % samplesPerFrame == 0
  152.  
  153. #print 'bytes per sample=', bytesPerSample, 'samples per chunk=', samplesPerChunk.value, 'samplesPerFrame', samplesPerFrame, 'frames per chunk', framesPerChunk
  154. while(True):
  155.     wavStr = wavFile.readframes(framesPerChunk)
  156.    
  157.     #print samplesPerChunk.value,  len(wavStr)
  158.  
  159.     if wavStr == '':
  160.         err = lame.beDeinitStream(stream, mp3Buf, byref(mp3Bytes));
  161.         if not err and mp3Bytes != 0:
  162.             mp3File.write(mp3Buf[0:mp3Bytes.value])        
  163.         break
  164.    
  165.     wavBuf = create_string_buffer(wavStr, samplesPerChunk.value*bytesPerSample)
  166.     err = lame.beEncodeChunk(stream, len(wavStr) / bytesPerSample, wavBuf, mp3Buf, byref(mp3Bytes) )
  167.    
  168.     if err:
  169.         break
  170.    
  171.     mp3File.write(mp3Buf[0:mp3Bytes.value])
  172.    
  173. lame.beCloseStream(stream)
  174. mp3File.close()
  175. wavFile.close()
  176.  
  177. lame.beWriteVBRHeader('C:/Users/Paul/Desktop/libmp3lame-3.98.2/test.mp3')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement