Bass and Avi movie
Blitz3D Forums/Blitz3D Userlibs/Bass and Avi movie
| ||
| Hi, I want to build (draw) a spectrum analyser over an avi movie. Any solution to have a sort of "What you Hear is What you Get" with Abrexxes's Bass23? ex : Init Bass in "What you Hear is What you Get" mode OpenMovie (Blitz3d command) Repeat DrawMovie (Blitz3d command) GET Avi stream audio infos Draw the spectrum or anything Until end of Movie Close process Thanks JP |
| ||
| "GET Avi stream audio infos" Thats the problem. The only way to get the output data is to record the BASS_INPUT_TYPE_WAVE device. But thats really dirty and not in realtime because the Channel_Get_Data will work over the recording buffer. So you can not "grab" only your informations on the fly. |
| ||
| Thx JP |
| ||
| I have locked around. What you can do is open the avi file and read out the audio stream into a bank, or a bigger one into a new temp file. After you play your video with Blitz and use the new stream in the same time for audio and Channel_Get_Data. But AVI ist just a container, if there is an obscur divx audio format bass will be not able to play them (Blitz also not). It is possible but you must "open" the avi containers . http://msdn2.microsoft.com/en-us/library/ms779638.aspx If you have simple PCM in your file here is some code from me to write a wav file with blitz. For a simple one dont use the SMPL Part. this was only to loop samples perfect in b3d for Sfx effects without any lib. ;)
; You dont need this global, but you can use it to see the data size of your wav file for max value
Global s_datalenght%
Graphics 640,480,0,2
SetBuffer BackBuffer ()
;LoadLoopSound("test.wav",0,0) ; no loop
LoadLoopSound("test.wav",1,s_datalenght) ; maximum loop
;LoadLoopSound("test.wav",800,8000) ; what you want but not more then datalenght
musik = LoadSound ("s_temp.wav")
DeleteFile "s_temp.wav"
While Not KeyHit (1)
Cls
If KeyHit (57) Then
PlaySound (musik)
EndIf
Text 10,10,"Press space to play"
Text 10,20, "Datasize = "+s_datalenght
Flip
Wend
End
Function LoadLoopSound(s_file$,s_start%,s_end%)
;**********************************
;**** Read Source Wav File *****
;**********************************
s_source = ReadFile (s_file)
; read RIFF header (1179011410) to see if it is a wav file
s_check = ReadInt (s_source)
If s_check = 1179011410 Then ; RIFF found
s_check = ReadInt (s_source)
s_sourcesize = (s_check + 8) ; size of sourcefile
s_check = ReadInt (s_source) ; read "wave"
EndIf
If Not s_check = 1163280727 Then Return 0 ; no wave..go away with that :)
; search and read FMT chunk for sample infos
s_position = 12
s_goal = 0
Repeat
SeekFile s_source, s_position
s_check = ReadInt (s_source)
If s_check = 544501094 Then ; FMT found
s_goal = 1 ; now lets read and store all the infos
s_fmtsize = ReadInt (s_source) ;<fmt length> size of this chunk, normal = 16 byte from here
s_format = ReadShort (s_source) ;<format tag> sample format, normal = 1 (hex) for PCM
s_channels = Readshort (s_source) ;<channels> 1 = mono, 2 = stereo
s_rate = ReadInt (s_source) ;<sample rate> (hz)
s_bytes = ReadInt (s_source) ;<bytes/second> Sample-Rate * Block-Align
s_block = Readshort (s_source) ;<block align> Channels * bits/sample / 8
s_bit = Readshort (s_source) ;<bits/sample> 8, 16 or 24
EndIf
s_position = s_position +1 ;FMT not found, next step
If s_goal = 1 Then Exit ; ok
Until Eof (s_source) = 1
If s_goal = 0 Then Return 0 ; no FMT found, Error
; search and read DATA chunk
s_position =12
s_goal = 0
Repeat
SeekFile s_source, s_position
s_check = ReadInt (s_source)
If s_check = 1635017060 Then ; DATA found
s_goal = 1
s_datalenght = ReadInt (s_source) ;<length> of data block
sbank_cache = CreateBank (s_datalenght) ; now we store the sample data
For i = 0 To (s_datalenght-1)
s_value = ReadByte (s_source)
PokeByte sbank_cache,i,s_value
Next
EndIf
s_position = s_position +1 ; DATA not found, next step
If s_goal = 1 Then Exit ; ok
Until Eof (s_source) = 1
If s_goal = 0 Then Return 0 ; no DATA found, Error
CloseFile s_source ; we have what we need, all other chunks we can ignore
;**********************************
;**** Write temp Wav File *****
;**********************************
s_temp = WriteFile ("s_temp.wav") ; create a temp
;write RIFF header
WriteInt s_temp, 1179011410 ; RIFF
WriteInt s_temp, s_sourcesize-8 ;size of header
WriteInt s_temp, 1163280727 ; WAVE
;write FMT chunk
WriteInt s_temp, 544501094 ; FMT
WriteInt s_temp, s_fmtsize ;<fmt length>
WriteShort s_temp, s_format ;<format tag>
WriteShort s_temp, s_channels ;<channels>
WriteInt s_temp, s_rate ;<sample rate>
WriteInt s_temp, s_bytes ;<bytes/second>
WriteShort s_temp, s_block ;<block align>
WriteShort s_temp, s_bit ;<bits/sample>
;write SMPL chunk
WriteInt s_temp, 1819307379 ;SMPL
WriteInt s_temp, 60 ;36 + 1 sample loop section (24)
WriteInt s_temp, 0 ; Manufacturer , we dont need
WriteInt s_temp, 0 ; ProductID , we dont need
WriteInt s_temp, 0 ;Sample Period ,not supported by blitzbasic
WriteInt s_temp, 0 ;MIDI Unity Note ,not supported by blitzbasic
WriteInt s_temp, 0 ;MIDI Pitch Fraction ,not supported by blitzbasic
WriteInt s_temp, 0 ;SMPTE Format ,not supported by blitzbasic
WriteInt s_temp, 0 ;SMPTE Offset ,not supported by blitzbasic
WriteInt s_temp, 0 ;Num Sample Loops ,not supported by blitzbasic
WriteInt s_temp, 0 ;Sampler Data ,not supported by blitzbasic
WriteInt s_temp, 0 ;Cue Point ,not supported by blitzbasic
WriteInt s_temp, 0 ;Type ,not supported by blitzbasic
WriteInt s_temp, s_start ; Start loop
WriteInt s_temp, s_end ;End loop
WriteInt s_temp, 0 ;Fraction ,not supported by blitzbasic
WriteInt s_temp, 0 ;Play Count ,not supported by blitzbasic
;write DATA chunk & data
WriteInt s_temp, 1635017060 ; DATA
WriteInt s_temp, s_datalenght ;<length>
WriteBytes (sbank_cache,s_temp,0,s_datalenght) ;sample data from bank
FreeBank sbank_cache ; we no need this longer
CloseFile s_temp
End Function |
| ||
| Thanks Again. Works on it. Another solution (maybe) with "winmm.dll". A sort of "get sound level" API. JP |
| ||
| Hmmmm.... i dont now what you want to do. If you can use wmv files, the wma plugin of bass is able to play the audiostream of wmv files.... |
| ||
| "Hmmmm.... i dont now what you want to do" A sort of "BASS_ChannelGetLevel_AVI" in real time. JP |
| ||
| Found a solution. BLZPeekInt is in the ISL lib http://www.blitzbasic.com/Community/posts.php?topic=34301 ------------------------------------------------------
Graphics 800,600,32,2
SetBuffer FrontBuffer()
Const WAVE_INVALIDFORMAT = $000 ;invalid forma
Const WAVE_FORMAT_1M08 = $001 ;11.025 kHz,Mono, 8-bit
Const WAVE_FORMAT_1S08 = $002 ;11.025 kHz,Stereo, 8-bit
Const WAVE_FORMAT_1M16 = $004 ;11.025 kHz,Mono, 16-bit
Const WAVE_FORMAT_1S16 = $008 ;11.025 kHz,Stereo,16-bit
Const WAVE_FORMAT_2M08 = $010 ;22.05 kHz,Mono, 8-bit
Const WAVE_FORMAT_2S08 = $020 ;22.05 kHz,Stereo, 8-bit
Const WAVE_FORMAT_2M16 = $040 ;22.05 kHz,Mono, 16-bit
Const WAVE_FORMAT_2S16 = $080 ;22.05 kHz,Stereo,16-bit
Const WAVE_FORMAT_4M08 = $100 ;44.1 kHz,Mono, 8-bit
Const WAVE_FORMAT_4S08 = $200 ;44.1 kHz,Stereo, 8-bit
Const WAVE_FORMAT_4M16 = $400 ;44.1 kHz,Mono, 16-bit
Const WAVE_FORMAT_4S16 = $800 ;44.1 kHz,Stereo,16-bit
Const WAVE_FORMAT_PCM = $001
Const WHDR_DONE = $001
Const WHDR_PREPARED = $002
Const WHDR_BEGINLOOP = $004
Const WHDR_ENDLOOP = $008
Const WHDR_INQUEUE = $010
WaveFmt = CreateBank(18)
PokeShort WaveFmt,00,WAVE_FORMAT_PCM ; FormatTag
PokeShort WaveFmt,02,1 ; Channels
PokeInt WaveFmt,04,11025 ; SamplesPerSec
PokeInt WaveFmt,08,11025 ; AvgBytesPerSec | BlockAlign * SamplesPerSec
PokeShort WaveFmt,12,1 ; BlockAlign | (Channels * BitsPerSample) / 8
PokeShort WaveFmt,14,8 ; BitsPerSample
PokeShort WaveFmt,16,0 ; ExtraDataSize
WaveCaps = CreateBank(48)
Dim Device(waveInGetNumDevs())
For I = 0 To waveInGetNumDevs() - 1
waveInGetDevCaps(I,WaveCaps,48)
If PeekInt(WaveCaps,40) And WAVE_FORMAT_1M08 Then
For C = 8 To 39
Char = PeekByte(WaveCaps,C)
If Char = 0 Then Exit
ProductName$ = ProductName$ + Chr$(Char)
Next
Print "(" + Str$(Dev) + ") " + ProductName$
ProductName$ = ""
Dev = Dev + 1
Device(Dev) = I
EndIf
Next
If Dev = 0 Then
Print "Can't find a sounddevice!"
WaitKey : End
EndIf
Repeat
DevUsed = Input("Select a device(0-" + Str$(Dev - 1) + "): ")
Until DevUsed => 0 And DevUsed <= Dev - 1
DevUsed = Device(DevUsed)
DevHandle = CreateBank(4)
waveInOpen(DevHandle,DevUsed,WaveFmt,0,0,0)
If PeekInt(DevHandle,0) = 0 Then
Print "Can't open wavedevice!"
WaitKey : End
EndIf
waveInStart(PeekInt(DevHandle,0))
WavData = CreateBank(1024)
WaveHead = CreateBank(32)
PokeInt WaveHead,00,BLZPeekInt(WavData+4) ; lpData
PokeInt WaveHead,04,1024 ; dwBufferLength
waveInPrepareHeader(PeekInt(DevHandle,0),WaveHead,32)
;SetBuffer BackBuffer()
film=OpenMovie("c:\movie.avi")
While Not KeyDown(1)
Cls
DrawMovie film,50,50
waveInAddBuffer(PeekInt(DevHandle,0),WaveHead,32)
For I = 0 To 1023
Line I,PeekByte(WavData,I),I,0
Next
Flip
Wend
CloseMovie film
waveInUnprepareHeader(PeekInt(DevHandle,0),WaveHead,32)
waveInReset(PeekInt(DevHandle,0))
waveInClose(PeekInt(DevHandle,0))
;.lib "winmm.dll"
;waveInGetDevCaps%(uDeviceID,WaveInCapsPointer*,WaveInCapsStructSize) : "waveInGetDevCapsA"
;waveInOpen%(WaveDeviceInputHandle*,WhichDevice,WaveFormatExPointer*,CallBack,CallBackInstance,Flags) : "waveInOpen"
;waveInGetNumDevs%() : "waveInGetNumDevs"
;waveInClose%(WaveDeviceInputHandle) : "waveInClose"
;waveInStart%(WaveDeviceInputHandle) : "waveInStart"
;waveInReset%(WaveDeviceInputHandle) : "waveInReset"
;waveInStop%(WaveDeviceInputHandle) : "waveInStop"
;waveInAddBuffer%(InputDeviceHandle,WaveHdrPointer*,WaveHdrStructSize) : "waveInAddBuffer"
;waveInPrepareHeader%(InputDeviceHandle,WaveHdrPointer*,WaveHdrStructSize) : "waveInPrepareHeader"
;waveInUnprepareHeader%(InputDeviceHandle,WaveHdrPointer*,WaveHdrStructSize) : "waveInUnprepareHeader"
;
|