Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Linux ALSA lib please test it with your Linux distro.
#11
Hello red_Marvin you are the only that will help to make the Win and Lin soundlib true thx for this.

It seams to be that i have found the problem.

in 16 bit most of all cards are can pay with singned 16 bit
but in 8 bit the most can play with unsigned 8bit

Please test all lines (but only one in same time)
Code:
'Player=Alsa_Init(,22050, 8,1)
'Player=Alsa_Init(,22050, 8,2)
'Player=Alsa_Init(,22050,16,1)
'Player=Alsa_Init(,22050,16,1)
'Player=Alsa_Init(,44100, 8,2)
Player=Alsa_Init(,44100,16,2)
'Player=Alsa_Init(,48000,16,1)
'Player=Alsa_Init(,48000,16,1)

it works on my 3 linux boxes with difrent soundcards.

If you get any mode not working please tell me witch mode makes trouble. and what is your kernel 2.4.x or 2.6.x and the alsa version.
Details what goes wrong 8/16 Bit 1/2 Channels

if you post the plot or mp3 won't help i need the parameters

Again thank you very mutch.

Joshy

Code:
option explicit

const EAGAIN                       = 11 ' Try again
const EPIPE                        = 32 ' Broken pipe
const ESTRPIPE                     = 86 ' Streams pipe error

const BLOCK                        = 0
const NONBLOCK                     = 1
const ASYNC                        = 2
const SND_PCM_STREAM_PLAYBACK      = 0
const SND_PCM_STREAM_CAPTURE       = 1
const SND_PCM_FORMAT_S16_LE        = 2
const SND_PCM_ACCESS_RW_INTERLEAVED= 3

type snd_pcm_t           as _snd_pcm
type snd_pcm_hw_params_t as _snd_pcm_hw_params

' PCM
declare function snd_pcm_open cdecl alias "snd_pcm_open" ( _
byval pcm          as snd_pcm_t ptr ptr, _
byval device       as string, _
byval direction    as integer, _
byval mode         as integer) as integer

declare function snd_pcm_close cdecl alias "snd_pcm_close" ( _
byval pcm          as snd_pcm_t ptr) as integer

declare function snd_pcm_hw_free cdecl alias "snd_pcm_hw_free" ( _
byval pcm          as snd_pcm_t ptr) as integer

declare function snd_pcm_nonblock cdecl alias "snd_pcm_nonblock" ( _
byval pcm          as snd_pcm_t ptr, _
byval nonblock     as integer) as integer

declare function snd_pcm_prepare cdecl alias "snd_pcm_prepare" ( _
byval pcm as snd_pcm_t ptr) as integer

declare function snd_pcm_writei cdecl alias "snd_pcm_writei" ( _
byval pcm          as snd_pcm_t ptr, _
byval buffer       as any ptr, _
byval size         as integer) as integer

declare function snd_pcm_resume cdecl alias "snd_pcm_resume" ( _
byval pcm as snd_pcm_t ptr) as integer

'hardware
declare function snd_pcm_hw_params_malloc cdecl alias "snd_pcm_hw_params_malloc" ( _
byval hw           as snd_pcm_hw_params_t ptr ptr) as integer

declare function snd_pcm_hw_params_any cdecl alias "snd_pcm_hw_params_any" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr) as integer

declare function snd_pcm_hw_params_set_access cdecl alias "snd_pcm_hw_params_set_access" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval mode         as integer) as integer

declare function snd_pcm_hw_params_set_format cdecl alias "snd_pcm_hw_params_set_format" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval fmt          as integer) as integer

declare function snd_pcm_hw_params_set_channels cdecl alias "snd_pcm_hw_params_set_channels" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval Channels     as integer) as integer

declare function snd_pcm_hw_params_get_channels cdecl alias "snd_pcm_hw_params_get_channels" ( _
byval hw           as snd_pcm_hw_params_t ptr, _
byval lpChannels   as integer ptr) as integer

declare function snd_pcm_hw_params_set_rate_near cdecl alias "snd_pcm_hw_params_set_rate_near" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval lpRate         as integer ptr, _
byval lpDir        as integer ptr) as integer

declare function snd_pcm_hw_params_set_periods_near cdecl alias "snd_pcm_hw_params_set_periods_near" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval lpValue      as integer ptr, _
byval lpDir        as integer ptr) as integer

declare function snd_pcm_hw_params_get_period_size cdecl alias "snd_pcm_hw_params_get_period_size" ( _
byval params       as snd_pcm_hw_params_t ptr, _
byval lpFrames     as integer ptr, _
byval lpDir        as integer ptr) as integer

declare function snd_pcm_hw_params_set_buffer_size_near cdecl alias "snd_pcm_hw_params_set_buffer_size_near" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr, _
byval lpFrames     as integer ptr) as integer

declare function snd_pcm_hw_params_get_buffer_size cdecl alias "snd_pcm_hw_params_get_buffer_size" ( _
byval hw           as snd_pcm_hw_params_t ptr, _
byval lpFrames     as integer ptr) as integer

declare function snd_pcm_hw_params cdecl alias "snd_pcm_hw_params" ( _
byval pcm          as snd_pcm_t ptr, _
byval hw           as snd_pcm_hw_params_t ptr) as integer

declare sub snd_pcm_hw_params_free cdecl alias "snd_pcm_hw_params_free" ( _
byval hw as snd_pcm_hw_params_t ptr)

#inclib "asound"


'#define device "plughw:0,0"
'#define device "hw:0,0"

union uniptr
  ptr8       as byte  ptr '  -128 to   +127
  ptr16      as short ptr '-32768 to +32767
end union
type player_driver_t
  handle     as snd_pcm_t ptr 'NULL = Error
  Speed      as integer  ' 11025 22050 44100
  nChannels  as integer  ' 1 or 2
  nBits      as integer  ' 8 or 16
  nFrames    as integer  ' 512,1024,2048,4096 and so on
  FrameSize  as integer  ' (nBits\8) * nChannels
  nPeriods   as integer  ' try 2
  PeriodSize as integer  ' BufferSize / FrameSize
  Buffer     as uniptr
end type

function Alsa_Init(byval strDevice as string="hw:0,0", _
                   byval Speed    as integer=44100, _
                   byval Bits     as integer=16, _
                   byval Channels as integer=2, _
                   byval Frames   as integer=4096) as player_driver_t ptr
  Bits \=8
  Frames\=256

  ' range of Speed
  if Speed < 11025 then
    Speed = 11025
  elseif Speed>48000 then
    Speed = 48000
  end if
  ' range of Bits
  if Bits<1 then
    Bits=1
  elseif Bits>2 then
    Bits=2
  end if
  ' range of Channels
  if Channels<1 then
    Channels=1
  elseif Channels>2 then
    Channels=2
  end if
  ' range of frames
  if Frames<2 then
    Frames=2
  elseif Frames>32 then
    Frames=32
  end if
  Bits   = Bits   shl 3  ' *   8
  Frames = Frames shl 7  ' * 256

  dim as snd_pcm_t ptr           htmp
  dim as snd_pcm_hw_params_t ptr hw
  dim as integer                 ret, direction,PeriodSize
  dim as player_driver_t ptr     tmp
  dim as zstring ptr             strRet
  ' open device in non blocking mode
  ret = snd_pcm_open(@htmp, strDevice, SND_PCM_STREAM_PLAYBACK, NONBLOCK)
  if (ret < 0) then ? "failed open":goto Alsa_Init_Error

  ' switch to blocking mode
  ret=snd_pcm_nonblock(htmp,BLOCK)
  if (ret < 0) then ? "failed block":goto Alsa_Init_Error

  'alloc the player
  tmp=callocate(sizeof(player_driver_t))
  tmp->Speed      = Speed
  tmp->nChannels  = Channels
  tmp->nBits      = Bits
  tmp->FrameSize  = (Bits \ 8) * Channels
  tmp->nFrames    = Frames
  tmp->nPeriods   = 2
  tmp->PeriodSize = 0

  ' qwery param
  snd_pcm_hw_params_malloc(@hw)
  ret = snd_pcm_hw_params_any(htmp,hw)
  if (ret < 0) then ? "failed hw_param_any":goto Alsa_Init_Error

  ' set read write access
  ret = snd_pcm_hw_params_set_access(htmp, hw, SND_PCM_ACCESS_RW_INTERLEAVED)
  if (ret < 0) then ? "failed set_access":goto Alsa_Init_Error

  if tmp->nBits=8 then
     ret = snd_pcm_hw_params_set_format(htmp,hw,1) 'set 8bit unsigned
     'if (ret<0) then ret = snd_pcm_hw_params_set_format(htmp,hw,1) 'set 8bit signed
  else
     ret = snd_pcm_hw_params_set_format(htmp,hw,2) ' set 16bit unsigned
  end if
  if (ret < 0) then ? "failed set_format":goto Alsa_Init_Error

  'set mono or stero
  ret = snd_pcm_hw_params_set_channels(htmp,hw, tmp->nChannels)
  if (ret < 0) then
    snd_pcm_hw_params_get_channels(hw,@tmp->nChannels)
    if (tmp->nChannels<>Channels) then ? "warning: use channels=";tmp->nChannels
  end if

  'set speed
  ret = snd_pcm_hw_params_set_rate_near(htmp,hw,@tmp->Speed,0)
  if (ret < 0) then
    ? "failed set_rate_near":goto Alsa_Init_Error
  elseif (ret > 0) then
    tmp->Speed=ret
  end if
  if tmp->Speed<>Speed then ? "warning: use speed";tmp->Speed

  ' set number of Frames
  ret = snd_pcm_hw_params_set_buffer_size_near(htmp, hw, @tmp->nFrames)
  if (ret < 0) then ? "failed set_buffer_size_near":goto Alsa_Init_Error

  ' Chunks of Frames
  ret = snd_pcm_hw_params_set_periods_near(htmp, hw,@tmp->nPeriods, 0)
  if (ret < 0) then ? "failed set_periods_near":goto Alsa_Init_Error
  snd_pcm_hw_params_get_period_size(hw,@tmp->PeriodSize,@Direction)

  ' set the config
  ret = snd_pcm_hw_params(htmp,hw)
  if (ret < 0) then ? "failed hw_params":goto Alsa_Init_Error

  ret = snd_pcm_prepare(htmp)
  if (ret < 0) then ? "failed prepare":goto Alsa_Init_Error

Alsa_Init_Ok:
  tmp->Handle=htmp
  snd_pcm_hw_params_free hw
  return tmp

Alsa_Init_Error:
  if hw  <>0 then snd_pcm_hw_params_free hw
  if htmp<>0 then snd_pcm_close          htmp
  if tmp <>0 then deallocate             tmp
  return 0

end function

sub Alsa_Exit(byval pcm as snd_pcm_t ptr)
  if pcm=0 then exit sub
  ? snd_pcm_close(pcm)
end sub

sub Alsa_Info(byval player  as player_driver_t ptr)
  ? "Alsa_Info"
  ? "-------------------"
  if player=0 then ? "not init":exit sub
  ? "speed     :" ; player->Speed
  ? "bits      :" ; player->nBits
  ? "channels  :" ; player->nChannels
  ? "frames    :" ; player->nFrames
  ? "framesize :" ; player->FrameSize
  ? "chunks    :" ; player->nPeriods
  ? "chunksize :" ; player->PeriodSize
end sub

sub Alsa_Send(byval player as player_driver_t ptr,byval nBytes as integer)

  dim as integer ret,nFrames
  dim as any ptr lpStart,lpEnd

  if player             =0 then exit sub
  if player->Handle     =0 then exit sub
  if player->Buffer.ptr8=0 then exit sub
  if nBytes             <1 then exit sub

  nFrames  = nBytes \ Player->FrameSize
  lpStart=Player->Buffer.ptr8
  lpEnd  =Player->Buffer.ptr8+nBytes

  while(lpStart<lpEnd)
    ret = snd_pcm_writei(Player->Handle,lpStart,nFrames)

    if (ret=-EAGAIN) then
      ' device busy
    elseif (ret=-ESTRPIPE) then
      ret=-EAGAIN
      while ret=-EAGAIN:ret=snd_pcm_resume(Player->Handle):wend
    elseif (ret=-EPIPE) then

    else
      if (ret<0) then  ? "failed send audiodata"
      if snd_pcm_prepare(Player->Handle) < 0 then exit sub
      nFrames-=ret:lpStart+=ret*Player->FrameSize
    endif
  wend
end sub

sub Fill_Buffer(byval Player as player_driver_t ptr,byval freq as integer=440)
  static as integer l,r
  static as double w1,w2
  dim    as double pif,scale,scale2
  dim    as integer i

  if Player=0 then exit sub
  if Player->Buffer.ptr8=0 then exit sub
  pif=(8.0*atn(1))/player->Speed
  scale =pif*freq
  scale2=pif*60

  if Player->nBits=8 then
    if Player->nChannels=1 then
      for i=0 to Player->nFrames*Player->nPeriods-1
        l=cubyte(sin(w1)*cos(w2)*64+64)
        player->Buffer.ptr8[i  ]=l
        w1+=scale
      next
    else
      for i=0 to Player->nFrames*Player->nPeriods*Player->nChannels - 1 step 2
        l=cubyte(sin(w1)     *cos(w2  )*64+64)
        r=cubyte(sin(w1*2.01)*cos(w2*2)*64+64)
        player->Buffer.ptr8[i  ]=l
        player->Buffer.ptr8[i+1]=r
        w1+=scale:w2+=scale2
      next
    end if
  else
    if Player->nChannels=1 then
      for i=0 to Player->nFrames*Player->nPeriods - 1
        l=cushort(sin(w1)*cos(w2)*8000+8000)
        player->Buffer.ptr16[i  ]=l
        w1+=scale
      next
    else
      for i=0 to Player->nFrames*Player->nPeriods*Player->nChannels - 1 step 2
        l=cshort(sin(w1)     *cos(w2  )*8000+8000)
        r=cshort(sin(w1*2.01)*cos(w2*2)*8000+8000)
        player->Buffer.ptr16[i  ]=l
        player->Buffer.ptr16[i+1]=r
        w1+=scale:w2+=scale2
      next
    end if
  end if
end sub


'
' main
'
dim as player_driver_t ptr player
dim as integer f

'Player=Alsa_Init(,22050, 8,1)
'Player=Alsa_Init(,22050, 8,2)
'Player=Alsa_Init(,22050,16,1)
'Player=Alsa_Init(,22050,16,1)
'Player=Alsa_Init(,44100, 8,2)
Player=Alsa_Init(,44100,16,2)
'Player=Alsa_Init(,48000,16,1)
'Player=Alsa_Init(,48000,16,1)



if Player=0 then end 1


Alsa_Info Player

player->Buffer.ptr8=allocate(Player->nFrames*Player->FrameSize*Player->nPeriods)
sleep 1000,1
while inkey=""
  f=int(rnd*880)
  Fill_Buffer player,f
  Alsa_Send player,Player->nFrames*Player->FrameSize*Player->nPeriods
wend
end
sorry about my english
Reply
#12
Player=Alsa_Init(,22050, 8,1)
failed set_format
Player=Alsa_Init(,22050, 8,2)
failed set_format
Player=Alsa_Init(,22050,16,1)
worked
Player=Alsa_Init(,22050,16,1)
worked
Player=Alsa_Init(,44100, 8,2)
failed set format
Player=Alsa_Init(,44100,16,2)
worked
Player=Alsa_Init(,48000,16,1)
worked
Player=Alsa_Init(,48000,16,1)
worked

Ubuntu Linux Breezy Badger kernel 2.6.12-10-386
/post]
Reply
#13
Hello red Marvin,
your ac97 onboard sound is an standardchip in scope of alsa and it makes me wonder why it dosn't run in 8 bit.

I have test it with CMEDIA onboard and DMX fire 1024 both with ac97 codec.

Take a look in the alsa card database if you can found your soundchip/manufactur.

http://www.alsa-project.org/alsa-doc/ind...All#matrix

Now i will not spent more time with this problem i make the FBSOUND lib ready to use and the default mode will be 16 bit stereo.

the first simple command's on Windows and Linux are this

if FBSound_Init([device],[speed],[bits],[channels]) then ...
or simple
if FBSound_Init() then ...
hSound1=FBSound_Load(File1)
hSound2=FBSound_Load(File2)
hSound3=FBSound_Load(File3)
...
FBSound_Play hSound1,1 'play once
FBSound_Play hSound2,10 'play ten times
FBSound_Play hSound3 'play endless / looping

FBSound_Set_Volume hSound,Value
Value=FBSound_Get_Volume(hSound)

FBSound_Set_Mainvolume Value
Value=FBSound_Get_Mainvolume()

FBSound_Set_Speed hSound,Value
Value=FBSound_Get_Speed(hSound)

FBSound_Set_Pan hSound,Value
Value=FBSound_Get_Pan(hSound)

The number of sound channels are free.

The lib will be run in it's own thread test's with 6 channels give me only 3-4% CPU usage the mixing is done in assembler.

If other FB coder's find this free Win and Lin compatble lib useful for demos or games i will extend it with this things.

MP3 Streaming
DSP Filter (Chorus, Flanger ...)
DSP Effekte (Hall, Reverb ...)
10 Band EQ 220Hz. - 20KHz.
3D Listener und Dopplereffekt

Again thx for your support.

Joshy
sorry about my english
Reply
#14
According to my hardware detection it should be a
SIS 740 with a SI7012 chipset.
/post]
Reply
#15
In the C sourcecode of your linux sound driver i found this lines.
/* Please note that an 8bit stream is not valid on this card, you must have a 16bit stream at a minimum for this card to be happy*/

this makes many things clear for me :wink:

Joshy
sorry about my english
Reply
#16
could you please zip those files and put them on a server ( when lacking a server try fileanchor ). i can't keep track of what i have to put in what file.
quote="NecrosIhsan"]
[Image: yagl1.png]
[/quote]
Reply
#17
Hello marzecTM,
there are nothing to zip this was only an test for the ALSA lib.

Now the lib will use DSound, MMSystem (win) OSS, ALSA. (lin)

If my free FBSound lib are ready i will make a download and forum section on my server.

Joshy
sorry about my english
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)