Gambas-it

Gambas3 => Programmazione => Topic aperto da: allegfede - 04 Marzo 2014, 17:07:08

Titolo: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 04 Marzo 2014, 17:07:08
Sto' ragionando su quale metodo sia il migliore per estrarre da un file audio la sua forma d'onda (al fine di visualizzarla e sovrapporci un cursore sopra durante la riproduzione).

Gstreamer potrebbe essere il partner ideale, e cercando un po' ho trovato un pezzo di codice C che potrebbe aiutare nell'operazione ...
https://github.com/erikd/sndfile-tools/blob/master/src/waveform.c

Codice: [Seleziona]
/*
** Copyright (C) 2007-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2012 Robin Gareus <robin@gareus.org>
** Copyright (C) 2013 driedfruit <driedfruit@mindloop.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 or version 3 of the
** License.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/*
** Generate a waveform as a PNG file from a given sound file.
*/

..... etc etc

fare anche una "visualizzazione" di tipo waveform come estenzione per gstreamer potrebbe essere un'opzione ......

qui' il termine waveform compare in piu' istanze ......
http://gstreamer.freedesktop.org/documentation/plugins.html
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 04 Marzo 2014, 17:48:46
Sto' ragionando su quale metodo sia il migliore per estrarre da un file audio la sua forma d'onda (al fine di visualizzarla e sovrapporci un cursore sopra durante la riproduzione).
Secondo me, se si tratta di un file di dati audio non compressi, allora puoi operare con i suoi stessi dati audio grezzi. Io ho fatto una cosa del genere:
http://www.gambas-it.org/wiki/index.php?title=Visualizzare_la_forma_d%27onda_di_un_file_WAV


cercando un po' ho trovato un pezzo di codice C che potrebbe aiutare nell'operazione ...
E' un codice interessante, ma molto vasto. Credo sia necessario chiamare e gestire le funzioni di due/tre librerie esterne. (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/SmileySuicide.gif)
...ma puoi sempre provarci ed iniziare.   ;D
Se vuoi, posso aiutarti. (...non c'è una faccina per rappresentare il masochista ?  ;D )
In alternativa, puoi modificarlo un po' e trasformarlo in una libreria esterna condivisa .so da chiamare con Gambas.... oppure se non vuoi proprio fare alcuno sforzo, potresti compilarlo e richiamarlo con il solito Deus ex machina chiamato "Shell".  ;D


fare anche una "visualizzazione" di tipo waveform come estenzione per gstreamer potrebbe essere un'opzione ......
...ma non credo che potresti lavorarci facendovi apparire un cursore sopra, come è tua intenzione.


qui' il termine waveform compare in piu' istanze ......
http://gstreamer.freedesktop.org/documentation/plugins.html
Un paio di quei plugin li ho usati in questo esempio della WIKI:
https://www.gambas-it.org/wiki/index.php/Eseguire_i_file_audio_mediante_la_Classe_%27%27MediaPipeline%27%27_del_componente_gb.media#Mostrare_i_plug-in_dei_visualizzatori_grafici_di_Gstreamer
ma non sembrano essere gestibili, manipolabili, diciamo, a basso livello.
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 05 Marzo 2014, 11:57:11
si penso che i passaggi dovrebbero essere due:
1) renderizzare il file audio su un fake sink per leggere i dati "RAW" ed ottenere quindi da un audio compresso un WAV non compresso (in ram).
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-fakesink.html

2) analizzare il WAV (come hai fatto tu) e disegnare la forma d'onda su una "drawing area".

3) il cursore semplicemente e' una riga verticale disegnata (in trasparenza) sopra alla drawing area della waveform in corrispondenza (X) della "player.position" (rilevata in un timer per esempio):

X=(DrawingArea.width/player.duration)*player.position
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 06 Marzo 2014, 00:22:39
Bene.
Pronti, partenza.... vai !   (http://forum.ubuntu-it.org/images/smilies/whistle.gif)
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 06 Marzo 2014, 11:01:28
Lol ... stay tuned :-)
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 06 Marzo 2014, 19:29:42
Lol ... stay tuned :-)

   (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/rulezza.gif)
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 12 Marzo 2014, 20:11:18
gst-launch  -m uridecodebin name=decoder uri=file:///percorso/file.mp3 ! audioconvert ! level name=level interval=10000 ! fakesink | perl -lne 'print $1 if /rms.+?{\s+(-?\d+\.?\d*)/'

qualcuno suggerisce di utilizzare mmap per mappare il file in un'area di memoria (per velocizzare l'accesso): http://man7.org/linux/man-pages/man2/mmap.2.html

oppure utilizzare fdsink al posto di fakesink:
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-fdsink.html
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 13 Marzo 2014, 03:04:21
qualcuno suggerisce di utilizzare mmap per mappare il file in un'area di memoria (per velocizzare l'accesso): http://man7.org/linux/man-pages/man2/mmap.2.html

Ho cercato di trasportare in Gambas l'esempio in C presente in quella pagina:
Codice: gambas [Seleziona]

Private Const _SC_PAGE_SIZE As Byte = 30
Private Const PROT_READ As Byte = 1         ' Data can be read
Private Const MAP_PRIVATE As Byte = 2       ' Changes are private
Private Const MAP_FAILED As Integer = -1    ' Return value of `mmap' in case of an error


Library "libc:6"

' long sysconf(int name)
' Restituisce il valore del parametro di sistema name.
Private Extern sysconf(name As Integer) As Long

' void *mmap (void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset) __THROW
' Map addresses starting near ADDR and extending for LEN bytes.
Private Extern mmap(_addr As Pointer, _len As Integer, _prot As Integer, flags As Integer, _fd As Integer, off_t As Integer) As Pointer


Public Sub Main()

  Dim percorsoFile As String
  Dim fl As File
  Dim addr As Pointer
  Dim lungh_file, length, i As Integer
  Dim offset, pa_offset As Long
  Dim st As Stream
  Dim b As Byte

    percorsoFile = "/percorso/del/file/da/leggere"

    lungh_file = Stat(percorsoFile).Size

    offset = 8      ' numero d'indice 'esemplificativo' di partenza dei byte da leggere

    length = 7      ' quantità 'esemplificativa' dei byte da leggere

    fl = Open percorsoFile For Read
    If IsNull(fl) Then Error.Raise("Impossibile aprire il file !")

    pa_offset = offset And (Not (sysconf(_SC_PAGE_SIZE) - 1))

    If offset >= lungh_file Then Error.Raise("Il valore della variabile 'offset' ha oltrepassato la fine del file !")
  
    If length > 0 Then
      If offset + length > lungh_file Then length = lungh_file - offset
    Else
      length = lungh_file - offset
    Endif

    addr = mmap(0, length + offset - pa_offset, PROT_READ, MAP_PRIVATE, fl.Handle, pa_offset)
    If addr = MAP_FAILED Then Error.Raise("Errore alla funzione 'mmap()' !")

' Dereferenziamo il 'Puntatore' "addr" mediante i "Memory Stream":
    st = Memory addr For Read

    For i = 0 To length - 1
      Seek #st, (offset - pa_offset) + i
      Read #st, b
      Print b, Chr(b)
    Next

    st.Close
    fl.Close

End


In alternativa, si può trasformare quell'esempio in un una libreria esterna condivisa .so  ;D


oppure utilizzare fdsink al posto di fakesink:

....e quindi quale strada hai scelto ?
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 13 Marzo 2014, 15:11:32
sto' studiando :D

.... non avecce fretta (come dicono dalle mie parti) :D
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 13 Marzo 2014, 15:18:30
.... non avecce fretta

Fretta, non ne ho: sei tu che devi fare il programma.  :devil:
Era solo curiosità.  ;D
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 14 Novembre 2014, 02:30:56
... ho trovato un pezzo di codice C che potrebbe aiutare nell'operazione ...
https://github.com/erikd/sndfile-tools/blob/master/src/waveform.c

Ciao,
ho ripreso questo codice da te segnalato e ne ho creato una libreria esterna condivisa .so, che qui ti allego.


Circa l'uso, facendo l'esempio che poni questo file della libreria esterna nel percorso /tmp, mostro con un semplicissimo codice come va utilizzata in Gambas:

Codice: gambas [Seleziona]
Library "/tmp/creaonda"

Private Extern Crea_Onda(i As Integer, param As String[]) As Integer

Private Extern usage_exit(uss As String[], status As Integer)


Public Sub Main()

  Dim ss As String[] = ["Crea onda", "-b", "-c 1", "/percorso/del/file/audio.wav", "/percorso/dove/verrà/salvato/il file/immagine/dell'onda.png"]
  Dim err As Integer

   err = Crea_Onda(5, ss)
   If err <> 0 Then Error.Raise("Errore nella realizzazione dell'immagine dell'onda audio !")

' Mostra contemporaneamente in console una breve guida sull'uso della libreria:
   usage_exit(Null, 0)

   Print "\n\n\nFile immagine: creato."

End


E' assolutamente necessario avere installata nel sistema la libreria di sndfile .
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 16 Novembre 2014, 23:01:23
...va be'.... t'ho ricreato quel programma in GAMBAS traducendolo dal C.  (mi sono spaccato il ....... !   :hatecomputer:  )

E' necessario avere installata nel proprio sistema la libreria sndfile.

Gli iscritti al forum possono scaricare il sorgente, qui allegato.
Titolo: Re: generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 24 Novembre 2014, 13:37:39
scusa vuott per la mancanza di risposta .... mi dispiace molto per l'assenza, ma sono stato incasinatissimo nel lancio del nuovo portale dell'azienda per cui lavoro :-(

come solito hai fatto un grande lavoro e sono sicuro che il codice sia esattamente cio' di cui ho bisogno, ma nonostante sia tutto fatto, ancora non avro' il tempo di testarlo :D

in questo momento sono stato ridirezionato verso OTVA (il gestore di canali televisivi) (mentre il waveform drawer era parte di un progetto di automazione radiofonica ;-) ) e come solito il tutto doveva essere pronto il giorno prima di ricevere l'incarico :D

giuro pero' che faro' tesoro del tuo lavoro a breve!

saluti
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 03 Marzo 2016, 18:55:57
eccomi qua' .. come solito con mesi di ritardo torno sui temi che accantono per le (quotidiane) emergenze ....

domani prometto che ti faccio vedere qualcosa vuott :D
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 04 Marzo 2016, 13:55:19
Allora, metto il tutto in un modulo chiamato waveform.

Chiamo la procedura con Waveform.main (unico metodo visibile), ma poi mi da' un errore di apretura file (un mp3 che sicuramente e' nel percorso indicato nel sorgente).

Le librerie ci sono, non so esattamente cosa gli prenda ...

screenshot in allegato :-(
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 04 Marzo 2016, 17:00:50
Le librerie ci sono, non so esattamente cosa gli prenda ...

Il formato MP3 non è supportato dalla libreria libsndfile:
http://www.mega-nerd.com/libsndfile/FAQ.html#Q020
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 07 Marzo 2016, 18:45:06
ah .. ecco .... era semplice ....

un bel problema ....

con un file WAV codificato opus (scaricato dal sito degli sviluppatori di opus codec) il sistema va' ...

dopo aver passato la path con un dialog chiamo questo form (MusicImporter) di editing audio e nel form_open

Codice: [Seleziona]
Public Sub Form_Open()
Dim hImage As Picture

  WaveForm.MusicFilePath = MusicImporter.Tag
  If Exist(MusicImporter.Tag & ".png") = False Then WaveForm.Main
 
  hImage = Picture.Load(MusicImporter.Tag & ".png")

 
  DrawingArea_WaveForm.Clear
  DrawingArea_WaveForm.Width = hImage.Width
  DrawingArea_WaveForm.Height = hImage.Height
  DrawingArea_WaveForm.BackGround = Color.Green
  Draw.Begin(DrawingArea_WaveForm)
  Draw.Picture(hImage, 0, 0, 800, 200)
  Draw.End
 
End

nel modulo WaveForm (che hai codiifcato tu), ho aggiunto una public per parametrizzare la path del file audio
Codice: [Seleziona]
Public MusicFilePath As String

e nel main del waveform ho seguito di conseguenza:
Codice: [Seleziona]
Public Sub Main()

  Dim rend As New RENDER
  Dim percorsoFile As String

  percorsoFile = MusicFilePath             ' Il file audio (wav o ogg) dal quale creare la forma d'onda

With rend
  .sndfilepath = percorsoFile
  .pngfilepath = percorsoFile & ".png"                 ' Il percorso del futuro file .png
  .filename = File.Name(percorsoFile)                   ' Il solo nome del file comprensivo di estensione

etc etc etc

e' carino .. ma il limite degli mp3 e' tosto .....
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 07 Marzo 2016, 19:27:21
tanto perche' google e' una grande risorsa, ma anche una grande distrazione ... questa roba e' una figata!
https://github.com/bbcrd/audiowaveform

e forse anche gstreamer come plug in:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-plugin-waveform.html
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 08 Marzo 2016, 03:02:38
ah .. ecco ....

un bel problema ....


...potresti agevolmente pre-convertire il file MP3 in fomato WAV con un breve codice della libreria esterna di GStreamer:    :-\

http://www.gambas-it.org/wiki/index.php?title=Convertire_un_file_MP3_in_un_file_WAV_usando_una_linea_di_pipeline_con_la_funzione_%27gst_parse_launch%28%29%27





Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 09 Marzo 2016, 11:04:59
Penso di tagliare la testa al toro e "lockare" la versione open source a soli formati aperti.
Dovranno riacquisire i CD audio in formato opus (128kbps penso).

La cosa strana è che come per gli mp3 la libreria fallisce anche per i file .opus
Mentre un WAV codificato opus gli piace ...
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 09 Marzo 2016, 12:00:46
Dovranno riacquisire i CD audio in formato opus (128kbps penso).
Che intendi dire ?   ???
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 09 Marzo 2016, 19:40:20
Piuttosto che trasformare un mp3 compesso in un wav non compresso che pero' occupera' spazio senza migliorarne la qualita', dovro' fargli riacquisire il materiale dai cd-audio originali direttamente in opus a 128kbps.

Opus a 128 kbps dovrebbe essere full band.

O tu pensavi, decomprimo l'mp3 in wav, renderizzo il waveform e poi butto il wav intermedio?
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 09 Marzo 2016, 21:50:42
Ho dubbi che in qualche modo acquisterai qualità partendo da un compresso rispetto invece ad un iniziale file raw, come ad esempio un wav.   :-\

Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: allegfede - 11 Marzo 2016, 17:03:37
esatto.
ma il problema e' che ho gia' una grande quantita' di materiale codificato mp3 ....
devo capire se puntare su "pochi ma buoni" (e taggati decentemente) piuttosto che una marea di mp3 piu' o meno eteroogenei e non "matataggati" .... a malapena hanno i tag mp3 giusti ...
Titolo: Re:generazione della forma d'onda di un file audio (sound waveform)
Inserito da: vuott - 11 Marzo 2016, 18:07:51
Capisco.
Ad ogni modo, non dimenticare la possibilità - volendo - di convertire in esecuzione e temporaneamente i file mp3 in wav con quel brevissimo codice con le risorse di GStreamer che t'ho sopra segnalato.