Seite 2 von 2

Verfasst: 19.04.2007 17:16
von Andreas_S
Ertapt :oops:

habs nicht ausprobiert

Verfasst: 19.04.2007 19:00
von Kaeru Gaman
ts-soft hat geschrieben:... weil dann würde Speicher für 10000 Sounds reserviert.
es ist so wie bei gadgets und sprites aber es wird nicht speicher für 10000 sounds reserviert,
sondern "nur" speicher für 10000 pointer zu möglichen sound-speichern. ;)

@PBprogger
komplette info:
elemente die man in PB einrichten kann, werden in einer liste von pointern geführt,
falls man sie mit nummern und nicht mit PB_Any einrichtet.
(gilt für fenster, gadgets, sprites, images, sounds, usw.)

diese liste braucht auch platz. wenn man also ein einziges element mit Nr. 9999 einrichtet,
wird eine liste für 10.000 elemente erstellt, auch wenn die anderen 9999 elemente nicht benutzt werden.

Verfasst: 19.04.2007 19:28
von ts-soft

Code: Alles auswählen

 Structure PB_StructureSound
    Sound.l         ; DirectSound pointer
  EndStructure
Hast ja recht, wollte nur nicht nachsehen :wink:
Aber 39 KB sind doch auch was, in der grösse erstellen die freaks komplette
Spiele :mrgreen:

Verfasst: 20.04.2007 14:07
von Andreas_S
Ist der Code jetzt eigendlich nützlich? Ehrlich antworten!

Verfasst: 20.04.2007 18:07
von Fluid Byte
PBprogger hat geschrieben:Ist der Code jetzt eigendlich nützlich? Ehrlich antworten!
Ich finds schon ganz geil aber bis jetzt hab ich noch keinen richtigen Nutzen davon (außer dem Lerneffekt). Was neben Sinus noch fehlt sind andere Grundformen wie Square, Triangle, Sawtooth und Noise. In Addition dazu noch eine Art einfaches Playback System für eigene "Songs". Somit wäre es ideal als "Engine" für Demos oder kleinere Spiele.

Ach ja, wie integriert man eigentlich einen Tunning Table? Ich meine wie wird definiert was eine ganze Note ist? Mit dem Code gibt man ja die Tonhöhe nicht mit der Samplerate sondern mit der Frequenz an. Also wäre doch eine Note jeweils +100 oder?

Ganz vergessen, habs noch mal überarbeitet:

Code: Alles auswählen

Structure WAVEFORMATEX
    wFormatTag.w
    nChannels.w
    nSamplesPerSec.l
    nAvgBytesPerSec.l
    nBlockAlign.w
    wBitsPerSample.w
EndStructure

Procedure CreateSound(SoundID,Frequency,Millisecs,Samplerate=44100,Bitrate=16,Channels=1)
	Protected avBytesPerSec = Channels * Bitrate/8 * Samplerate
	Protected Seconds.d = Millisecs/1000
	Protected wfmt.WAVEFORMATEX
	
	*sndData = AllocateMemory(avBytesPerSec * Seconds + 44)
	
	PokeL(*sndData + 00,$46464952)						; RIFF Header
	PokeL(*sndData + 04,avBytesPerSec * Seconds + 44)	; Remaining File Length
	PokeL(*sndData + 08,$45564157)						; WAVE Header	
	PokeL(*sndData + 12,$20746D66)						; FMT Header
	PokeL(*sndData + 16,SizeOf(WAVEFORMATEX))			; FMT Chunk Length
	
	wfmt\wFormatTag = #WAVE_FORMAT_PCM
	wfmt\nChannels = Channels
	wfmt\nSamplesPerSec = Samplerate
	wfmt\nAvgBytesPerSec = avBytesPerSec
	wfmt\nBlockAlign = avBytesPerSec / Samplerate
	wfmt\wBitsPerSample = Bitrate
	CopyMemory(wfmt,*sndData + 20,SizeOf(WAVEFORMATEX))
	
	PokeL(*sndData + 36,$61746164)						; DATA Header
	PokeL(*sndData + 40,avBytesPerSec * Seconds)		; DATA Chunk Length
	
	For ActTime=1 To Samplerate * Seconds
		For ActChannel=1 To Channels
			ActSampleVal = $7FFF * Sin(2 * #PI * Frequency * ActTime/Samplerate)			
			PokeW(*sndData + 44 + IncVal,ActSampleVal) : IncVal + 2						
		Next
	Next
	
	CatchSound(SoundID,*sndData) : FreeMemory(*sndData)
EndProcedure

InitSound()

CreateSound(0,1000,1000)
PlaySound(0)
Delay(1000)

Verfasst: 20.04.2007 18:28
von DarkDragon
Hallo,

Das ganze gab es schonmal. http://www.purebasic.fr/german/viewtopi ... 9661#19661
Fluid Byte hat geschrieben:Somit wäre es ideal als "Engine" für Demos oder kleinere Spiele.
QBPlay lib. Wird anscheinend noch auf PB4 portiert.

Verfasst: 20.04.2007 18:34
von Andreas_S
@Fluid Byte

Erstmal Danke und ich hab da noch ein bischen was dazu gemacht. Ist so eine Art kleine Wave erstellung. Hat sicher ein paar Fehler aber hier die Proceduren:

Code: Alles auswählen

Global numWave
Global NewList numFQ()
Global NewList numMS()

Procedure CreateWave()
 *Mem=AllocateMemory(16)
 ProcedureReturn *Mem
EndProcedure

Procedure SetSamplerate(Wave,samplerate)
 *Mem=Wave
 PokeL(*Mem,samplerate)
EndProcedure

Procedure SetBitrate(Wave,bitrate)
 *Mem=Wave
 PokeW(*Mem+4,bitrate)
EndProcedure

Procedure SetChannels(Wave,channels)
 *Mem=Wave
 PokeW(*Mem+6,channels)
EndProcedure

Procedure SetMs(Wave,ms.q)
 *Mem=Wave
 PokeQ(*Mem+8,ms)
EndProcedure

Procedure AddFQ(Wave,fq,ms)
 *Mem=Wave
 AllMS=PeekL(*Mem+12)
 AddElement(numFQ())
 numFQ()=fq
 AddElement(numMS())
 numMS()=ms
 AllMS+ms
 PokeL(*Mem+12,AllMS)
EndProcedure

Procedure Pause(Wave,ms)
 *Mem=Wave
 AllMS=PeekL(*Mem+12)
 AddElement(numFQ())
 numFQ()=0
 AddElement(numMS())
 numMS()=ms
 AllMS+ms
 PokeL(*Mem+12,AllMS)
EndProcedure

Procedure SaveWave(Wave,FileName$)
 *Mem=Wave
 samplerate.l=PeekL(*Mem)
 bitrate.w=PeekW(*Mem+4)
 channels.w=PeekW(*Mem+6)
 secs.d=PeekQ(*Mem+8)/1000

 avBytesPerSec=channels*bitrate/8*samplerate

 file=CreateFile(#PB_Any,FileName$)
  WriteByte(file,Asc("R"))
  WriteByte(file,Asc("I"))
  WriteByte(file,Asc("F"))
  WriteByte(file,Asc("F"))

  WriteLong(file,avBytesPerSec*secs+44)

  WriteByte(file,Asc("W"))
  WriteByte(file,Asc("A"))
  WriteByte(file,Asc("V"))
  WriteByte(file,Asc("E"))

  WriteByte(file,Asc("f"))
  WriteByte(file,Asc("m"))
  WriteByte(file,Asc("t"))
  WriteByte(file,Asc(" "))

  WriteLong(file,16)

  WriteWord(file,1)
  WriteWord(file,channels)
  WriteLong(file,samplerate)
  WriteLong(file,channels*bitrate/8*samplerate)
  WriteWord(file,bitrate/8*channels)
  WriteWord(file,bitrate)

  WriteByte(file,Asc("d"))
  WriteByte(file,Asc("a"))
  WriteByte(file,Asc("t"))
  WriteByte(file,Asc("a"))

  WriteLong(file,avBytesPerSec*secs)

  actsamplevalue.w

  FirstElement(numMS())
   ForEach numFQ()
    fq=numFQ()
    ms=numMS()
    NextElement(numMS())
     If CountList(numFQ())=a
      Break
     EndIf
    a+1 

    For acttime=1 To samplerate*ms/1000
     For actchannel=1 To channels
      actsamplevalue=32767*Sin(2*#PI*fq*acttime/samplerate)
      WriteWord(file,actsamplevalue)
     Next
    Next
   Next
EndProcedure

Procedure WaveToBuffer(Wave)
 *Mem=Wave
 samplerate.l=PeekL(*Mem)
 bitrate.w=PeekW(*Mem+4)
 channels.w=PeekW(*Mem+6)
 secs.d=PeekQ(*Mem+8)/1000
  If PeekQ(*Mem+8)>PeekL(*Mem+12)
   ms=PeekQ(*Mem+8)-PeekL(*Mem+12)
   Pause(Wave,ms)
  EndIf
  If secs<PeekL(*Mem+12)/1000
   secs=PeekL(*Mem+12)/1000
  EndIf

 avBytesPerSec=channels*bitrate/8*samplerate

 *Mem1=AllocateMemory(avBytesPerSec*secs+44)

  PokeB(*Mem1+0,Asc("R"))
  PokeB(*Mem1+1,Asc("I"))
  PokeB(*Mem1+2,Asc("F"))
  PokeB(*Mem1+3,Asc("F"))

  PokeL(*Mem1+4,avBytesPerSec*secs+44)

  PokeB(*Mem1+8,Asc("W"))
  PokeB(*Mem1+9,Asc("A"))
  PokeB(*Mem1+10,Asc("V"))
  PokeB(*Mem1+11,Asc("E"))

  PokeB(*Mem1+12,Asc("f"))
  PokeB(*Mem1+13,Asc("m"))
  PokeB(*Mem1+14,Asc("t"))
  PokeB(*Mem1+15,Asc(" "))

  PokeL(*Mem1+16,16)

  PokeW(*Mem1+20,1)
  PokeW(*Mem1+22,channels)
  PokeL(*Mem1+24,samplerate)
  PokeL(*Mem1+28,channels*bitrate/8*samplerate)
  PokeW(*Mem1+32,bitrate/8*channels)
  PokeW(*Mem1+34,bitrate)

  PokeB(*Mem1+36,Asc("d"))
  PokeB(*Mem1+37,Asc("a"))
  PokeB(*Mem1+38,Asc("t"))
  PokeB(*Mem1+39,Asc("a"))

  PokeL(*Mem1+40,avBytesPerSec*secs)

 actsamplevalue.w

 FirstElement(numMS())
  ForEach numFQ()
   fq=numFQ()
   ms=numMS()
   NextElement(numMS())
    If CountList(numFQ())=a
     Break
    EndIf
   a+1 

   For acttime=1 To samplerate*ms/1000
    For actchannel=1 To channels
     actsamplevalue=32767*Sin(2*#PI*fq*acttime/samplerate)
     PokeW(*Mem1+44+k,actsamplevalue)
     k+2
    Next
   Next
  Next
 ProcedureReturn *Mem1
EndProcedure

Procedure InitDirectPlay()
 Global Int_=1
 result=InitSound()
 ProcedureReturn result
EndProcedure

Procedure CatchWaveBuffer(FreeSound,*WaveBuffer)
 k=CatchSound(FreeSound,*WaveBuffer)
  If k<>0
   result=1
  Else
   result=-1
  EndIf
 ProcedureReturn result
EndProcedure

Procedure PlayWave(FreeSound,Mode)
 PlaySound(FreeSound,Mode)
EndProcedure

Procedure StopWave(FreeSound,Channel=0)
 StopSound(FreeSound,Channel)
EndProcedure

Procedure BalanceWave(FreeSound,Balance,Channel=0)
 SoundPan(FreeSound,Balance,Channel)
EndProcedure

Procedure VolumeWave(FreeSound,Volume,Channel=0)
 SoundVolume(FreeSound,Volume,Channel)
EndProcedure

Procedure LoadWave(FreeSound,FileName$)
 LoadSound(FreeSound,FileName$)
EndProcedure

Procedure FreeWave(FreeSound)
 FreeSound(FreeSound)
EndProcedure

Procedure FrequencyWave(FreeSound,Frequency,Channel=0)
 SoundFrequency(FreeSound,Frequency,Channel)
EndProcedure
Kann dann zB. so verwendet werden:

Code: Alles auswählen

InitDirectPlay()

Wave=CreateWave()

SetSamplerate(Wave,44100)
SetBitrate(Wave,16)
SetChannels(Wave,2)
SetMs(Wave,2000)

AddFQ(Wave,1000,1000)
AddFQ(Wave,2000,1000)
Dann kann man es in einen Buffer speichern und abspielen oder in einen Wave seichern.

Buffer & Play:

Code: Alles auswählen

*Buffer=WaveToBuffer(Wave)

CatchWaveBuffer(0,*Buffer)
PlayWave(0)

Delay(2000)
To File:

Code: Alles auswählen

SaveWave(Wave,...)
Bitte Verzeichnis statt den Punkten eingeben und .wav nicht vergessen!

Was anderes als mit Sinus hab ich noch nicht gesehen oder probiert(hab auch keine Ahnung wie das funktioniert)[/code]

@DarkDragon

Progge ich eigendlich immer das gleiche wie andere???

Verfasst: 20.04.2007 18:50
von Fluid Byte
QBPlay lib. Wird anscheinend noch auf PB4 portiert.
Froggerprogger ist für mich der Sound Gott! Bild

Es gibt "sogar" Effekte wie Arpeggio. Da lässt sich sicher noch einiges rausholen aus der Engine.

Danke für die Info! Bild

[EDIT]

@PBprogger
Ich glaub ich bin zu behämmert, es funzt irgendwie nicht.

Als Erstes habe Ich alle nötigen Prozeduren rüberkopiert und dann

Code: Alles auswählen

InitDirectPlay()

Wave=CreateWave()

SetSamplerate(Wave,44100)
SetBitrate(Wave,16)
SetChannels(Wave,2)
SetMs(Wave,2000)

AddFQ(Wave,1000,1000)
AddFQ(Wave,2000,1000)
eingefügt und danach

Code: Alles auswählen

*Buffer=WaveToBuffer(Wave)

CatchWaveBuffer(0,*Buffer)
PlayWave(0,0)

Delay(2000)
Bei PlayWave meckert PB und sagt das ein Parameter fehlt (Playmode). Hab Ich dann nachgetragen aber wenn man es dann kompliert bekomme Ich bei Zeile 132

Code: Alles auswählen

*Mem1=AllocateMemory(avBytesPerSec*secs+44)
einen Fehler das PB keinen Speicherblock von NULL anlegen kann.
[/EDIT]

Verfasst: 20.04.2007 19:12
von DarkDragon
@DarkDragon

Progge ich eigendlich immer das gleiche wie andere???
:lol: k.A. wollt dich nur drauf Hinweisen, nicht dass du denkst du wärst der komplett erste (Ist mit PB noch gut möglich der erste zu sein).