Gambas-it

Programmazione => Altri linguaggi => Topic aperto da: allegfede - 21 Luglio 2017, 23:37:17

Titolo: Da un long derivare i due short (c)
Inserito da: allegfede - 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....
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 22 Luglio 2017, 00:25:40
Quanti ricordi... Svaniti....

Te sta' 'ntruppa' ?
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: splugenbrau - 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. :-\
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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


Titolo: Re:Da un long derivare i due short (c)
Inserito da: Gianluigi - 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  :-\
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 24 Luglio 2017, 00:38:44
Chi crede in San Midi (https://it.wikipedia.org/wiki/Musical_Instrument_Digital_Interface), programmerà in eterno !

 sanmidi
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 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)
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 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 .... ??!!!?!?!?!
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 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.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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 ?    :-\
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 25 Luglio 2017, 18:52:55
mi crasha alla grande sul wait 0.001.....
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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.    :-\
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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 | ......

Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 26 Luglio 2017, 14:14:09
boh? avevo inferito da questa immagine:

(http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/067/6735/6735f1.jpg)
Titolo: Re:Da un long derivare i due short (c)
Inserito da: Gianluigi - 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:
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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 ?
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 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 ....
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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)
Titolo: Re:Da un long derivare i due short (c)
Inserito da: allegfede - 27 Luglio 2017, 18:38:02
... m'arrendo :-(
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: Top Fuel - 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? :-\
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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).
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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:


Titolo: Re:Da un long derivare i due short (c)
Inserito da: Top Fuel - 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...
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 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... (http://www.kadrovik.ru/modules/PNphpBB2/images/smiles/icon_rolleyes.gif)

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.   (http://prisonofficer.org.uk/images/smilies/crazy.gif)
Titolo: Re:Da un long derivare i due short (c)
Inserito da: Top Fuel - 20 Agosto 2017, 19:52:20
Quello che non capisco  è il fatto che Lsr dovrebbe semplicemente spostare i bit a destra fregandosene altamente del bit di segno e introdurre degli zeri da sinistra. Ma non lo fa, secondo me è un bug.
Riguardo la richiesta di Allegfede, io l'ho capita abbastanza bene, vuole in pratica spaccare un Long in due parti distinte, e lo spostamento dei bit è una buona maniera di poterlo fare.
Titolo: Re:Da un long derivare i due short (c)
Inserito da: vuott - 20 Agosto 2017, 20:32:09
Riguardo la richiesta di Allegfede, io l'ho capita abbastanza bene, vuole in pratica spaccare un Long in due parti distinte, e lo spostamento dei bit è una buona maniera di poterlo fare.
Sì, ma quello che non capisco  :-\ è come - secondo lui - il valore contenuto dal Long possa essere costituito in vero da due valori che si riferiscono a dati audio di canali distinti: ossia 16 bit a destra, che si riferiscono ad un canale audio, e 16 bit a sinistra che si riferiscono all'altro canale audio.
Del resto la somma di due onde non lascia distinte - come risultato - le due onde medesime.