MP3 grafisch darstellen
MP3 grafisch darstellen
Ich hätte mal ein Problem. Wie kann ich ein MP3 grafisch darstellen wie es auch zB der MP3-Cutter macht ? Geht sowas (einfach) ?
SYNTAX ERROR IN 30! TYPE MISMATCH
- captain_hesse
- Beiträge: 138
- Registriert: 17.05.2009 18:55
- Computerausstattung: Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)
- Wohnort: Saarland
Re: MP3 grafisch darstellen
Hallo
Ich hatte damit auch schon mal herum experimentiert und habs dann später so gemacht daß ich die MP3
mittels acmStreamConvert_() in eine Wave Datei umgewandelt habe, diese Daten brauchst du dann nur noch auslesen und sie dann mit dem 2DDrawing Befehl LineXY() auf den Bildschirm zu zeichnen.
Gruß
Armin
Ich hatte damit auch schon mal herum experimentiert und habs dann später so gemacht daß ich die MP3
mittels acmStreamConvert_() in eine Wave Datei umgewandelt habe, diese Daten brauchst du dann nur noch auslesen und sie dann mit dem 2DDrawing Befehl LineXY() auf den Bildschirm zu zeichnen.
Gruß
Armin
Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)
Re: MP3 grafisch darstellen
Würde mich auch mal interessieren wie das geht. @captain_hesse: magst du ein lauffähiges Beispiel posten?
"Papa, ich laufe schneller - dann ist es nicht so weit."
- captain_hesse
- Beiträge: 138
- Registriert: 17.05.2009 18:55
- Computerausstattung: Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)
- Wohnort: Saarland
Re: MP3 grafisch darstellen
Ein lauffähiges Beispiel hatte ich gerade nicht griffbereit und habe daher auf die schnelle was programmiert also bitte erschlagt mich nicht wenn es nicht ganz perfekt ist, soll ja auch nur ein Wegweiser sein.
Das folgende Beispiel zeigt wie man eine *.wav Datei grafisch auf dem Bildschirm darstellt aber bitte beachten es geht nur mit Wave Dateien.Wie man eine MP3 in eine Wave Datei umwandelt muß ich erst nochmal nachschauen und dann auch ins Reine schreiben. Bitte lasst mir etwas Zeit, ich werde es in den nächsten Tagen hier posten.
Gruß Armin
Das folgende Beispiel zeigt wie man eine *.wav Datei grafisch auf dem Bildschirm darstellt aber bitte beachten es geht nur mit Wave Dateien.
Code: Alles auswählen
InitSprite()
window=OpenWindow(#PB_Any,0,0,1024,600,"stream", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
wav_datei$ = OpenFileRequester(".wav Datei laden", "", "wav (*.wav) |*.wav|Alle Dateien (*.*) |*.*", 0)
If ReadFile( 0,wav_datei$ )
;wave header einlesen
riff$=""
For i=1 To 4
riff$+Chr(ReadCharacter(0))
Next
gr=ReadLong(0)
wave$=""
For i=1 To 4
wave$+Chr(ReadCharacter(0))
Next
fmt$=""
For i=1 To 4
fmt$+Chr(ReadCharacter(0))
Next
fmt_length=ReadLong(0)
format_tag=ReadWord(0)
channels=ReadWord(0)
sample_rate=ReadLong(0)
bytes_per_second=ReadLong(0)
block_align=ReadWord(0)
bits_per_sample=ReadWord(0)
dat$=""
For i=1 To 4
dat$+Chr(ReadCharacter(0))
Next
data_length=ReadLong(0)
;Audio daten einlesen
*buffer=AllocateMemory(data_length)
ReadData(0, *buffer, data_length)
Debug riff$
Debug "dateigröße = "+Str(gr)
Debug wave$
Debug fmt$
Debug Str(fmt_length)
Debug "format_tag ="+Str(format_tag)
Debug "channels ="+Str(channels)
Debug "sample_rate ="+Str(sample_rate)
Debug "bytes_per_second ="+Str(bytes_per_second)
Debug "block_align ="+Str(block_align)
Debug "bits_per_sample ="+Str(bits_per_sample)
Debug dat$
Debug "data_length ="+Str(data_length)
CloseFile(0)
EndIf
faktor_x=data_length/1024
faktor_y.d=200/32767
If faktor_x % 2 <> 0 ;faktor_x muß durch 2 teilbar sein
faktor_x+1
EndIf
OpenWindowedScreen(WindowID(window),0,0,1024,500,0,0,0, #PB_Screen_WaitSynchronization)
Repeat
event=WindowEvent()
ClearScreen(0)
StartDrawing(ScreenOutput())
x=0
x1=0
While x<data_length
y=PeekW(*buffer+x)
y*faktor_y
LineXY( x1,250,x1,250+y,RGB($ff,$ff,$ff) )
x+faktor_x
x1+1
Wend
LineXY( 0,250,1024,250,RGB($ff,$00,$00) )
StopDrawing()
FlipBuffers()
Until event=#PB_Event_CloseWindow
CloseScreen()
CloseWindow(window)
Gruß Armin
Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)
- captain_hesse
- Beiträge: 138
- Registriert: 17.05.2009 18:55
- Computerausstattung: Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)
- Wohnort: Saarland
Re: MP3 grafisch darstellen
So ich habe in meinem Archiv da noch einen Code gefunden mit dem ich früher mal experimentiert habe. Allerdings habe ich das nicht selbst geschrieben sondern irgendwo im Forum gefunden und es dann an meine Bedürfnisse angepasst aber es funktioniert. Das einzige was man nach dem Konvertieren noch tun muss ist der Wave Datei einen Header zu verpassen das macht diese Programm nämlich nicht. Also viel Spaß damit

Code: Alles auswählen
#MPEGLAYER3_ID_MPEG = 1
#WAVE_FORMAT_MPEGLAYER3 = $0055
#MPEGLAYER3_WFX_EXTRA_BYTES = 12
#ACM_FORMATSUGGESTF_WFORMATTAG = $00010000
#ACM_STREAMSIZEF_SOURCE = $00000000
#ACM_STREAMCONVERTF_BLOCKALIGN = $00000004
#ACM_STREAMCONVERTF_END = $00000020
#ACM_STREAMOPENF_NONREALTIME = $00000004
Structure MPEGLAYER3WAVEFORMAT
wfx.WAVEFORMATEX
wID.w
fdwFlags.l
nBlockSize.w
nFramesPerBlock.w
nCodecDelay.w
EndStructure
Structure ACMSTREAMHEADER
cbStruct.l
fdwStatus.l
dwUser.l
pbSrc.l
cbSrcLength.l
cbSrcLengthUsed.l
dwSrcUser.l
pbDst.l
cbDstLength.l
cbDstLengthUsed.l
dwDstUser.l
dwReservedDriver.l[10]
EndStructure
Structure ACMVERSION
build.w
rev.b
ver.b
EndStructure
OpenConsole()
Enumeration
#infile
#outfile
EndEnumeration
nb_read.l = 0
leftover.l = 0
wfxSrc.WAVEFORMATEX
MP3wfxDst.MPEGLAYER3WAVEFORMAT
dwACMVer.l = 0
has.l = #Null
ash.ACMSTREAMHEADER
total_bytes.l = 0
cbSrcBuf.l = 50000000
cbDstBuf.l
;Get And display the ACM version.
dwACMVer = acmGetVersion_();
*acmver.ACMVERSION = @dwACMVer
Print("ACM v" + StrU(*acmver\ver, #PB_Byte) + "." + StrU(*acmver\rev, #PB_Byte))
If *acmver\build = 0
PrintN(" Retail")
Else
PrintN(" build " + StrU(*acmver\build, #PB_Word))
EndIf
wfxSrc\wFormatTag = #WAVE_FORMAT_PCM
wfxSrc\nSamplesPerSec = 44100
wfxSrc\nBlockAlign = 4
wfxSrc\nAvgBytesPerSec = wfxSrc\nSamplesPerSec*wfxSrc\nBlockAlign
wfxSrc\nChannels = 2
wfxSrc\wBitsPerSample = 16
wfxSrc\cbSize = 0
MP3wfxDst\wID = #MPEGLAYER3_ID_MPEG
MP3wfxDst\wfx\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
MP3wfxDst\wfx\nChannels = 2
MP3wfxDst\wfx\nSamplesPerSec = 44100
MP3wfxDst\wfx\wBitsPerSample = 0
MP3wfxDst\wfx\nAvgBytesPerSec = 128 / 8*1024
MP3wfxDst\wfx\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
MP3wfxDst\wfx\nBlockAlign = 1
MP3wfxDst\fdwFlags = 2
MP3wfxDst\nBlockSize = 522
MP3wfxDst\nFramesPerBlock = 1
MP3wfxDst\nCodecDelay = 1393
;now let the driver try and find the best match for us
res = acmFormatSuggest_(#Null ,@MP3wfxDst ,@wfxSrc, SizeOf(WAVEFORMATEX), #ACM_FORMATSUGGESTF_WFORMATTAG)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
;now try to open the input and output streams
res = acmStreamOpen_(@has, #Null, @MP3wfxDst,@wfxSrc, #Null, 0, 0, #ACM_STREAMOPENF_NONREALTIME)
If res<>#S_OK
PrintN("error> " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
;now let the driver decide how big the destination buffer should be based
;on the parameters of both input and output wfx
res = acmStreamSize_(has, cbSrcBuf, @cbDstBuf, #ACM_STREAMSIZEF_SOURCE)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
*pSrcBuf = AllocateMemory(cbSrcBuf)
*pDstBuf = AllocateMemory(cbDstBuf)
;this would likely be a better place to allocate both the input and output buffers
;instead of the fixed size [0xffff] used at the top
;now set up the header to get ready to convert
ash\cbStruct = SizeOf(ACMSTREAMHEADER)
ash\pbSrc = *pSrcBuf
ash\cbSrcLength = cbSrcBuf
ash\pbDst = *pDstBuf
ash\cbDstLength = cbDstBuf
res = acmStreamPrepareHeader_(has, @ash, 0)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Debug "ende"
Goto quit
EndIf
;open up the input file
res = ReadFile(#infile, "source.mp3")
If res = 0
PrintN("cannot open input file")
;do something here about the failure
Goto quit
EndIf
;open up the output file
res = CreateFile(#outfile, "dest.wav")
If res = 0
PrintN("Cannot open outfile")
;do something here about the failure
Goto quit
EndIf
;here's a hack to skip over the usual 44 bytes in the wav header
FileSeek(#infile, 44)
ash\cbDstLengthUsed = 0
ash\cbSrcLengthUsed = 0
leftover = 0
total_bytes = 0
;keep looping until we break or the eof is found on the input file
While Eof(#infile) = 0
nb_read = 0
If leftover<cbSrcBuf
;read some bytes from the file
nb_read = ReadData(#infile, *pSrcBuf + leftover, cbSrcBuf-leftover)
If nb_read = 0
PrintN("cannot read bytes from input")
;do something here about the failure
Goto quit
EndIf
total_bytes + nb_read
EndIf
;adjust the size of the input buffer based on leftover amount and newly read data
ash\cbSrcLength = leftover + nb_read
;loop this section for a stream convert
;The acmStreamConvert function converts data in a source buffer into
;the destination format, writing the converted data into the destination buffer.
If nb_read> = 0
res = acmStreamConvert_(has, @ash, #ACM_STREAMCONVERTF_BLOCKALIGN)
Else
res = acmStreamConvert_(has, @ash, #ACM_STREAMCONVERTF_BLOCKALIGN | #ACM_STREAMCONVERTF_END)
EndIf
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
PrintN("compressed total: " + StrU(total_bytes, #PB_Long) + " mp3: " + StrU(ash\cbDstLengthUsed, #PB_Long) + " pcm: " + StrU(ash\cbSrcLengthUsed, #PB_Long))
leftover = ash\cbSrcLength-ash\cbSrcLengthUsed
;move to the start of the input buffer any of the unused pcm data
CopyMemory(*pSrcBuf + ash\cbSrcLengthUsed, *pSrcBuf, leftover)
WriteData(#outfile, *pDstBuf, ash\cbDstLengthUsed)
Wend
;now flush out any data from the queue
PrintN("")
PrintN("flushing decoder")
ash\cbDstLengthUsed = 1
ash\cbSrcLength = 0
;keep looping through the streamconverts until the input and output buffers are flushed
While ash\cbDstLengthUsed>0
;The acmStreamConvert function converts data in a source buffer into
;the destination format, writing the converted data into the destination buffer.
res = acmStreamConvert_(has, @ash, #ACM_STREAMCONVERTF_BLOCKALIGN | #ACM_STREAMCONVERTF_END)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
If ash\cbDstLengthUsed>0
PrintN("compressed " + StrU(ash\cbDstLengthUsed, #PB_Long) + " bytes from " + StrU(ash\cbSrcLengthUsed, #PB_Long))
WriteData(#outfile, *pDstBuf, ash\cbDstLengthUsed)
EndIf
Wend
;first make sure the input and output buffer sizes are
;the same as when the buffer was prepared
ash\cbSrcLength = cbSrcBuf
ash\cbDstLength = cbDstBuf
;unprepare the header before closing the stream
res = acmStreamUnprepareHeader_(has, @ash, 0)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
;The acmStreamClose function closes a conversion stream.
res = acmStreamClose_(has, 0)
If res<>#S_OK
PrintN("error " + StrU(res, #PB_Long))
;do something here about the failure
Goto quit
EndIf
quit:
Input()
CloseConsole()
Windows 7 Ultimate 64 Bit / AMD Phenom II 1090T, 6x3200 MHz / AMD HD-6850 / PureBasic 5.1 (x86) (x64)