Finding MP3 decoder source

Everything else that doesn't fall into one of the other PB categories.
User avatar
oryaaaaa
Addict
Addict
Posts: 833
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Finding MP3 decoder source

Post by oryaaaaa »

I want to MP3 to wav on memory. But Almost lib just do Comvert to Play.
I need decoded wav data.

Do you know MP3 decode LIB or source code?

Thanks
User avatar
oryaaaaa
Addict
Addict
Posts: 833
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Re: Finding MP3 decoder source

Post by oryaaaaa »

Thanks

I decide using libmpg123.dll . coz Its LGPL.
http://www.mpg123.de/
Features

We all know that mpg123 is the fast console mpeg audio decoder/player, don't we? But here are some things that go beyond simple decoding:

support for many platforms (many Unices, MacOSX, Windows) and audio subsystems
simple but powerful control mode for frontends (commands via STDIN)
realtime control of efficient equalizer (because built into decoder)
built-in terminal control keys
support for gapless playback of mp3 files (skipping encoder/decoder padding/junk)
many audio data settings: resampling, choose channel, mono, ...
really efficient with a growing number of assembler optimizations (pentium, MMX, AltiVec, ...)
support for Relative Volume Adjustment / ReplayGain
Also, especially for the simple decoding, the decoder part of mpg123 is usable as a library in your application!

mpg123 supports a wide range of audio interfaces, including:

ALSA (Advanced Linux Sound Architecture)
CoreAudio (Mac OS X)
EsounD (The Enlightened Sound Daemon)
JACK (Jack Audio Connection Kit)
NAS (Network Audio System)
OSS (Open Sound System)
PortAudio (Portable cross-platform Audio API)
PulseAudio (sound server for POSIX and Win32)
SDL (Simple DirectMedia Layer)
Sun Audio (/dev/audio)
Win32 (Windows WaveOut)
I want to use LAME in a non-GPL way and need permission for using the included mpglib

That request is coming quite often. The issue is that current mpg123 and libmpg123 is LGPL and I as maintainer am fine with usage of code from mpg123 under these terms, while the mpglib in LAME is older and still under GPL. There may be changes to the mpglib made by people who don't want their work used under LGPL instead of GPL. I don't know how relevant this issue is, but it is a concern by the LAME developers.
But.... mpg123_decode invalid memory access error
I just try SDK tomorrow :cry:

Add: Tips How to make MP3 Library
http://forum.purebasic.com/english/view ... 12&t=39538
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Re: Finding MP3 decoder source

Post by KarLKoX »

Hi !
I ve succesfully used libmpg123 with pb without pb but right, it doesn't surprise me that you are in trouble, i hate the coding style and the way this lib is coded ...
Btw, i don't have a lot of spare time but i ll see what i can do this week end.
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
User avatar
oryaaaaa
Addict
Addict
Posts: 833
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Re: Finding MP3 decoder source

Post by oryaaaaa »

Could you show me libmpg123.pbi code?

This is mine

Code: Select all

#MPG123_ENC_16     = $040
#MPG123_ENC_SIGNED = $080
#MPG123_ENC_SIGNED_16   = #MPG123_ENC_16|#MPG123_ENC_SIGNED|$10
#MPG123_OK=0
#MPG123_ERR=-1
#MPG123_DONE=-12
#MPG123_NEW_FORMAT=-11
#MPG123_NEED_MORE=-10

Enumeration
  #MPG123_VERBOSE
  #MPG123_FLAGS          
  #MPG123_ADD_FLAGS      
  #MPG123_FORCE_RATE     
  #MPG123_DOWN_SAMPLE    
  #MPG123_RVA            
  #MPG123_DOWNSPEED      
  #MPG123_UPSPEED        
  #MPG123_START_FRAME    
  #MPG123_DECODE_FRAMES  
  #MPG123_ICY_INTERVAL   
  #MPG123_OUTSCALE       
  #MPG123_TIMEOUT       
  #MPG123_REMOVE_FLAGS   
  #MPG123_RESYNC_LIMIT   
  #MPG123_INDEX_SIZE      
  #MPG123_PREFRAMES 
EndEnumeration

#MPG123_FORCE_MONO   = $7
#MPG123_MONO_LEFT    = $1 
#MPG123_MONO_RIGHT   = $2
#MPG123_MONO_MIX     = $4
#MPG123_FORCE_STEREO = $8 
#MPG123_FORCE_8BIT   = $10
#MPG123_QUIET        = $20
#MPG123_GAPLESS      = $40
#MPG123_NO_RESYNC    = $80
#MPG123_SEEKBUFFER   = $100
#MPG123_FUZZY        = $200
#MPG123_FORCE_FLOAT  = $400
#MPG123_PLAIN_ID3TEXT = $800

Prototype.l mpg123_decode_frame(a.l,b.l,c.l,d.l)
Prototype.l mpg123_feed(a.l,b.l,c.l)
Prototype.l mpg123_feedseek(a.l,b.l,c.l,d.l)
Prototype.l mpg123_tell_stream(a.l)
Prototype.l mpg123_getformat(mh.l, rate.l, channels.l, encoding.l)
Prototype.l mpg123_open_feed(mh.l)
Prototype.l mpg123_close(mh.l)
Prototype.l mpg123_decode(mh.l, inmemory.l, immemseize.l, outmemory.l, outmemsize.l, done.l)
Prototype.l mpg123_format_none(mh.l)
Prototype.l mpg123_delete(mh.l)
Prototype.l mpg123_exit()
Prototype.l mpg123_init()
Prototype.l mpg123_new(decoder.l, mh.l)
Prototype.l mpg123_fmt_none(mh.l)
Prototype.l mpg123_format(mh.l, rate.l, channels.l, encoding.l)
Prototype.l mpg123_outblock(mh.l)

Global mpg123_close.mpg123_close
Global mpg123_delete.mpg123_delete
Global mpg123_exit.mpg123_exit
Global mpg123_init.mpg123_init
Global mpg123_decode.mpg123_decode
Global mpg123_decode_frame.mpg123_decode_frame
Global mpg123_new.mpg123_new
Global mpg123_outblock.mpg123_outblock
Global mpg123_format_none.mpg123_format_none
Global mpg123_feed.mpg123_feed
Global mpg123_feedseek.mpg123_feedseek
Global mpg123_format.mpg123_format
Global mpg123_open_feed.mpg123_open_feed
Global mpg123_getformat.mpg123_getformat
Global mpg123_tell_stream.mpg123_tell_stream

Procedure libmpg123_Init()
  Shared DLL.l
  DLL = OpenLibrary(#PB_Any, "libmpg123-0.dll") 
  If DLL
    mpg123_close = GetFunction(DLL, "mpg123_close")
    mpg123_delete = GetFunction(DLL, "mpg123_delete")
    mpg123_exit = GetFunction(DLL, "mpg123_exit")
    mpg123_init = GetFunction(DLL, "mpg123_init")
    mpg123_decode = GetFunction(DLL, "mpg123_decode")
    mpg123_decode_frame = GetFunction(DLL, "mpg123_decode_frame@16")
    mpg123_new = GetFunction(DLL, "mpg123_new")
    mpg123_outblock = GetFunction(DLL, "mpg123_outblock")
    mpg123_format_none = GetFunction(DLL, "mpg123_format_none")
    mpg123_feed = GetFunction(DLL, "mpg123_feed@12")
    mpg123_feedseek = GetFunction(DLL, "mpg123_feedseek@16")
    mpg123_format = GetFunction(DLL, "mpg123_format")
    mpg123_open_feed = GetFunction(DLL, "mpg123_open_feed")
    mpg123_getformat = GetFunction(DLL, "mpg123_getformat")
    mpg123_tell_stream = GetFunction(DLL, "mpg123_tell_stream@4")
  EndIf
EndProcedure

Procedure libmpg123_End()
  Shared DLL.l
  CloseLibrary(DLL)
EndProcedure
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Re: Finding MP3 decoder source

Post by KarLKoX »

Hi !
You are right, i was also in trouble with the last libmpg123 release wich i didn't have with older version but i finally managed to get it working.
Here is the PB code :

Code: Select all

#MPG123_DONE=-12
#MPG123_ERR=-1
#MPG123_OK = 0
#MPG123_ENC_16        = $040      ; < 0000 0100 0000 Some 16 bit integer encoding.
#MPG123_ENC_SIGNED    = $080      ; < 0000 1000 0000 Some signed integer encoding.
#MPG123_ENC_SIGNED_16 = (#MPG123_ENC_16|#MPG123_ENC_SIGNED|$10)

#MP3_FILENAME = "01 - Red Alert 3 - Soviet March.mp3"
#DLL_FILENAME = "libmpg123-0.dll"

PrototypeC   Proto_mpg123_init()
PrototypeC.l Proto_mpg123_new(*decoder.s, *error.l)
PrototypeC.l Proto_mpg123_open(*mh.l, path.s)
PrototypeC.l Proto_mpg123_getformat(*mh.l, *rate.l, *channels.l, *encoding.l)
PrototypeC.l Proto_mpg123_plain_strerror(errcode.l)
PrototypeC.l Proto_mpg123_strerror(*mh.l)
PrototypeC.l Proto_mpg123_format_none(*mh.l)
PrototypeC.l Proto_mpg123_format(*mh.l, rate.l, channels.l, encodings.l)
PrototypeC.l Proto_mpg123_outblock(*mh.l)
PrototypeC.l Proto_mpg123_read(*mh.l, *outmemory.b, outmemsize.l, *done.l)
PrototypeC.l Proto_mpg123_decode(*mh.l, *inmemory.b, inmemsize.l, *outmemory.b, outmemsize.l, *done.l)
PrototypeC.l Proto_mpg123_close(*mh.l)
PrototypeC   Proto_mpg123_delete(*mp.l)
PrototypeC   Proto_mpg123_exit()
PrototypeC.l Proto_mpg123_length(*mh.l)

Structure libmpg123_struct
  mpg123_init.Proto_mpg123_init
  mpg123_new.Proto_mpg123_new
  mpg123_open.Proto_mpg123_open
  mpg123_getformat.Proto_mpg123_getformat
  mpg123_plain_strerror.Proto_mpg123_plain_strerror
  mpg123_strerror.Proto_mpg123_strerror
  mpg123_format_none.Proto_mpg123_format_none
  mpg123_format.Proto_mpg123_format
  mpg123_outblock.Proto_mpg123_outblock
  mpg123_read.Proto_mpg123_read
  mpg123_decode.Proto_mpg123_decode
  mpg123_close.Proto_mpg123_close
  mpg123_delete.Proto_mpg123_delete
  mpg123_exit.Proto_mpg123_exit
  mpg123_length.Proto_mpg123_length
EndStructure

Global *mpg123_handle.l, hDll, *libmpg123_obj.libmpg123_struct

;Force a pointer To be 16 byte Aligned
Macro Align16(pointer)
  (((pointer) + 15) &~ $0F)
EndMacro

Procedure AllocateAlignedMemory(Size.l)
Protected pointer.l, ReturningPointer.l
  pointer = AllocateMemory(Size + 16)
  ReturningPointer = Align16(pointer)
  PokeB(ReturningPointer + Size + 1, (pointer % 16))
  ProcedureReturn ReturningPointer
EndProcedure

Procedure DBG(msg.s)
  CompilerIf #PB_Compiler_Debugger = 1
    Debug msg
  CompilerElse
    MessageRequester("Debug", msg)
  CompilerEndIf
EndProcedure

Procedure.l Init_LibMpg123(libname.s)

  If hDll = 0
    hDll = OpenLibrary(#PB_Any, libname)
    If hDll
      *libmpg123_obj = AllocateMemory(SizeOf(libmpg123_struct))
      If *libmpg123_obj = #Null
        Dbg("Failed to allocate a libmpg123_obj object")
        ProcedureReturn #False
      EndIf
        *libmpg123_obj\mpg123_init = GetFunction(hDll, "mpg123_init")
        *libmpg123_obj\mpg123_new = GetFunction(hDll, "mpg123_new")
        *libmpg123_obj\mpg123_open = GetFunction(hDll, "mpg123_open")
        *libmpg123_obj\mpg123_getformat = GetFunction(hDll, "mpg123_getformat")
        *libmpg123_obj\mpg123_plain_strerror = GetFunction(hDll, "mpg123_plain_strerror")
        *libmpg123_obj\mpg123_strerror = GetFunction(hDll, "mpg123_strerror")
        *libmpg123_obj\mpg123_format_none = GetFunction(hDll, "mpg123_format_none")
        *libmpg123_obj\mpg123_format = GetFunction(hDll, "mpg123_format")
        *libmpg123_obj\mpg123_outblock = GetFunction(hDll, "mpg123_outblock")
        *libmpg123_obj\mpg123_read = GetFunction(hDll, "mpg123_read")
        *libmpg123_obj\mpg123_decode = GetFunction(hDll, "mpg123_decode")
        *libmpg123_obj\mpg123_close = GetFunction(hDll, "mpg123_close")
        *libmpg123_obj\mpg123_delete = GetFunction(hDll, "mpg123_delete")
        *libmpg123_obj\mpg123_exit = GetFunction(hDll, "mpg123_exit")
        *libmpg123_obj\mpg123_length = GetFunction(hDll, "mpg123_length")
        
        ;- TODO : paranoiac sanity check for function pointers (too lazy to verify them)
        ProcedureReturn #True
    EndIf
  EndIf
  
  ProcedureReturn #False
EndProcedure

Procedure Cleanup_LibMpg123()

  If hDll And *libmpg123_obj
    *libmpg123_obj\mpg123_close(*mpg123_handle)
    *libmpg123_obj\mpg123_delete(*mpg123_handle)
    *libmpg123_obj\mpg123_exit()
    FreeMemory(*libmpg123_obj)
    *libmpg123_obj = #Null
    CloseLibrary(hDLL)
    hDLL = #Null
  EndIf

EndProcedure

Procedure Mp3_To_Memory(filename.s)
Protected err.l = #MPG123_OK, err_open.l = #MPG123_OK, err_getformat.l = #MPG123_OK
Protected channels.l = 0, encoding.l = 0
Protected rate.l = 0
Protected buffer_size.l = 0
Protected num_samples.l = 0
Protected bytes_memory.l = 0
Protected *buffer_memory.b, *ptr_buffer_memory.b
Protected bytes_read.l, delta.l, remaining.l
Protected done.l = #MPG123_OK

  If Init_LibMpg123(#DLL_FILENAME) <= 0
    DBG("Error with Init_LibMpg123 !")
    ProcedureReturn -3
  EndIf
   
  err = *libmpg123_obj\mpg123_init()
  *mpg123_handle = *libmpg123_obj\mpg123_new(#Null, @err)
  err_open = *libmpg123_obj\mpg123_open(*mpg123_handle, filename) 
  err_getformat = *libmpg123_obj\mpg123_getformat(*mpg123_handle, @rate, @channels, @encoding)                  
  If err <> #MPG123_OK Or *mpg123_handle = #Null Or err_open <> #MPG123_OK Or err_getformat <> #MPG123_OK
  ;If( err <> #MPG123_OK Or (*mpg123_handle = *libmpg123_obj\mpg123_new(#Null, @err)) = #Null Or *libmpg123_obj\mpg123_open(*mpg123_handle, filename) <> #MPG123_OK Or *libmpg123_obj\mpg123_getformat(*mpg123_handle, @rate, @channels, @encoding) <> #MPG123_OK )
    If *mpg123_handle = #Null                 
      DBG(PeekS(*libmpg123_obj\mpg123_plain_strerror(err)))
    Else
      DBG(PeekS(*libmpg123_obj\mpg123_strerror(*mpg123_handle)))
    EndIf
    Cleanup_LibMpg123()   
    ProcedureReturn -1           
  EndIf
  
  If(encoding <> #MPG123_ENC_SIGNED_16)
    DBG("Bad encoding: " + Str(encoding) )
    ProcedureReturn -2
  EndIf
  *libmpg123_obj\mpg123_format_none(*mpg123_handle)
  *libmpg123_obj\mpg123_format(*mpg123_handle, rate, channels, encoding)
  buffer_size = *libmpg123_obj\mpg123_outblock(*mpg123_handle)
  num_samples = *libmpg123_obj\mpg123_length(*mpg123_handle)
  bytes_memory = num_samples * channels * SizeOf(Word)   ; convert samples to bytes
  *buffer_memory = AllocateMemory(bytes_memory)
  If MemorySize(*buffer_memory) <> bytes_memory
   DBG("Failed to alloc a buffer memory, size = " + Str(MemorySize(*buffer_memory)) )
   ProcedureReturn -1
  EndIf
    
  *ptr_buffer_memory = *buffer_memory
  bytes_read = 0
  remaining = bytes_memory
  While 1
    delta = buffer_size
    remaining = bytes_memory - bytes_read
    If remaining <= 0
      Break
    EndIf
    If delta > remaining
      delta = remaining
    EndIf
    
    err = *libmpg123_obj\mpg123_read(*mpg123_handle, *ptr_buffer_memory, delta, @done )
    If err <> #MPG123_OK
      Break
    EndIf    
    *ptr_buffer_memory + done
    bytes_read + done
    remaining - delta
  Wend
  
  If bytes_read <> bytes_memory
     Debug "num_samples done <> num_samples to read !"
  EndIf
  
  If err <> #MPG123_DONE
    If err = #MPG123_ERR
      DBG(PeekS(*libmpg123_obj\mpg123_strerror(*mpg123_handle)))
    Else
      DBG(PeekS(*libmpg123_obj\mpg123_plain_strerror(err)))
    EndIf
  EndIf

  ;- for debugging purpose, write to a 16/2/44100 raw file
  If CreateFile(0, "test.raw")
    WriteData(0, *buffer_memory, bytes_memory)
    CloseFile(0)
  EndIf
  
  Cleanup_LibMpg123()
EndProcedure


Mp3_To_Memory(#MP3_FILENAME)
If you use this code, there will be a crash in mpg123_read. Why ? There seems to be a configure bug : in fact, libmpg123 use aligned pointers by default, i was too lazy to manage them (but i let you the macro, just in case) so i disable the alignment check when configuring the makefile with "--enable-aligncheck=no" but after hours of crash with pb and searching in the C sourcecode i found that the CCALIGN macro is still defined in config.h for attribute ! I just commented this line, recompiled the dll and all is fine :)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
User avatar
oryaaaaa
Addict
Addict
Posts: 833
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Re: Finding MP3 decoder source

Post by oryaaaaa »

Thank you, KarLKox.

I understand it. PrototypeC and "--enable-aligncheck=no" :D
Post Reply