* * *    
Главная » Статьи » Код PB

Просмотров: 1613 | Дата: 26.04.2024 | Коментарии (0)

Звуки



Code
;Raw Sound Creation Demo
;By: Joakim L. Christiansen
;Version: 1.1

EnableExplicit

; Structure WAVEFORMATEX ;may need to uncomment on Linux or Mac
; wFormatTag.w
; nChannels.w
; nSamplesPerSec.l
; nAvgBytesPerSec.l
; nBlockAlign.w
; wBitsPerSample.w
; cbSize.w
; EndStructure

Global format.WAVEFORMATEX

Procedure setWaveFormat(bitsPerSample=16,samplesPerSec=44100)
  format\wFormatTag = #WAVE_FORMAT_PCM
  format\nChannels = 1 ;mono
  format\wBitsPerSample = bitsPerSample ;8/16
  format\nSamplesPerSec = samplesPerSec ;8000 Hz, 11025 Hz, 22050 Hz, and 44100 Hz
  format\nBlockAlign = (format\nChannels * format\wBitsPerSample) / 8 ;equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte).
  format\nAvgBytesPerSec = format\nSamplesPerSec * format\nBlockAlign ;equal to the product of nSamplesPerSec and nBlockAlign
EndProcedure
Procedure.l createTone(*address,volume.d,duration,frequency.d) ;returns needed size if address=0
  ;creates a triangle wave
  Protected sample.l, result
  Protected pos, dir, waveY.d, maxValue, centerValue
  Protected samplesPerHalfWave, waveIncrementValue.d, size
  Protected samplesSinceHalfWave, waveTop.d
   
  size = (format\nSamplesPerSec / 1000*duration) * format\wBitsPerSample / 8
  If *address = 0 ;return size needed
  ProcedureReturn size
  EndIf
   
  If format\wBitsPerSample = 8
  maxValue = 255
  ElseIf format\wBitsPerSample = 16
  maxValue = 65535
  EndIf
  centerValue = (maxValue/2)
   
  waveTop = volume/1000 * centerValue
  samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
  waveIncrementValue = waveTop / samplesPerHalfWave

  For pos=0 To size
  If dir=0
  waveY + waveIncrementValue
  Else
  waveY - waveIncrementValue
  EndIf
  samplesSinceHalfWave + 1
  If samplesSinceHalfWave >= samplesPerHalfWave
  dir = dir!1 ;switch it
  samplesSinceHalfWave = 0
  EndIf
   
  If format\wBitsPerSample = 8
  sample = centerValue + waveY
  PokeA(*address+pos,sample)
  ElseIf format\wBitsPerSample = 16
  sample = waveY
  PokeW(*address+pos,sample)
  pos+1
  EndIf
  Next
EndProcedure
Procedure.l createToneEx(*address,volumeAtStart.d,volumeAtEnd.d,duration.d,frequencyAtStart.d,frequencyAtEnd.d=0,noiseAtStart.d=0,noiseAtEnd.d=0,backToStart=0) ;returns needed size if address=0
  ;creates a triangle wave with added effects
  Protected sample.l, result, pos, dir, waveY.d, maxValue, centerValue
  Protected samplesPerHalfWave.d, waveIncrementValue.d, size, samplesSinceHalfWave, waveTop.d
  Protected frequency.d, frequencyIncrementValue.d, noise.d, noiseIncrementValue.d, lastNoise.d, halfSize, loop, loops
  Protected waveYpos.d, volumeIncrementValue.d, volume.d
  volume = volumeAtStart
  frequency = frequencyAtStart
  noise = noiseAtStart
   
  size = (format\nSamplesPerSec / 1000*duration) * format\wBitsPerSample / 8
  If *address = 0 ;return size needed
  If backToStart
  ProcedureReturn size * 2
  Else
  ProcedureReturn size
  EndIf
  EndIf
   
  If format\wBitsPerSample = 8
  maxValue = 255
  ElseIf format\wBitsPerSample = 16
  maxValue = 65535
  EndIf
  centerValue = (maxValue/2)
  waveTop = centerValue
   
  samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
  waveIncrementValue = waveTop / samplesPerHalfWave
   
  volumeIncrementValue = (volumeAtEnd - volumeAtStart) / size * format\wBitsPerSample/8
  frequencyIncrementValue = (frequencyAtEnd - frequencyAtStart) / size * format\wBitsPerSample/8
  noiseIncrementValue = (noiseAtEnd - noiseAtStart) / size * format\wBitsPerSample/8
   
  If backToStart: loops=1: EndIf
  For loop=0 To loops
  For pos=pos To size
  If volumeAtEnd
  volume + volumeIncrementValue
  EndIf
  If frequencyAtEnd
  frequency + frequencyIncrementValue
  samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
  waveIncrementValue = waveTop / samplesPerHalfWave
  EndIf
  If noiseAtEnd
  noise + noiseIncrementValue
  EndIf
   
  If dir=0
  waveYpos + waveIncrementValue
  Else
  waveYpos - waveIncrementValue
  EndIf
  samplesSinceHalfWave + 1
  If samplesSinceHalfWave >= samplesPerHalfWave
  If dir=0
  waveYpos = waveTop
  Else
  waveYpos = -waveTop
  EndIf
  dir = dir!1 ;switch it
  samplesSinceHalfWave = 0
  EndIf
   
  waveY = waveYpos
   
  ;waveY = waveY*16
  ;waveY + Random(90000)

   
  If noiseAtStart
  If lastNoise >= noise; Random(noise) = 0
  Select 0
  Case 0: waveYpos = Random(maxValue)-centerValue
  Case 1: waveY = Random(maxValue)-centerValue
  ;Case 2: waveYpos = Random(maxValue) ; waveY + Random(90000)
  EndSelect
  lastNoise = 1
  Else
  lastNoise+1
  EndIf
  EndIf
   
  ;adjust volume
  waveY = volume/1000 * waveY

  If format\wBitsPerSample = 8
  sample = centerValue + waveY
  PokeA(*address+pos,sample)
  ElseIf format\wBitsPerSample = 16
  sample = waveY
  PokeW(*address+pos,sample)
  pos+1
  EndIf
  Next
   
  If backToStart ;morph back
  If volumeAtEnd
  volume = volumeAtEnd
  EndIf
  If frequencyAtEnd
  frequency = frequencyAtEnd
  EndIf
  If noiseAtEnd
  noise = noiseAtEnd
  EndIf
  volumeIncrementValue = -volumeIncrementValue
  frequencyIncrementValue = -frequencyIncrementValue
  noiseIncrementValue = -noiseIncrementValue
  size+size
  EndIf
  Next
EndProcedure

Procedure addWaveHeader(*address,dataSize,channels,samplesPerSec,blockAlign,bitsPerSample)
  ; RIFF Chunk
  PokeL(*address+ 0, 'FFIR')
  PokeL(*address+ 4, dataSize + 36)
  PokeL(*address+ 8, 'EVAW')
  ; FORMAT Chunk
  PokeL(*address+ 12, ' tmf')
  PokeL(*address+ 16, $0010)
  PokeW(*address+ 20, $01)
  PokeW(*address+ 22, channels)
  PokeL(*address+ 24, samplesPerSec)
  PokeL(*address+ 28, samplesPerSec * channels * (bitsPerSample / 8) )
  PokeW(*address+ 32, blockAlign)
  PokeW(*address+ 34, bitsPerSample)
  ; DATA Chunk
  PokeL(*address+ 36, 'atad')
  PokeL(*address+ 40, dataSize)
EndProcedure
Procedure catchTone(volume,duration,frequency)
  Protected *memory, id, size
  size = createTone(0,volume,duration,frequency) ;get size
  *memory = AllocateMemory(44+size)
  createTone(*memory+44,volume,duration,frequency) ;write wave data to memory
  addWaveHeader(*memory,size,format\nChannels,format\nSamplesPerSec,format\nBlockAlign,format\wBitsPerSample)
  id = CatchSound(#PB_Any,*memory)
  FreeMemory(*memory)
  ProcedureReturn id
EndProcedure
Procedure catchToneEx(volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd=0,noiseAtStart=0,noiseAtEnd=0,backToStart=0)
  Protected *memory, id, size
  size = createToneEx(0,volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd,noiseAtStart,noiseAtEnd,backToStart) ;get size
  *memory = AllocateMemory(44+size)
  createToneEx(*memory+44,volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd,noiseAtStart,noiseAtEnd,backToStart) ;write wave data to memory
  addWaveHeader(*memory,size,format\nChannels,format\nSamplesPerSec,format\nBlockAlign,format\wBitsPerSample)
  id = CatchSound(#PB_Any,*memory)
  FreeMemory(*memory)
  ProcedureReturn id
EndProcedure

InitSound()
setWaveFormat(16,44100)
Define snd_explosion, snd_laser, snd_shoot, snd_pacman, snd_flying

snd_explosion = catchToneEx(1000,100, 1000, 50,20, 20,100)
snd_laser = catchToneEx(1000,100, 300, 1500,200)
snd_shoot = catchToneEx(1000,1, 500, 200,10, 1,10)
snd_pacman = catchToneEx(500,0, 100, 400,200, 0,0, #True)
snd_flying = catchToneEx(500,0, 200, 10,0, 5,10, #True)

PlaySound(catchToneEx(1000,100, 2000, 200,40, 0,0)):Delay(2000)
PlaySound(catchToneEx(1000,100, 2000, 10,200, 100,1 )):Delay(2000)
PlaySound(snd_flying): Delay(400)
PlaySound(snd_flying): Delay(400)
PlaySound(snd_flying): Delay(400)
PlaySound(snd_flying): Delay(400)
PlaySound(snd_pacman): Delay(200)
PlaySound(snd_pacman): Delay(200)
PlaySound(snd_explosion): Delay(1000)
PlaySound(snd_laser): Delay(300)
PlaySound(snd_laser): Delay(300)
PlaySound(snd_shoot): Delay(1000)
PlaySound(catchToneEx(1000,100, 2000, 200,10, 1,100 )):Delay(2000)

;Have fun! ;-)










Сайт посвящён языку программирования PureBasic — коммерческий компилятор языка программирования, использующего синтаксис BASIC. Предназначен для создания кроссплатформенных приложений для AmigaOS, Linux, Microsoft Windows, Windows NT и Mac OS X. Разработан компанией Fantaisie Software.