Autore Topic: Da un long derivare i due short (c)  (Letto 5152 volte)

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Da un long derivare i due short (c)
« il: 21 Luglio 2017, 23:37:17 »
In questo codice il programmatore prende un segnale mono (il device default di alsa) e ne legge il valore per visualizzarlo a schermo.
https://github.com/johnliu55tw/ALSASoundMeter

Ora io dovrei farme una versione stereo, che banalmente farei raddoppiando buffer in buffer_l e buffer_r, aggiungendo un buffer_totale che è non più short, ma long

Long buffer_totale[2*8*1024];

Cambiando la procedura di 'setup' della lettura di alsa da:

err = snd_pcm_set_params(handle_capture,
                             SND_PCM_FORMAT_S16_LE,
                             SND_PCM_ACCESS_RW_INTERLEAVED,
                             1,
                             48000,
                             1,
                             500000);

In:

err = snd_pcm_set_params(handle_capture,
                             SND_PCM_FORMAT_S16_LE,
                             SND_PCM_ACCESS_RW_INTERLEAVED,
                             2,
                             48000,
                             1,
                             500000);

Ma ora non so come assegnare i primi 8 bit di buffer_totale a buffer_l e gli ultimi 8 a buffer_r

......

Quanti ricordi... Svaniti....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #1 il: 22 Luglio 2017, 00:25:40 »
Quanti ricordi... Svaniti....

Te sta' 'ntruppa' ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #2 il: 22 Luglio 2017, 00:45:22 »
Interessante questo programmino che mostra in tempo reale i decibel di una registrazione !   :)


che è non più short, ma long
Non riesco a capire perché, raddoppiando, tu vai a quadruplicare passando da un tipo "short int" (come vedo impostato nel codice C) ad un tipo "long int", per poi analogamente al contrario derivare da questo long due short.   :-\

Inoltre, non ho ben compreso cosa vuoi fare.    ???
 Il tipo "long int" occupa ben 64 bit e rappresenta comunque un numero unico.
« Ultima modifica: 22 Luglio 2017, 02:38:21 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline splugenbrau

  • Grande Gambero
  • ***
  • Post: 205
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #3 il: 23 Luglio 2017, 11:06:34 »
Si può fare shiftando i bits?
In C:
https://en.wikipedia.org/wiki/Bitwise_operations_in_C
In Gambas non ho trovato nessuna pagina web. :-\

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #4 il: 23 Luglio 2017, 15:04:37 »
Si può fare shiftando i bits?
Exactement.


In Gambas non ho trovato nessuna pagina web.
http://gambaswiki.org/wiki/cat/bit
http://www.gambas-it.org/wiki/index.php?title=Sostituire_gli_operatori_logici_di_spostamento_dei_bit_con_semplici_operazioni

Il problema è che - con riferimento al suo argomento - io non ho compreso perché AllegFede li vuole spostare. Per ottenere "cosa" ?  :-X
« Ultima modifica: 23 Luglio 2017, 15:28:49 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #5 il: 23 Luglio 2017, 18:25:19 »
In questo codice il programmatore prende un segnale mono (il device default di alsa) e ne legge il valore per visualizzarlo a schermo.
https://github.com/johnliu55tw/ALSASoundMeter
Per gli utenti, ...vicini e lontani, ho tradotto in Gambas il simpatico programmino, scritto in C, sopra indicato da AllegFede.

Prendete e mangiatene tutti:
Codice: [Seleziona]
Private handle As Pointer
Private bo As Boolean
Private lb As Label
 
Library "libasound:2"

Private Const SND_PCM_STREAM_CAPTURE As Byte = 1
Private Const SND_PCM_FORMAT_S16_LE As Byte = 2
Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Byte = 3

' int snd_pcm_open(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)
' Opens a PCM.
Private Extern snd_pcm_open(handleP As Pointer, nome As String, flusso As Integer, mode As Integer) As Integer

' int snd_pcm_set_params(snd_pcm_t * pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned Int latency)
' Set the hardware and software parameters in a simple way.
Private Extern snd_pcm_set_params(pcm As Pointer, formatInt As Integer, accesso As Integer, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer

' snd_pcm_sframes_t snd_pcm_readi (snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
' Read interleaved frames from a PCM.
Private Extern snd_pcm_readi(pcm As Pointer, buffer As Pointer, size As Integer) As Integer

' const char * snd_strerror (int errnum)
' Returns the message for an error code.
Private Extern snd_strerror(errnum As Integer) As String

' int snd_pcm_recover (snd_pcm_t *pcm, int err, int silent)
' Recover the stream state from an error or suspend.
Private Extern snd_pcm_recover(pcm As Pointer, err As Integer, silent As Integer) As Integer
   
' snd_pcm_close(snd_pcm_t *pcm)
' Close PCM handle.
Private Extern snd_pcm_close(pcm As Pointer)


Public Sub Form_Open()

  Dim err As Integer
   
' Apre il sub-sistema PCM di ALSA per la registrazione:
   err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_CAPTURE, 0)
   If err < 0 Then Error.Raise("Errore nell'apertura del sub-sistema PCM: " & snd_strerror(err))
 
' Imposta i parametri del sub-sistema PCM di ALSA per la registrazione:
   err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 48000, 1, 500000)
   If err < 0 Then
     snd_pcm_close(handle)
     Error.Raise("Errore nell'impostazione dei parametri del sub-sistema PCM: " & snd_strerror(err))
   Endif
 
   With ProgressBar1
     .Value = 0
     .Label = False
   End With
 
   With lb = New Label(ProgressBar1)
     .Background = Color.Transparent
     .Alignment = Align.Center
   End With
   
   bo = True

End


Public Sub Button1_Click()
 
  Dim err, dB, peak As Integer
  Dim k As Float = 0.45255
  Dim Pvalue As Float
  Dim buffer As Short[]
  Dim buffer_size, frames As Long
  Dim b As Byte

   buffer = New Short[8 * 1024]
 
   buffer_size = CLong(Shr(buffer.Count * SizeOf(gb.Short), 1))
   
   While bo
' Legge i dati intercettati:
     frames = snd_pcm_readi(handle, buffer.Data, buffer_size)
     If frames < 0 Then
' Tenta di ripristinare:
       err = snd_pcm_recover(handle, frames, 0)
       If err < 0 Then
         snd_pcm_close(handle)
         Error.Raise("Errore alla funzione snd_pcm_readi( ): " & snd_strerror(err))
       Endif
     Endif

     If (frames > 0) And (frames < CLong(buffer_size)) Then
       snd_pcm_close(handle)
       Error.Raise("Lettura dati ridotta (atteso: " & CStr(buffer_size) & ", letto: " & CStr(frames) & ")")
     Endif
       
' Calcola dB e aggiorna eventualmente il valore di picco:
     Pvalue = rms(buffer, buffer_size) * k
     dB = CInt(20 * Log10(Pvalue))
     If dB > peak Then peak = dB
       
     For b = 1 To 8
       ProgressBar1.Value = dB / 100
       lb.Text = CStr(dB) & " dB"
       Wait 0.001
     Next
     
     Label1.Text = "Picco max: " & CStr(peak) & " dB"

   Wend
   
' Va in Chiusura liberando la memoria precedentemente occupata:
   buffer.Clear
   snd_pcm_close(handle)
   Me.Close
   
End


Public Sub Button2_Click()

   bo = False
   
End


Private Function rms(buf As Short[], dimbuffer As Long) As Float
 
  Dim i As Integer
  Dim square_sum As Long
  Dim result As Float
   
   For i = 0 To dimbuffer - 1
     square_sum += CLong(buf[i]) * CLong(buf[i])
   Next
   result = Sqr(square_sum / dimbuffer)
 
   Return result
   
End


« Ultima modifica: 23 Luglio 2017, 18:52:43 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #6 il: 23 Luglio 2017, 21:21:36 »

Per gli utenti, ...vicini e lontani...
Prendete e mangiatene tutti:
...
Grazie  :D

ma non ho capito se sei il novello Nunzio Filogamo o il novello Messia  :-\
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #7 il: 24 Luglio 2017, 00:38:44 »
Chi crede in San Midi, programmerà in eterno !

 sanmidi
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #8 il: 24 Luglio 2017, 14:12:57 »
come al solito sei un mito!

Ho fatto un paio di integrazioni:

Codice: [Seleziona]
Try dB = CInt(20 * Log10(Pvalue))
If Error Then db = 0

perche' il logaritmo di 0 (quando premi il tasto mute di un microfono usb) da' errore :D

ed ho cambiato la selezione del device cosi':
Codice: [Seleziona]
err = snd_pcm_open(VarPtr(handle), "dsnoop:CARD=Device,DEV=0", SND_PCM_STREAM_CAPTURE, 0)

PS: arecord -L da la lista dettagliata dei device

PPS:: pero' e' sempre mono, se uso un segnale stereo e' un problema:
err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 48000, 1, 500000)
« Ultima modifica: 24 Luglio 2017, 14:20:46 da allegfede »
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #9 il: 24 Luglio 2017, 16:10:20 »
perche' il logaritmo di 0 (quando premi il tasto mute di un microfono usb) da' errore
Sì, avevo notato.
Si potrebbe anche suggerire una soluzione di questo genere:
Codice: [Seleziona]
......
   Pvalue = rms(buffer, buffer_size) * k

   If Pvalue <> 0 Then
     dB = CInt(20 * Log10(Pvalue))
     If dB > peak Then peak = dB
       
     For b = 1 To 8
       ProgressBar1.Value = dB / 100
       lb.Text = CStr(dB) & " dB"
       Wait 0.001
     Next
     Else
       ProgressBar1.Value = 0.0
       lb.Text = "0 dB"
       Wait 0.001
   Endif

     Label1.Text = "Picco max: " & CStr(peak) & " dB"

......




PPS:: pero' e' sempre mono, se uso un segnale stereo e' un problema:
Ovviamente il problema non è legato alle risorse esterne lì utilizzate di ALSA; si tratta invece di rendere coerente la procedura, per ottenere i decibel, con la cattura di tipo stereo.

...eh...cumincia a curre', ma senza inciampica' !  :-X
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #10 il: 24 Luglio 2017, 19:16:12 »
non t'arrabbia' vuott, alsa e' criptico parecchio .....

ed in ogni caso c'e' qualcosa che non ho capito perche' con un altro codice (in allegato) ottengo robe stranissime:

sommando anche due soli byte ottengo valori di diversi milioni sul canale destro .... ??!!!?!?!?!
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #11 il: 24 Luglio 2017, 20:58:11 »
non t'arrabbia' vuott, alsa e' criptico parecchio .....
Chi si sta arrabbiando ?!


ed in ogni caso c'e' qualcosa che non ho capito perche' con un altro codice (in allegato) ottengo robe stranissime:

sommando anche due soli byte ottengo valori di diversi milioni sul canale destro .... ??!!!?!?!?!
Non ho capito che cosa intendi dire.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #12 il: 25 Luglio 2017, 02:08:30 »
Forse il tread sta andando off topic.
Cambio il Titolo in alsa vu meter in c?
Domani mattina faccio una disamina più dettagliata.
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #13 il: 25 Luglio 2017, 02:42:46 »
Cambio il Titolo in alsa vu meter in c?
Cosa cambia ?    ???


Riguardo ad un possibile Vu-Meter ricordo quello creato da Ingo Beckert, del forum tedesco dei programmatori Gambas, che io ho leggermente ritoccato e del quale gli iscritti al nostro forum possono scaricare qui l'allegato.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #14 il: 25 Luglio 2017, 02:53:22 »
...ma perché non traduci in Gambas quel secondo programmino, scritto in C, per la cattura stereo dei dati audio ?    :-\
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »