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