Play Sound problem (alsa)

Linux specific questions.
Post Reply
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Play Sound problem (alsa)

Post by VANYA »

Hello everybody!

Guys, who knows please tell me why the code below only play short on the length of the melody? If the melody is not longer than ~20 seconds, then everything is fine, but if 1-2 minutes, the sound is interrupted somewhere after ~20 seconds.

Linux mint 64-bit

Code: Select all

Dim Shared As Any Ptr alsa
Dim Shared As long OSS


'ALSA declarations
alsa = Dylibload("asound")

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_ACCESS_RW_INTERLEAVED= 3

enum  	snd_pcm_format_t 
  SND_PCM_FORMAT_UNKNOWN = -1
  SND_PCM_FORMAT_S8 = 0
  SND_PCM_FORMAT_U8
  SND_PCM_FORMAT_S16_LE
  SND_PCM_FORMAT_S16_BE
  SND_PCM_FORMAT_U16_LE
  SND_PCM_FORMAT_U16_BE
  SND_PCM_FORMAT_S24_LE
  SND_PCM_FORMAT_S24_BE
  SND_PCM_FORMAT_U24_LE
  SND_PCM_FORMAT_U24_BE
  SND_PCM_FORMAT_S32_LE
  SND_PCM_FORMAT_S32_BE
  SND_PCM_FORMAT_U32_LE
  SND_PCM_FORMAT_U32_BE
  SND_PCM_FORMAT_FLOAT_LE
  SND_PCM_FORMAT_FLOAT_BE
  SND_PCM_FORMAT_FLOAT64_LE
  SND_PCM_FORMAT_FLOAT64_BE
  SND_PCM_FORMAT_IEC958_SUBFRAME_LE
  SND_PCM_FORMAT_IEC958_SUBFRAME_BE
  SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_A_LAW
  SND_PCM_FORMAT_IMA_ADPCM
  SND_PCM_FORMAT_MPEG
  SND_PCM_FORMAT_GSM
  SND_PCM_FORMAT_SPECIAL = 31
  SND_PCM_FORMAT_S24_3LE = 32
  SND_PCM_FORMAT_S24_3BE
  SND_PCM_FORMAT_U24_3LE
  SND_PCM_FORMAT_U24_3BE
  SND_PCM_FORMAT_S20_3LE
  SND_PCM_FORMAT_S20_3BE
  SND_PCM_FORMAT_U20_3LE
  SND_PCM_FORMAT_U20_3BE
  SND_PCM_FORMAT_S18_3LE
  SND_PCM_FORMAT_S18_3BE
  SND_PCM_FORMAT_U18_3LE
  SND_PCM_FORMAT_U18_3BE
  SND_PCM_FORMAT_G723_24
  SND_PCM_FORMAT_G723_24_1B
  SND_PCM_FORMAT_G723_40
  SND_PCM_FORMAT_G723_40_1B
  SND_PCM_FORMAT_DSD_U8
  SND_PCM_FORMAT_DSD_U16_LE
  SND_PCM_FORMAT_DSD_U32_LE
  SND_PCM_FORMAT_DSD_U16_BE
  SND_PCM_FORMAT_DSD_U32_BE
  SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_DSD_U32_BE
  SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE
  SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE
  SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE
  SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE
  SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE
  SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE
  SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_LE
  SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_LE
  SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_LE
end enum

#IFNDEF NULL
#DEFINE NULL 0
#ENDIF

Type snd_pcm_t           As Any Ptr
Type snd_pcm_hw_params_t As Any Ptr
Type snd_output_t        As Any Ptr

' PCM


Dim Shared snd_strerror As Function ( _
Byval ecode As long) As Zstring Ptr
snd_strerror= Dylibsymbol(alsa, "snd_strerror")

Dim Shared snd_pcm_open As Function ( _
Byval pcm          As snd_pcm_t Ptr, _
Byval device       As Zstring Ptr, _
Byval direction    As long, _
Byval mode         As long) As long
snd_pcm_open= Dylibsymbol(alsa, "snd_pcm_open")

Dim Shared snd_pcm_close As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_close= Dylibsymbol(alsa, "snd_pcm_close")

Dim Shared snd_pcm_start As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_start= Dylibsymbol(alsa, "snd_pcm_start")

Dim Shared snd_pcm_drain As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_drain= Dylibsymbol(alsa, "snd_pcm_drain")

Dim Shared snd_pcm_hw_free As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_hw_free= Dylibsymbol(alsa, "snd_pcm_hw_free")

Dim Shared snd_pcm_nonblock As Function ( _
Byval pcm          As snd_pcm_t, _
Byval nonblock     As long) As long
snd_pcm_nonblock= Dylibsymbol(alsa, "snd_pcm_nonblock")

Dim Shared snd_pcm_prepare As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_prepare= Dylibsymbol(alsa, "snd_pcm_prepare")

Dim Shared snd_pcm_writei As Function ( _
Byval pcm          As snd_pcm_t, _
Byval buffer       As Any Ptr, _
Byval size         As long) As long
snd_pcm_writei= Dylibsymbol(alsa, "snd_pcm_writei")

Dim Shared snd_pcm_recover As Function ( _
Byval pcm          As snd_pcm_t, _
Byval Err          As long, _
Byval silent       As long) As long
snd_pcm_recover= Dylibsymbol(alsa, "snd_pcm_recover")

Dim Shared snd_pcm_avail_update As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_avail_update= Dylibsymbol(alsa, "snd_pcm_avail_update")

Dim Shared snd_pcm_delay As Function ( _
Byval pcm          As snd_pcm_t, _
Byval delayp       As snd_pcm_t) As long
snd_pcm_delay= Dylibsymbol(alsa, "snd_pcm_delay")

Dim Shared snd_pcm_wait As Function ( _
Byval pcm          As snd_pcm_t, _
Byval msec As long) As long
snd_pcm_wait= Dylibsymbol(alsa, "snd_pcm_wait")

Dim Shared snd_pcm_resume As Function ( _
Byval pcm          As snd_pcm_t) As long
snd_pcm_resume= Dylibsymbol(alsa, "snd_pcm_resume")

'hardware
Dim Shared snd_pcm_hw_params_malloc As Function ( _
Byval hw           As snd_pcm_hw_params_t Ptr) As long
snd_pcm_hw_params_malloc= Dylibsymbol(alsa, "snd_pcm_hw_params_malloc")

Dim Shared snd_pcm_hw_params_any As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t) As long
snd_pcm_hw_params_any= Dylibsymbol(alsa, "snd_pcm_hw_params_any")

Dim Shared snd_pcm_hw_params_set_access As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval mode         As long) As long
snd_pcm_hw_params_set_access= Dylibsymbol(alsa, "snd_pcm_hw_params_set_access")

Dim Shared snd_pcm_hw_params_set_format As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval fmt          As long) As long
snd_pcm_hw_params_set_format= Dylibsymbol(alsa, "snd_pcm_hw_params_set_format")

Dim Shared snd_pcm_hw_params_set_channels As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval Channels     As long) As long
snd_pcm_hw_params_set_channels= Dylibsymbol(alsa, "snd_pcm_hw_params_set_channels")

Dim Shared snd_pcm_hw_params_get_channels As Function ( _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpChannels   As long Ptr) As long
snd_pcm_hw_params_get_channels= Dylibsymbol(alsa, "snd_pcm_hw_params_get_channels")

Dim Shared snd_pcm_hw_params_set_rate_near As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpRate       As long Ptr, _
Byval lpDir        As long Ptr) As long
snd_pcm_hw_params_set_rate_near= Dylibsymbol(alsa, "snd_pcm_hw_params_set_rate_near")


Dim Shared snd_pcm_hw_params_get_periods As Function ( _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpValue      As long Ptr, _
Byval lpDir        As long Ptr) As long
snd_pcm_hw_params_get_periods= Dylibsymbol(alsa, "snd_pcm_hw_params_get_periods")

Dim Shared snd_pcm_hw_params_set_periods_near As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpValue      As long Ptr, _
Byval lpDir        As long Ptr) As long
snd_pcm_hw_params_set_periods_near= Dylibsymbol(alsa, "snd_pcm_hw_params_set_periods_near")

Dim Shared snd_pcm_hw_params_get_period_size As Function ( _
Byval params       As snd_pcm_hw_params_t, _
Byval lpFrames     As long Ptr, _
Byval lpDir        As long Ptr) As long
snd_pcm_hw_params_get_period_size= Dylibsymbol(alsa, "snd_pcm_hw_params_get_period_size")

Dim Shared snd_pcm_hw_params_set_period_size_near As Function ( _
Byval pcm          As snd_pcm_t Ptr, _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpValue      As long Ptr, _
Byval lpDir        As long Ptr) As long
snd_pcm_hw_params_set_period_size_near= Dylibsymbol(alsa, "snd_pcm_hw_params_set_period_size_near")

Dim Shared snd_pcm_hw_params_set_buffer_size_near As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpFrames     As long Ptr) As long
snd_pcm_hw_params_set_buffer_size_near= Dylibsymbol(alsa, "snd_pcm_hw_params_set_buffer_size_near")

Dim Shared snd_pcm_hw_params_get_buffer_size As Function ( _
Byval hw           As snd_pcm_hw_params_t, _
Byval lpFrames     As long Ptr) As long
snd_pcm_hw_params_get_buffer_size= Dylibsymbol(alsa, "snd_pcm_hw_params_get_buffer_size")

Dim Shared snd_pcm_hw_params As Function ( _
Byval pcm          As snd_pcm_t, _
Byval hw           As snd_pcm_hw_params_t) As long
snd_pcm_hw_params= Dylibsymbol(alsa, "snd_pcm_hw_params")

Dim Shared snd_pcm_hw_params_free As Sub ( _
Byval hw           As snd_pcm_hw_params_t)
snd_pcm_hw_params_free= Dylibsymbol(alsa, "snd_pcm_hw_params_free")
     

Dim Shared As snd_pcm_t Ptr           hDevice
Dim Shared As snd_pcm_hw_params_t Ptr hw
Dim Shared As long                 ret,value,direction,buffersize,nFrames,Periodsize
Dim Shared As Zstring Ptr             strRet


'OSS declarations

#INCLUDE "file.bi"

OSS=FileExists("/dev/dsp")

Declare Function fileno Cdecl Alias "fileno" (Byval As Any Ptr) As long
Declare Function ioctl Cdecl Alias "ioctl" (Byval hDevice As long,Byval io_cmd As long,Byval lpArg As long Ptr) As long


#DEFINE _IOC_NRBITS    8
#DEFINE _IOC_TYPEBITS  8
#DEFINE _IOC_SIZEBITS 14
#DEFINE _IOC_DIRBITS   2

#DEFINE _IOC_NRMASK   ((1 Shl _IOC_NRBITS  )-1)
#DEFINE _IOC_TYPEMASK ((1 Shl _IOC_TYPEBITS)-1)
#DEFINE _IOC_SIZEMASK ((1 Shl _IOC_SIZEBITS)-1)
#DEFINE _IOC_DIRMASK  ((1 Shl _IOC_DIRBITS )-1)

#DEFINE _IOC_NRSHIFT    0
#DEFINE _IOC_TYPESHIFT  (_IOC_NRSHIFT   + _IOC_NRBITS)
#DEFINE _IOC_SIZESHIFT  (_IOC_TYPESHIFT + _IOC_TYPEBITS)
#DEFINE _IOC_DIRSHIFT   (_IOC_SIZESHIFT + _IOC_SIZEBITS)

' Direction bits.
#DEFINE _IOC_NONE  0U
#DEFINE _IOC_WRITE 1U
#DEFINE _IOC_READ  2U

#DEFINE _IOC(Dir,t,nr,size) (((Dir) Shl _IOC_DIRSHIFT) Or ((t) Shl _IOC_TYPESHIFT) Or ((nr)  Shl _IOC_NRSHIFT) Or ((size) Shl  _IOC_SIZESHIFT))

' used to create numbers
#DEFINE _IO(t,nr)        _IOC(_IOC_NONE,(t),(nr),0)
#DEFINE _IOR(t,nr,size)  _IOC(_IOC_READ,(t),(nr),Sizeof(size))
#DEFINE _IOW(t,nr,size)  _IOC(_IOC_WRITE,(t),(nr),Sizeof(size))
#DEFINE _IOWR(t,nr,size) _IOC(_IOC_READ Or _IOC_WRITE,(t),(nr),Sizeof(size))

' used to decode ioctl numbers..
#DEFINE _IOC_DIR(nr)   (((nr) Shr _IOC_DIRSHIFT)  And _IOC_DIRMASK)
#DEFINE _IOC_TYPE(nr)  (((nr) Shr _IOC_TYPESHIFT) And _IOC_TYPEMASK)
#DEFINE _IOC_NR(nr)    (((nr) Shr _IOC_NRSHIFT)   And _IOC_NRMASK)
#DEFINE _IOC_SIZE(nr)  (((nr) Shr _IOC_SIZESHIFT) And _IOC_SIZEMASK)

' ...and for the drivers/sound files...
#DEFINE IOC_IN        ( _IOC_WRITE    Shl _IOC_DIRSHIFT)
#DEFINE IOC_OUT       ( _IOC_READ     Shl _IOC_DIRSHIFT)
#DEFINE IOC_INOUT     ((_IOC_WRITE    Or  _IOC_READ) Shl _IOC_DIRSHIFT)
#DEFINE IOCSIZE_MASK  ( _IOC_SIZEMASK Shl _IOC_SIZESHIFT)
#DEFINE IOCSIZE_SHIFT ( _IOC_SIZESHIFT)

' IOCTL commands for /dev/dsp and /dev/audio
#DEFINE SNDCTL_DSP_RESET          _IO  (Asc("P"), 0)
#DEFINE SNDCTL_DSP_SYNC           _IO  (Asc("P"), 1)
#DEFINE SNDCTL_DSP_SPEED          _IOWR(Asc("P"), 2, long)
#DEFINE SNDCTL_DSP_STEREO         _IOWR(Asc("P"), 3, long)
#DEFINE SNDCTL_DSP_GETBLKSIZE     _IOWR(Asc("P"), 4, long)
#DEFINE SNDCTL_DSP_SETFMT         _IOWR(Asc("P"), 5, long) ' Selects ONE fmt
#DEFINE SNDCTL_DSP_CHANNELS       _IOWR(Asc("P"), 6, long)
#DEFINE SOUND_PCM_WRITE_CHANNELS  SNDCTL_DSP_CHANNELS
#DEFINE SOUND_PCM_WRITE_FILTER    _IOWR(Asc("P"), 7, long)
#DEFINE SNDCTL_DSP_POST           _IO  (Asc("P"), 8)
#DEFINE SNDCTL_DSP_SUBDIVIDE      _IOWR(Asc("P"), 9, long)
#DEFINE SNDCTL_DSP_SETFRAGMENT    _IOWR(Asc("P"),10, long)
#DEFINE SNDCTL_DSP_GETFMTS        _IOR (Asc("P"),11, long) ' Returns a mask
#DEFINE SNDCTL_DSP_SAMPLESIZE     SNDCTL_DSP_SETFMT
#DEFINE SNDCTL_DSP_GETODELAY   _IOR (Asc("P"), 23, long)


'arg for SNDCTL_DSP_SETFMT cmd
Const AFMT_MU_LAW    = &H00000001
Const AFMT_A_LAW     = &H00000002
Const AFMT_IMA_ADPCM = &H00000004
Const AFMT_U8        = &H00000008
Const AFMT_S16_LE    = &H00000010  ' Little endian signed
Const AFMT_S16_BE    = &H00000020  ' Big endian signed 16
Const AFMT_S8        = &H00000040
Const AFMT_U16_LE    = &H00000080  ' Little endian U16
Const AFMT_U16_BE    = &H00000100  ' Big endian U16
Const AFMT_MPEG      = &H00000200  ' MPEG (2) audio
Const AFMT_AC3       = &H00000400  ' Dolby Digital AC3


Sub SoundSet(frequency As long, channels As long, bits As long)
   If alsa Then
      If bits=16 Then PeriodSize=2 Else Periodsize=1
      Periodsize*=channels

      ret = snd_pcm_open(@hDevice,"default", SND_PCM_STREAM_PLAYBACK, BLOCK)

      snd_pcm_hw_params_malloc(@hw)
      ret = snd_pcm_hw_params_any(hDevice,hw)
      ret = snd_pcm_hw_params_set_access(hDevice, hw, SND_PCM_ACCESS_RW_INTERLEAVED)

      ret = snd_pcm_hw_params_set_format(hDevice,hw,SND_PCM_FORMAT_S16_LE)
      ret = snd_pcm_hw_params_set_channels(hDevice,hw,channels)

      value=frequency 'set speed
      ret = snd_pcm_hw_params_set_rate_near(hDevice,hw,@value,@direction)

      ret = snd_pcm_hw_params(hDevice,hw)
      snd_pcm_hw_params_free (hw)
      snd_pcm_prepare(hDevice)
   Elseif OSS Then
      If OSS>0 Then Close OSS
      OSS=FreeFile
      Open "/dev/dsp" For Output As #1

      Dim As long arg
      arg=IIF(bits=16, AFMT_S16_LE, AFMT_U8)
      ioctl fileno(Cast (Any Ptr,Fileattr(1,2))), SNDCTL_DSP_SETFMT, @arg

      arg=IIF(channels<>0, 1, 0)
      ioctl fileno(Cast (Any Ptr,Fileattr(1,2))), SNDCTL_DSP_STEREO, @arg

      arg=channels
      ioctl fileno(Cast (Any Ptr,Fileattr(1,2))), SNDCTL_DSP_CHANNELS, @arg

      arg=frequency
      ioctl fileno(Cast (Any Ptr,Fileattr(1,2))), SNDCTL_DSP_SPEED, @arg


   End If

End Sub

Sub playbuffer (soundBuffer As Any Ptr, buffersize As long)

  If alsa Then

      buffersize/=Periodsize

      ret=snd_pcm_writei(hDevice, soundBuffer, buffersize)

      If ret=EPIPE Then

         ret=snd_pcm_recover(hDevice, ret,1)

         If ret=0 Then ret=snd_pcm_writei(hDevice, soundBuffer, buffersize)
      
      EndIf

   Elseif OSS>0 Then

      Put #OSS, ,*cast(Ubyte Ptr, soundBuffer), buffersize
   EndIf
End Sub

Function SoundQueue() As long
   If alsa Then
      Dim value As long
      snd_pcm_delay(hDevice, @value)
      Return value*Periodsize
   Elseif OSS>0 Then
      Dim value As long
      ioctl fileno(Cast (Any Ptr,Fileattr(1,2))), SNDCTL_DSP_GETODELAY, @value
      Return value
   End If
End Function

Dim as long samplerate, allBytes
Dim As Short fTag, ncanal , bits
Dim As Byte Ptr bBuf 


Dim idFile As long = Freefile

Open "33.wav" For Binary As #idFile

Get #idFile,21,fTag
Get #idFile,,ncanal
Get #idFile,,samplerate
Get #idFile,35,bits
Get #idFile,41,allBytes

bBuf = Allocate (allBytes+1)

Get #idFile,45,*bBuf,allBytes

Close
 

SoundSet samplerate,ncanal,bits

playbuffer bBuf,allBytes


do
print SoundQueue()
loop until SoundQueue() = 0


David Watson
Posts: 57
Joined: May 15, 2013 16:48
Location: England

Re: Play Sound problem (alsa)

Post by David Watson »

You seem to be trying to play an entire wave file in your sound card's buffer! If your sound card's buffer is 1 MiB and you are playing a 48 kHz, 8-bit, mono sample then you will be limited to 1048576 / 48000 / 1 / 1 = 21.845 seconds.

You need to switch to something like sdl_mixer instead.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Play Sound problem (alsa)

Post by VANYA »

David Watson wrote:You seem to be trying to play an entire wave file in your sound card's buffer! If your sound card's buffer is 1 MiB and you are playing a 48 kHz, 8-bit, mono sample then you will be limited to 1048576 / 48000 / 1 / 1 = 21.845 seconds.

You need to switch to something like sdl_mixer instead.
Thank you David for attention to my question!

I'm very bad at Linux. Do I understand correctly that when using the ALSA API with large buffers, will it be necessary to split the buffer into parts and send them to a sound card in a cycle? Do you know articles on the topic of playing PCM with large amounts of data with help API ALSA, could you recommend them?
David Watson
Posts: 57
Joined: May 15, 2013 16:48
Location: England

Re: Play Sound problem (alsa)

Post by David Watson »

You are correct about splitting the audio into parts (usually around 20 milliseconds or so). If you can read C then you might want to look at the pcm.c and pcm_min.c examples at http://www.alsa-project.org/alsa-doc/al ... mples.html

Are you sure you don't want to use sdl_mixer?
David Watson
Posts: 57
Joined: May 15, 2013 16:48
Location: England

Re: Play Sound problem (alsa)

Post by David Watson »

I wrote this test program years ago. It plays both a wave file and an internally rendered buffer. It might be useful to you.

Code: Select all

'sdl_mixer (program to test sdl_mixer sound api) - David Watson



'######################### set up variables and screen #########################
#include "SDL\SDL.bi"
#include "SDL\SDL_mixer.bi"

'note - sdl2 api has backwards compatible audio, just change the includes:
'#include "SDL2\SDL.bi"
'#include "SDL2\SDL_mixer.bi"

dim as short			a
dim as string			i
dim as byte				buffer(9599)
dim as Mix_Chunk ptr	sample1, sample2

screen 18, 8

for a = 0 to 4799
	buffer(a * 2 + 1) = sin(a / 17.3624) * 127	'store sinewave in msbs
next a



'#################### initialize sdl_mixer and load sample #####################
SDL_Init(SDL_INIT_AUDIO)

if Mix_OpenAudio(48000, AUDIO_S16, 1, 1024) <> 0 then
	print "Error initializing SDL_mixer"
	SDL_Quit
	sleep
	end
endif

sample1 = Mix_QuickLoad_RAW(@buffer(0), 9600)	'create 100 ms buffer

sample2 = Mix_LoadWAV("gun.wav")
if sample2 = 0 then
	print "Error loading sample"
	Mix_CloseAudio
	SDL_Quit
	sleep
	end
endif



'################################## main loop ##################################
print "Press space bar to play gun sample, S to play sinewave or Esc to quit."
do
	i = inkey
	if i = "s" then Mix_PlayChannel(-1, sample1, 9)		'loop 10 times
	if i = " " then Mix_PlayChannel(-1, sample2, 0)
	sleep 50
loop until i = chr(27) or i = chr(255) + "k"	'esc or close button pressed

Mix_CloseAudio
SDL_Quit
end
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Play Sound problem (alsa)

Post by VANYA »

Thank you David!

I looked at sdl_mixer. Good library.

I wanted to achieve playback with the help of ALSA because of the fact that ALSA allows you to play "PCM data in IEEE floating-point format".
David Watson
Posts: 57
Joined: May 15, 2013 16:48
Location: England

Re: Play Sound problem (alsa)

Post by David Watson »

Your sound card is limited to 16 or 24-bit only, so it might be easier to render in 32-bit float, convert to 16-bit signed integer then play the 16-bit data.

If you really need to play 32-bit float then take a look at JACK http://www.jackaudio.org/api/
JACK uses 32-bit float exclusively.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Play Sound problem (alsa)

Post by VANYA »

David Watson wrote:Your sound card is limited to 16 or 24-bit only, so it might be easier to render in 32-bit float, convert to 16-bit signed integer then play the 16-bit data.

If you really need to play 32-bit float then take a look at JACK http://www.jackaudio.org/api/
JACK uses 32-bit float exclusively.
Thanks, I'll see.
David Watson
Posts: 57
Joined: May 15, 2013 16:48
Location: England

Re: Play Sound problem (alsa)

Post by David Watson »

If you don't need realtime playback then render a wave file and play it back with aplay.
This is from aplay's man page:
Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE
S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE
FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUB‐
FRAME_BE MU_LAW A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE
U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE
U18_3LE
FLOAT_LE is what you want.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Play Sound problem (alsa)

Post by VANYA »

David Watson wrote:If you don't need realtime playback then render a wave file and play it back with aplay.
This is from aplay's man page:
Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE
S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE
FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUB‐
FRAME_BE MU_LAW A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE
U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE
U18_3LE
FLOAT_LE is what you want.
David! I wanted to write a simple library for playing WAV. In Windows, I have no problem, I can play WAV files in many different ways (sndPlaySound, mcisendstring, DirectShow, DirectSound). And with all the means of the system, without resorting to third-party libraries. In Linux, I wanted the same functionality with the tools of the system, but as practice showed, in Linux with sound (without libraries) everything is very difficult.

I'll have to resort to your advice (sdl_mixer) for Linux. And the files that sdl_mixer will not play , I will be converted to a supported format.
CODEX
Posts: 1
Joined: Jul 24, 2017 9:51

Re: Play Sound problem (alsa)

Post by CODEX »

I wrote this game in FreeBasic
https://www.youtube.com/watch?v=4EuXnzaweEY
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Play Sound problem (alsa)

Post by counting_pine »

Hi CODEX, welcome to the forum!
There's not much to go on from a video alone.. Does it use alsa?
Otherwise (or even so?), I think the post should probably be moved to the Projects subforum.
Post Reply