Aktuelle Zeit: 02.12.2020 14:45

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 11:33 
Offline
Benutzeravatar

Registriert: 21.07.2005 00:02
Wohnort: am schönen Niederrhein
Hallo zusammen,

ich habe bislang mit Sound noch nicht viel gemacht und würde gerne eine Wellenform selber generiere und diese dann irgendwie abspielen.

Soweit ich die PB Sound-Befehle verstanden habe, geht sowas ja damit nicht, da man nur vorgefertigte Soundfiles catchen kann.

Hat evtl. schon mal jemand sowas gemacht oder hätte einen Tipp dazu, wie man selbst generierte Wellenformen abspielen könnte oder eben einen Ton durch Angabe von Frequenz und Länge ausgeben kann (ggfl. auch über API)?

Thx und Grüße,
PL.

PS: Mir würde im Grunde auch sowas reichen wie :
Spiele Frequenz X1 für Y1 Millisekunden, danach Frequenz X2 für Y2 Millisekunden, ...
Früher habe ich für sowas Beep_() benutzt, aber bei neueren Betriebssystemen liegt zwischen den Beeps ist immer eine Pause, so dass man keinen zusammenhängenden Sound mehr hin bekommt.
Code:
For n = 900 To 700 Step -20 : Beep_(n,50) : Next

_________________
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 14:08 
Offline
Benutzeravatar

Registriert: 23.07.2011 02:08
Vielleicht hilft dir das?
https://www.purebasic.fr/english/viewto ... ave+memory

_________________
Signatur und so


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 15:58 
Offline
Benutzeravatar

Registriert: 21.07.2005 00:02
Wohnort: am schönen Niederrhein
Derren hat geschrieben:
Vielleicht hilft dir das?
Wau .... das wäre es gewesen. :allright: ... naja ... fast !!! :cry:
Ich hab den alten Code mal auf 5.71 angepasst, aber irgendwie klappt das nicht die erzeugten Daten anschließend mit CatchSound() zu grabben.

Evtl. liegt's daran, dass im Wave-Header einige ASCII Strings drin sind und PB ja komplett auf Unicode umgestellt wurde?
Aber dazu hab' ich aber ja PokeS() angepasst ... sollte meiner Ansicht ja nun so klappen. /:->
Der Wave-Header benötigt doch vermutlich nach wie vor noch die Header-Texte im ASCII Format, oder nicht?

Evtl. 'ne Idee woran's scheitert?
Code:
EnableExplicit

Structure WAVE
   wFormatTag.w
   nChannels.w
   nSamplesPerSec.l
   nAvgBytesPerSec.l
   nBlockAlign.w
   wBitsPerSample.w
   cbSize.w
EndStructure

Procedure MakeSound(nr,Frequency, Duration)
   Protected SoundValue.b, Result
   Protected w.f; // omega ( 2 * pi * frequency)
   #Mono         =   $0001;
   #SampleRate   =   11025; // 8000, 11025, 22050, or 44100
   #RiffId      =   "RIFF"   ;
   #WaveId      =   "WAVE"   ;
   #FmtId      =   "fmt "   ;
   #DataId      =   "data"   ;
   
   Protected WaveFormatEx.WAVE
   WaveFormatEx\wFormatTag         =   #WAVE_FORMAT_PCM;
   WaveFormatEx\nChannels         =   #Mono             ;
   WaveFormatEx\nSamplesPerSec    =   #SampleRate;
   WaveFormatEx\wBitsPerSample   =   $0008        ;
   WaveFormatEx\nBlockAlign      =   (WaveFormatEx\nChannels * WaveFormatEx\wBitsPerSample) /8
   WaveFormatEx\nAvgBytesPerSec   =   WaveFormatEx\nSamplesPerSec * WaveFormatEx\nBlockAlign;
   WaveFormatEx\cbSize            =   0
   
   Protected DataCount = (Duration * #SampleRate)/1000; // sound data
   Protected RiffCount.l = 4+4 +4+ SizeOf(WAVE)+4 +4+ DataCount
   
   Protected *start=AllocateMemory(RiffCount+100)
   Protected MS.i=*start
   
   PokeS(MS,#RiffId,4,#PB_Ascii | #PB_String_NoZero)   :   MS+4  ; 'RIFF'
   PokeL(MS,RiffCount)                                 :   MS+4   ; file Data size
   PokeS(MS,#WaveId,4,#PB_Ascii | #PB_String_NoZero)   :   MS+4   ; 'WAVE'
   PokeS(MS,#FmtId ,4,#PB_Ascii | #PB_String_NoZero)   :   MS+4   ; 'fmt '
   PokeL(MS,SizeOf(WAVE))                              :   MS+4   ; TWaveFormat data size
   
   PokeW(MS,WaveFormatEx\wFormatTag)                  :   MS+2   ; WaveFormatEx record
   PokeW(MS,WaveFormatEx\nChannels)                     :   MS+2
   PokeL(MS,WaveFormatEx\nSamplesPerSec)               :   MS+4
   PokeL(MS,WaveFormatEx\nAvgBytesPerSec)               :   MS+4
   PokeW(MS,WaveFormatEx\nBlockAlign)                  :   MS+2
   PokeW(MS,WaveFormatEx\wBitsPerSample)               :   MS+2
   PokeW(MS,WaveFormatEx\cbSize)                        :   MS+2
   
   PokeS(MS,#DataId,4,#PB_Ascii | #PB_String_NoZero)   :   MS+4  ;'data'
   PokeL(MS,DataCount)                                 :   MS+4   ;sound data size
   
   ;{Calculate And write out the tone signal} // now the Data values
   
   Protected i
   w = 2 * #PI * Frequency                              ; omega
   For i = 0 To DataCount - 1
      ;// wt = w *i /SampleRate
      ;SoundValue := 127 + trunc(127 * Sin(i * w / SampleRate));
      SoundValue = 127 + 127 * Sin(i * w / #SampleRate);
      PokeB(MS,SoundValue):MS+1                         ;
   Next
   ;// you could save the wave tone To file with :
   ;// MS.Seek(0, soFromBeginning);
   ;// MS.SaveToFile('C:\MyFile.wav');
   ;// then reload And play them without having To
   ;// construct them each time.
   ;{now play the sound}
   ;sndPlaySound(MS.Memory, SND_MEMORY Or SND_SYNC);
   ;MS.Free;
   
   Result = CatchSound(nr,MS)
   FreeMemory(*start)
   ProcedureReturn Result
   
EndProcedure

Procedure QuitSound(nr)
   StopSound(nr)
   FreeSound(nr)
   ;FreeMemory(nr)
EndProcedure

InitSound()
If MakeSound(0,1100,2000)
   PlaySound(0)
   Delay(2000)
   QuitSound(0)
Else
   Debug "ERROR !!! MakeSound() / CachSound() failed" + #CRLF$
EndIf
Debug "done"

PS: Hab im CodeArchiv auch noch einen ähnlichen Code von Froggerprogger gefunden (Create&PlayWAVESoundsInMemory.pb für PB4.0)
Musste natürlich auch angepasst werden ... läuft aber leider genauso wenig. :cry:

_________________
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 16:03 
Offline
Benutzeravatar

Registriert: 20.04.2006 09:50
Vielleicht ist das hier auch hilfreich:
https://www.purebasic.fr/english/viewtopic.php?f=27&t=62941

_________________
my pb stuff..
Bild..jedenfalls war das mal so.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 16:11 
Offline
Benutzeravatar

Registriert: 21.07.2005 00:02
Wohnort: am schönen Niederrhein
#NULL hat geschrieben:
Danke für den Link ... sieht schick aus. :mrgreen:

Hab mir aber gerade nochmal den Code von FroggerProgger (aus dem CodeArchiv) angeschaut und hab den Fehler gefunden.
Klappt also nun wie erhofft.

Vielen Dank nochmals für Eure Hilfe !!! :allright:

Aber noch 'ne Frage zu 'nem Trick den FroggerProgger da ursprünglich angewandt hatte:
Code:
*mem\l = 'atad'       ; anstatt:  PokeS(*mem,"data", 4,#PB_Ascii | #PB_String_NoZero)
(Wusste garnicht, dass sowas geht. :D )

Dieser Code erzeugt seit der Umstellung auf Unicode ja nun eine 8 Byte Ergebnis (statt früher 4 Byte)
Kann man PB noch irgendwie dazu bringen sowas in ASCII aufzulösen?

Code:
; English forum: http://www.purebasic.fr/english/viewtopic.php?t==14344&highlight=
; Author: Froggerprogger (updated for PB 4.00 by Andre)
; Date: 11. March 2005
; OS: Windows
; Demo: Yes


;- 11.03.05 by Froggerprogger
;- For further information on the WAV-format look at: http://www.sonicspot.com/guide/wavefiles.html

#samplerate = 44100                 ; samplerate
#bitrate = 16                       ; Bits per sample, #bitrate Mod 8 must be 0 !
#channels = 2                       ; number of channels
#totalsamples = 5*#samplerate       ; length in samples (here 5 seconds)

#avBytesPerSec  = #channels*#bitrate/8*#samplerate  ; calculate the average bytes per second
#datachunkBytes = #totalsamples * #channels * #bitrate/8

Structure PBUnion
  StructureUnion
    b.b
    w.w
    l.l
    f.f
  EndStructureUnion
EndStructure

*sound = AllocateMemory(44 + #datachunkBytes)

*mem.PBUnion = *sound

;*mem\l = 'FFIR'                                                 : *mem+4      ; riff-chunk-ID "RIFF"
PokeS(*mem,"RIFF", 4,#PB_Ascii | #PB_String_NoZero)      : *mem+4      ; riff-chunk-ID "RIFF"
*mem\l = 36 + #datachunkBytes                             : *mem+4      ; normally filesize minus (these) 8 Bytes
PokeS(*mem,"WAVE", 4,#PB_Ascii | #PB_String_NoZero)      : *mem+4      ; wave-chunk-ID "WAVE"
PokeS(*mem,"fmt ", 4,#PB_Ascii | #PB_String_NoZero)      : *mem+4      ; format-chunk-ID "FMT "
*mem\l = 16                                              : *mem+4      ; chunk data size (+ Extra Format Bytes)
*mem\w = 1                                                 : *mem+2      ; compression code
*mem\w = #channels                                       : *mem+2      ; number of channels
*mem\l = #samplerate                                       : *mem+4      ; samplerate
*mem\l = #avBytesPerSec                                    : *mem+4      ; average bytes per second, (channels)*(block align)*(samplerate)
*mem\w = #bitrate/8*#channels                              : *mem+2      ; Block Align ('bytes per sample')
*mem\w = #bitrate                                          : *mem+2      ; Bits per sample
;*mem\l = 'atad'                                          : *mem+4      ; data-chunk-ID "DATA"
PokeS(*mem,"data", 4,#PB_Ascii | #PB_String_NoZero)      : *mem+4      ; data-chunk-ID "DATA"
*mem\l = #datachunkBytes                                 : *mem+4      ; data chunk size in byes

Debug *mem - *sound
;/ Now lets write #totalsamples of a 440Hz-sinus
;/ work only for 16 Bit or more. 8-Bit has zero-line at value 128, so it is unsigned

#fq = 440
Global maxAmp.l : maxAmp = Pow(2, #bitrate-1)-1

For acttime = 1 To #totalsamples
  For actchannel = 1 To #channels
    *mem\w = maxAmp * Sin(2 * #PI * #fq * acttime / #samplerate)
    *mem+2
  Next
Next


;/ catch and play the sound
InitSound()
CatchSound(0, *sound)
PlaySound(0)
Delay(5000)

_________________
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selbst generierten Sound aus RAM abspielen?
BeitragVerfasst: 30.01.2020 16:46 
Offline
Benutzeravatar

Registriert: 24.02.2007 22:15
Der vollständigkeit halber noch ne lib für Audio ein- und ausgabe:

Damit ist es außerdem einfach möglich audiodaten "live" per callback auszugeben oder abzufragen. Grobes Beispiel für eine simple Ausgabe, wobei vollständige Beispiele auf Github vorliegen:

Code:
*AudioOut = AudioOut::Initialize(#WAVE_MAPPER, 44100, 1, 8) ; Daten als 44100 Samples/s, 1 Kanal, 8 Bit

AudioOut::Write_Data(*AudioOut, ?Blub, ?Blub_End - ?Blub)
Delay(1000)

AudioOut::Deinitialize(*AudioOut)

DataSection
  Blub:
  Data.a $7D,$7D,$7E,$7D,$7D,$7C,$7E,$7E,$80,$82,$82,$83,$81,$82,$80,$80,$80,$82,$82,$83,$82,$84,$83,$81,$82,$81,$81,$80,$81,$81,$7E ; Weitere Wellenformdaten fehlen. Nur ein Beispiel
  Blub_End:
EndDataSection

_________________
Webseite


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye