fbsound 1.0 Win/Lin 32/64-bit (wav mp3 ogg mod it xm s3m)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by MrSwiss »

With: me.nCores = (r Shr 24) And &hFF

I'm gettig results: from 0 To 3 cores (obviously, a highly shaky affair ...)
while 1 and 3 (if 0 based), could be accepted, otherwise: 2 and 4 (if 1 based)
Windows reports: 2 cores, 4 logical processor's, Intel Core I7-7500 @ 2.70 GHz
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by badidea »

From what I read here (https://stackoverflow.com/questions/290 ... r-threadin) and here (https://wiki.osdev.org/Detecting_CPU_Topology_(80x86))

CPUID function aex=1 gives the ' logical core count'. See links for 'physical' core count.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

I changed the nCores part from here: https://stackoverflow.com/questions/290 ... r-threadin

How ever for FBSound numbers of CPU cores isn't important it runs in it's own thread of the main app.
More Important are the version of MMX or SSSE or NEON on __FB_ARM__.

Joshy

Code: Select all

#ifndef __FB_64BIT__
private _
function ReadTSC() as longint
  static as longint r
  dim as long ptr p = cptr(long ptr,@r)
  asm
    rdtsc
    mov edi,[p]
    mov [edi],eax
    mov [edi+4],edx
  end asm
  return r
end function
#else
private _
function ReadTSC() as longint
  asm
    rdtsc
    shl rdx, 32
    or  rax, rdx
    mov [function],rax
  end asm
end function
#endif

private _
function ReadEFLAG() as integer
  asm
#ifndef __FB_64BIT__
   pushfd  'eflag on stack
   pop eax 'in eax
   mov [function],eax
#else  
   pushfq
   pop rax 'in rax
   mov [function],rax
#endif  
  end asm
end function

private _
sub WriteEFLAG(byval v as integer)
  asm
#ifndef __FB_64BIT__
  mov eax,[v]  
  push eax
  popfd
#else
  xor rax,rax
  mov rax,[v]
  push rax
  popfq
#endif  
  end asm
end sub

private _
function IsCPUID() as boolean
  dim as integer o,n
  o = ReadEFLAG()
  n = o xor (1 shl 21) ' change bit 21
  WriteEFLAG(n)
  n = ReadEFLAG()
  WriteEFLAG(o)        ' restore old value
  return (o<>n)
end function 

private _
function _IsFPU() as boolean 'FPU aviable
  dim as ushort tmp
  tmp = &HFFFF
  asm fninit         ' try FPU init
  asm fnstsw [tmp]   ' store statusword
  if tmp=0 then      ' is it really 0
    asm fnstcw [tmp] ' store control
    if tmp=&H37F then function = true
  end if
end function 

private _
function CPUID_EAX(byval nr as long) as long
  asm mov eax,[nr]
  asm cpuid
  asm mov [function],eax
end function 

private _
function CPUID_EBX(byval nr as long) as long
  asm mov eax,[nr]
  asm cpuid
  asm mov [function],ebx
end function

private _
function CPUID_ECX(byval nr as long) as long
  asm mov eax,[nr]
  asm cpuid
  asm mov [function],ecx
end function

private _
function CPUID_EDX(byval nr as long) as long
  asm mov eax,[nr]
  asm cpuid
  asm mov [function],edx
end function 

type ME_
  as boolean x86_64,cpuid,fpu,tsc,cmov,mmx,mmx2,sse,sse2,sse3,sse41,sse42,n3d,n3d2
  as string*12 Vendor
  as longint Mhz
  as integer nCores
end type
dim as ME_ me

dim as string   msg
dim as ulong ptr p
dim as long  ct,r
dim as longint c1,c2,cd
dim as double t1,t2,td
me.cpuid = IsCPUID()

'print "fpu: " & _IsFPU()

if me.cpuid then
  p=cptr(ulong ptr, strptr(me.Vendor))
  p[0]=CPUID_EBX(0)
  p[1]=CPUID_EDX(0)
  p[2]=CPUID_ECX(0)
  msg = me.Vendor
    
  #ifndef __FB_64BIT__
    msg &= ", X86"
  #else
    msg &= ", X86_64"   
    me.x86_64=true
  #endif
  
  r=CPUID_EBX(1)
  me.nCores = (r shr 16) and &HFF
  if (me.Vendor = "GenuineIntel") then
    r=CPUID_EDX(4)
    var nCores =  (r shr 26) and &H3F 
    if nCores then me.nCores=nCores+1
  elseif (me.Vendor = "AuthenticAMD") then
    r=CPUID_ECX(( (1 shl 31) or (1 shl 3) ))
    var nCores = r and &HFF 
    if nCores then me.nCores=nCores+1
  end if
  if me.nCores then msg &= ", "  & me.nCores & " cpu cores"
       
  msg &= ", CPUID"   
   
  r=CPUID_EDX(1)
  
  if (r and (1 shl  0)) then me.fpu =true
  if (r and (1 shl  4)) then me.tsc =true
  if (r and (1 shl 15)) then me.cmov=true
  if (r and (1 shl 23)) then me.mmx =true
  if (r and (1 shl 25)) then
    me.sse=true
    if (r and (1 shl 26)) then me.sse2=true
  end if  

  r=CPUID_ECX(1)
  if me.sse then
    if (r and (1 shl 9)) then
      me.sse3 =true
      if (r and (1 shl 19)) then
        me.sse41=true
        if (r and (1 shl 20)) then me.sse42=true   
      end if
    end if
  end if
  
  r=CPUID_EAX(1 shl 31)
  if (r and (1 shl 31)) andalso (r and &HFF) then 
    r=CPUID_EDX((1 shl 31) or (1 shl 0))
    if me.mmx then
      if (r and (1 shl 20)) then me.mmx2=true
    end if  
    if (r and (1 shl 31)) then
      me.n3d=true
      if me.n3d then
        if (r and (1 shl 30)) then me.n3d2=true
      end if  
    end if  
  end if
  
  if me.fpu  then msg &= ", FPU"
  if me.tsc  then msg &= ", RDTSC"
  if me.cmov then msg &= ", CMOVxx, FCMOVxx"
  
  if me.mmx then 
    msg &= ", MMX I"
    if me.mmx2 then msg &= ",II"
  end if  
  if me.sse  then
    msg &= ", SSE"
    if me.sse2 then
      msg &= ",2"
      if me.sse3 then
        msg &= ",3"
        if me.sse41 then
          msg &= ",4.1"
          if me.sse42 then
            msg &= ",4.2"
          end if
        end if
      end if
    end if
  end if ' SSE         

  if me.n3d then
    msg &= ", 3D NOW 1"
    if me.mmx2 then msg &= ",2"
  end if    

  if me.tsc=true then
    t1=timer()
    c1=ReadTSC()
    while td<1.0:t2=timer:td=t2-t1:wend
    c2=ReadTSC()
    cd=c2-c1
    cd\=1000000
    me.MHz=cd*td
    msg &= " ~" & str(me.Mhz) & " MHz"
  end if
  print msg
end if


sleep
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

I edit 2,500 lines of assembler codes and it works now :- )
(all tests with *.wav files or soundtracker modules)

But my rebuild of static versions of: libmad *.MP3 decoder or vorbis *.OGG decoder doesn't work here ATM.

Joshy
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by srvaldez »

thank you Joshy :-)
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

FBS_Load_MP3Files works but FBS_Play_MP3Stream not.
I'm searching last 12 hours the bug without success.

The new trouble is in 32 and 64 bit so my new
64bit assembler code isn't the source of error.

After a second of sound, decode_frame returns -1
0 would be OK but not an meaningful error code.

Years ago I compiled the MP3 decoder for 32bit Windows and Linux
but now 64bit mode something must be different.

May be a wrong pointer arithmetic in the C code.

I hope after a break I find the devil :-)
Normally 12 hours are enough for me
to find some stupid mistakes.

Joshy
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by MrSwiss »

Is it possible, that parameter passing, has a influence? In x64, first 4 param's
in Registers, instead of, on the Stack (as in 32 bit's).
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

@MrSwiss I know it all.

libMad is a pure C lib so that can't be the problem.

I must make break from bug searching (Can't see the forest for the trees)
after the weekend I will search for the beast again :-)

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound for Linux x86 Win32 (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

I found the beast WAV, Soundtracker modules and MP3 works now :-)

But you can prof your self translate this short struct mad_stream
to FreeBASIC and of course show me your result.

Tip: Don't think in 32bit mode only ;-)

Next trip to hell are: compiling libogg, libvorbis and libvorbisfile as static libs also.

Joshy

Code: Select all

enum mad_error {
  MAD_ERROR_NONE           = 0x0000, /* no error */
  MAD_ERROR_BUFLEN         = 0x0001, /* input buffer too small (or EOF) */
 /* cut */
};

struct mad_stream {
  unsigned char const *buffer;     /* input bitstream buffer */
  unsigned char const *bufend;     /* end of buffer */
  unsigned long        skiplen;    /* bytes to skip before next frame */
  int                  sync;       /* stream sync found */
  unsigned long        freerate;   /* free bitrate (fixed) */
  unsigned char const *this_frame; /* start of current frame */
  unsigned char const *next_frame; /* start of next frame */
  struct mad_bitptr    ptr;        /* current processing bit pointer */
  struct mad_bitptr    anc_ptr;    /* ancillary bits pointer */
  unsigned int         anc_bitlen; /* number of ancillary bits */
  unsigned char (*main_data)[MAD_BUFFER_MDLEN]; /* Layer III main_data() */
  unsigned int         md_len;     /* bytes in main_data */
  int                  options;    /* decoding options (see below) */
  enum mad_error       error;      /* error code (see above) */
};
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

I uploaded a very early test version of FBSound 0.21 see first post.

Thank you for testing and bug report if any :-)

Joshy
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: fbSound Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by MrSwiss »

Well, here goes my try (remember, I've coded in C, less days than you did years,
except some Arduino-C, which is a "heavyly simplified subset" of C):

Code: Select all

' suppose we need some 'helpers' first
Type uchar As UByte
Type puchar As uchar Ptr
Type const_uchar As Const uchar
Type pconst_uchar As const_uchar Ptr 

Enum mad_error
    MAD_ERROR_NONE      = 0 ' or &h00 (which is the same, after all)
    MAD_ERROR_BUFLEN        ' = 1 (automatic)
    /' snip '/
End Enum

Type mad_stream
    As pconst_uchar     buffer
    As pconst_uchar     bufend
    As UInteger         skiplen
    As Long             sync
    As UInteger         freerate
    As pconst_uchar     this_frame
    As pconst_uchar     next_frame
    As Any ptr          _ptr    ' points to 'another' Type | rename needed
    As Any ptr          anc_ptr ' points to 'another' Type
    As ULong            anc_bitlen
    ' sorry don't speak: complex C (layer III stuff)
    As Any ptr          ' some_name ???
    As ULong            md_len
    As Long             options
    ' don't think, that Enum in type works in FB
    As Integer          _error  ' rename needed
End Type
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

Not bad only 3 errors :-)

Joshy

Code: Select all

Type mad_stream
    As pconst_uchar     buffer
    As pconst_uchar     bufend
    As UInteger         skiplen    ' wrong must be 32 bit on Win32/64 Linux32 but 64bit on Linux64
    As Long             sync
    As UInteger         freerate   ' wrong must be 32 bit on Win32/64 Linux32 but 64bit on Linux64
    As pconst_uchar     this_frame
    As pconst_uchar     next_frame
    As Any ptr          _ptr    ' points to 'another' Type | rename needed
    As Any ptr          anc_ptr ' points to 'another' Type
    As ULong            anc_bitlen
    As Any ptr          ' some_name ???
    As ULong            md_len
    As Long             options
    ' don't think, that Enum in type works in FB
    As Integer          _error     ' wrong must be 32-bit on Windows 32/64 and Linux 32/64
End Type
Here are how it looks with clong and culong from "crt.bi" include

Code: Select all

#iclude "crt.bi"
type cenum as long
type enum_mad_error as cenum
enum mad_error
  MAD_ERROR_NONE           = &H0000 ' no error
  MAD_ERROR_BUFLEN         = &H0001 ' input buffer too small (or EOF)
  ' <- cut ->
  MAD_ERROR_BADSTEREO      = &H0239 ' incompatible block_type for JS
end enum

type mad_stream
  as const ubyte ptr buffer     ' input bitstream buffer
  as const ubyte ptr bufend     ' end of buffer
  as culong          skiplen    ' bytes to skip before next frame
  as long            sync       ' stream sync found
  as culong          freerate   ' free bitrate (fixed)
  as const ubyte ptr this_frame ' start of current frame
  as const ubyte ptr next_frame ' start of next frame
  as mad_bitptr      _ptr       ' current processing bit pointer
  as mad_bitptr      anc_ptr    ' ancillary bits pointer
  as ulong           anc_bitlen ' number of ancillary bits
  as ubyte ptr       main_data  ' !!! (MAD_BUFFER_MDLEN-1)
  as ulong           md_len     ' bytes in main_data
  as long            options    ' decoding options (see below)
  as enum_mad_error  error       ' error code (see above)
end type
I made a bigger error / mistake and defined an array of pointers
as ubyte ptr main_data (MAD_BUFFER_MDLEN-1)
if the MP3 decoder crashed I reed a zero from error enum :lol:

Joshy
Last edited by D.J.Peters on Apr 20, 2018 20:26, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbSound Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

Added Linux 32/64 bit support to FBSound 0.21 see first post.

Joshy
Last edited by D.J.Peters on Apr 21, 2018 5:32, edited 1 time in total.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: fbSound Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by srvaldez »

danke schön :-)
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: fbsound 1.0 Linux Windows 32/64-bit (wav mp3 ogg mod it xm s3m)

Post by D.J.Peters »

After 25 hours without sleep i'm proud to presence you fbsound V1.0 :-)

See first post.

Joshy
Post Reply