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

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #15 il: 25 Luglio 2017, 18:52:55 »
mi crasha alla grande sul wait 0.001.....
se corri, morirai stanco (motto degli sniper)

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #16 il: 25 Luglio 2017, 19:41:05 »
Sì, ho visto.
Non accade con la funzione Sleep, ma il cambio risulta del tutto inutile per l'attivazione delle ProgressBar.    :-\
« 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. »

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #17 il: 25 Luglio 2017, 20:13:48 »
...c'è un problema sostanziale importantissimo all'interno di queste due funzioni:
Private Function rms1(buf As Short[], dimbuffer As Long) As Float
Private Function rms2(buf As Short[], dimbuffer As Long) As Float

ed in modo particolare noto che nella seconda funzione tu fai cominciare la raccolta dei campioni audio a 16 bit relativi al 2° canale  dalla metà della quantità di dati memorizzati nel buffer.
In sostanza i campioni di un canale, da mostrare, tu li prendi dalla prima metà di campioni memorizzati nel buffer, ed i campioni del secondo canale li fai derivare dalla seconda metà di dati memorizzati nel buffer.
Per capirci... se in ipotesi il buffer ha una capacità di 100 byte (25 * 2 per il canale destro + 25 * 2 per il canale sinistro.... moltiplichiamo per 2, poiché trattasi di campioni audio con definizione a 16-bit), tu dici che i primi 50 byte appartengono tutti ad un canale, e gli ultimi 50 byte all'altro canale.

Bisogna tenere conto delle caratteristiche di memorizzazione scelte.
La memorizzazione e la conseguente disposizione dei valori dei campioni in memoria è condizionata dalle opzioni: "Interleaved" e "Non-interleaved".
Leggasi al riguardo il breve paragrafo a tale argomento dedicato in queste pagine:
 http://nairobi-embedded.org/alsa_terminology.html
 https://www.alsa-project.org/main/index.php/PCM_Ring_Buffer

Ebbene tale caratteristica viene specificamente e precisamente impostata nel 3° parametro della funzione esterna di ALSA "snd_pcm_set_params( )", che nel tuo esempio è rappresentata dalla costante
 SND_PCM_ACCESS_RW_INTERLEAVED
Il che determina che la memorizzazione dei campioni audio a 16-bit sono posti un canale dopo l'altro alternativamente. Ossia:
| 16-bit 1° canale | 16-bit 2° canale | 16-bit 1° canale | 16-bit 2° canale | e così via.......

Da quanto detto, le parti delle due funzioni afferenti all'estrapolazione dei dati dei campioni audio dal buffer sono errate nella sostanza, poiché estrapoli la prima metà dei dati contenuti nel buffer, ritenendoli erroneamente attinenti tutti al 1 canale, e poi estrapoli gli ultimi dati finali del buffer, ritenendoli erroneamente attinenti tutti al 2° canale.
Insomma tu ritieni che i dati siano così disposti nel buffer:
| 16-bit 1° canale | 16-bit 1° canale | 16-bit 1° canale | ...... 16-bit 2° canale | 16-bit 2° canale | 16-bit 2° canale | ......

« Ultima modifica: 26 Luglio 2017, 10:27:31 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 allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #18 il: 26 Luglio 2017, 14:14:09 »
boh? avevo inferito da questa immagine:

se corri, morirai stanco (motto degli sniper)

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.133
  • Tonno verde
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #19 il: 26 Luglio 2017, 15:01:46 »
boh? avevo inferito da questa immagine:

Ho capito bene? Hai usato volutamente nel tuo post il verbo Inferire (Treccani = Portar dentro, arrecare, concludere) o si è trattato di un refuso?  :D

Un uso smodato di termini inusuali potrebbe arrecare grave danno al forum, financo l'estinzione di moderatori ignoranti!  >:( :evil:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #20 il: 26 Luglio 2017, 16:10:19 »
... da questa immagine:
A me pare  :-\ che si noti abbastanza [L][R]: ......insomma ogni casellina del "period" mi sembra appaia formata da un Left e da un Right, pari a 16 (in LittleEndian) + 16 (in LittleEndian) = 32 byte.   
No ?
« 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 #21 il: 26 Luglio 2017, 20:10:40 »
Citazione
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.

vedi, anche lui legge meta' del buffer:

Codice: [Seleziona]
   err = snd_pcm_readi(handle, buffer.Data, SIZE / 2)
   If err < 0 Then Error.Raise("Fehler bei der Audiodatenaufzeichnung " & snd_strerror(err))

   ' Berechnung der Summe der Volume-Werte
   For i = 0 To SIZE - 1
      iVol += CInt(buffer[i])
   Next

sembra come se abilitasse una lettura stereo ma visualizzasse solo i dati di un canale ....
se corri, morirai stanco (motto degli sniper)

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #22 il: 27 Luglio 2017, 01:24:00 »
Perché, mentre il buffer è espresso in Short (ossia nel tipo di dati che occupa 2 Byte, cioè 16-bit), il 3° parametro della funzione esterna di Alsa, snd_pcm_readi( ), è di tipo nativo-ALSA, ossia "snd_pcm_uframes_t", che rappresenta la quantità di frames letti o scritti.
Vedi al riguardo:
http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gab01fcfe9b97382a8d3f2027c664b8b8a
Riprendendo l'immagine da te proposta, e leggendo le seguenti righe:
" For 16 bit per channel stereo data, one ALSA frame has a length of four bytes (32 bits). "
presenti in questa pagina:
http://nairobi-embedded.org/alsa_terminology.html#alsa-frames-and-periods
risulta che, essendo un "frame" composto da due campioni per ciascun canale, Destra/Sinistra, si ha che (1 campione/canale/destro * Sizeof(gb.Short) byte) + (1 campione/canale/sinistro * SizeOf(gb.Short) byte) = 4 byte (32 bit).
Va da sé, dunque, che il valore attribuito per instanziare l'array di tipo Short, ossia il buffer contenente i dati audio, non assume il medesimo valore in byte di memoria occupati, se è posto al 3° parametro.

Infatti se - ad esempio - instanziamo un buffer_audio_dati come array di tipo Short con 1024 elementi, occupiamo in totale 1024 * 2 byte di memoria (rectius: 1024 * SizeOf(gb.Short) byte).
Se andassimo a porre il medesimo valore 1024 all'interno del 3° parametro della funzione esterna di Alsa, snd_pcm_readi( ), esso verrà così interpretato:
 1024 frames = 1024 * (2 byte + 2 byte)......... che è appunto il doppio dell'array.
Questo accade, lo ripeto per chiarezza, perché:
 1 campione_audio_L_o_R = 1 * SizeOf(gb.Short) = 16 bit
 1 frames_audio_ALSA = 1 * (1_campione_audio_destra + 1_campione_audio_sinistra) = 32 bit
In pratica come si vede anche nell'immagine da te proposta, 1 frame contiene 2 campioni audio (1 del canale destro e 1 del canale sinistro):

|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro| etc............  (interleaved)
[                Frame                     ][               Frame                     ][                Frame                     ][                Frame                     ][  etc............


Quindi il nostro amico deve dividere per 2 per rendere omogenei i byte di memoria occupati definiti nel 2° parametro con i byte di memoria occupati definiti nel 3° parametro:

  (1_campione_audio_destra + 1_campione_audio_sinistra) / 2 = 16 = SizeOf(gb.Short)
« Ultima modifica: 28 Luglio 2017, 21:11:35 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 allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #23 il: 27 Luglio 2017, 18:38:02 »
... m'arrendo :-(
se corri, morirai stanco (motto degli sniper)

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #24 il: 27 Luglio 2017, 18:49:29 »
ALSA non è criptica; è un sistema molto complesso che pretende precisione.  :-X

Se ci si vuol avere a che fare, si è costretti a studiarlo in modo approfondito.
« 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 Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #25 il: 19 Agosto 2017, 20:17:39 »
Provando a fare in Gambas quello che chiedeva allegfede, ho buttato giù queste poche righe:

Codice: [Seleziona]
Public Sub Form_Open()
Dim intero As Integer
Dim short1, short2 As Short
intero = &hA0B035FF
short2 = intero And &hFFFF 'manteniamo le 4 cifre più a destra
Print Hex$(short2)
short1 = Lsr(intero, 16) 'spostiamo a destra di 4 cifre
Print Hex$(short1)
End

La prima operazione riporta correttamente il valore &h35FF la seconda invece mi restituisce &hFFFFFFFFFFFFA0B0, che sarebbe anche corretta se non aggiugesse tutte quelle F facendo diventare uno short addirittura un long... ???
Notare che se la pima cifra dell'intero è inferiore a 8 questo scherzo non lo fa.
Ho provato in altre maniere ma da sempre lo stesso risultato. Capita anche a voi? :-\
« Ultima modifica: 19 Agosto 2017, 20:21:53 da Top Fuel »
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #26 il: 19 Agosto 2017, 20:59:23 »
La prima cosa che noto è che il valore esadecimale &hA0B035FF, da te assegnato ad una variabile di tipo "Integer", equivale in rappresentazione decimale a: 2695902719.
Questo valore supera le capacità di memorizzazione del tipo di dato "Integer", il valore massimo del quale in Gambas è "2147483647" (corrispondente al tipo di dato "signed int" del linguaggio C).
« 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. »

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #27 il: 19 Agosto 2017, 21:34:37 »
la seconda invece mi restituisce &hFFFFFFFFFFFFA0B0
Ho provato in altre maniere ma da sempre lo stesso risultato. Capita anche a voi? :-\

Anche in quest'altro caso tu non hai tenuto conto del tipo di dato  :violent: al quale hai voluto assegnare il valore esadecimale 0xa0b0 (&A0B0).

Il valore &A0B0 equivale in rappresentazione decimale a 41136 .
La variabile alla quale tu hai assegnato 41136 è uno Short (corrispondente al tipo signed short del C), il cui valore massimo positivo di memorizzazione e di rappresentazione in Gambas è:  +32767 !

32767 = &h7FFF
quindi....


Oh, ragazzi ! Sveglia !!!   :hatecomputer:


« Ultima modifica: 19 Agosto 2017, 22:05:32 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 Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #28 il: 19 Agosto 2017, 22:11:39 »
Dovrebbe dare comunque un valore negativo, cioè -24400, comunque dentro nel range di uno short.
Ciò vale anche per l'integer che ho usato.
Ciò continua a non spiegare tutte quelle FFFF...
« Ultima modifica: 19 Agosto 2017, 22:12:41 da Top Fuel »
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Online vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.245
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Da un long derivare i due short (c)
« Risposta #29 il: 20 Agosto 2017, 00:28:42 »
Dovrebbe dare comunque un valore negativo, cioè -24400, comunque dentro nel range di uno short.
Ciò vale anche per l'integer che ho usato.

..ed infattii la sua rappresentazione decimale dà -24400 .
Se tu appunto scrivi:
   Print Hex$(short1), short1
ottieni:
FFFFFFFFFFFFA0B0        -24400
Però tu non t'aspettavi questo risultato, non volevi quel numero negativo...

Tu invece volevi ovviamente il risultato restituito da questa istruzione:
 Print Hex(Lsr(&A0B035FF&, 16), 16)
In questo caso il valore restituito dalla funzione "Lsr( )" non viene assegnato ad alcuna variabile di tipo Short, né convertito in un valore di tipo Short; esso viene invece letto e stampato direttamente nello standard output (console).



Ciò continua a non spiegare tutte quelle FFFF...
E' in ogni caso il modo in cui vengono espressi in decimale i numeri negativi, ma anche i valori che oltrepassano i limiti del tipo-di-dato della variabile utilizzata:
Codice: [Seleziona]
Public Sub Main()

  Dim s As Short

   s = -24400
   Print Hex(s)
 
   s = 41136
   Print Hex(s)

End


Facendo un'analoga prova in C:
Codice: [Seleziona]
#include <stdio.h>


int main() {

signed short int pos = 41136, neg = -24400;

printf("%.16x\n%.16x\n", pos, neg);

      return (0);

}
si ottiene sostanzialmente il medesimo risultato di Gambas:

00000000ffffa0b0

con la differenza rispetto a Gambas che, però, in C non sono presenti gli altri otto "F" sulla sinistra dell'esadecimale.



......ad ogni modo ciò non inficia la necessità di prestare la dovuta attenzione ai "tipi" di dati durante la gestione dei dati.
Inoltre, restano le mie iniziali perplessità e incomprensioni  :rolleyes: sull'ipotesi di Allegfede, di poter ottenere - o meglio: distinguere - da un Long, con lo spostamento dei bit, i valori di ciascuno dei due canali di un flusso di dati audio stereo.   
« Ultima modifica: 20 Agosto 2017, 04:33:06 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. »