Sto cercando di realizzare un vumeter "fisico" per piattaforma raspberry per dare un feedback visuale agli utilizzatori del device embedded.
Quindi l'idea e' leggere l'intensita' del segnale in ingresso dal line in di una scheda audio usb e visualizzare su un piccolo schermo lcd una barra che riproduca l'intensita' del segnale.
Dai vari suggerimenti e link scaturiti da questa discussione:
http://www.gambas-it.org/smf/index.php?topic=5807.0ho derivato un piccolo programma "console" che visualizza una barra sul terminale in base al volume di un segnale audio.
si lancia con (per esempio):
programmazione/DAB/pialsameter/pialsameter.gambas default
in allegato il codice completo:
' Gambas module file
Private Const SIZE As Long = 512
Private $bStop As Boolean
Private hVol As Float
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)
Private Extern snd_pcm_open(pcm As Pointer, name As String, streamInt 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)
Private Extern snd_pcm_set_params(pcm As Pointer, _format As Integer, _access 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)
Private Extern snd_pcm_readi(pcm As Pointer, buffer As Pointer, size As Long) As Long
' const char * snd_strerror (int errnum)
Private Extern snd_strerror(errnum As Integer) As String
' snd_pcm_close(snd_pcm_t *pcm)
Private Extern snd_pcm_close(pcm As Pointer)
Public Sub Main()
Dim deviceName As String
Dim handle As Pointer
Dim err, fc, channel, iVol, i As Integer
Dim buffer As New Short[SIZE]
If Application.Args.Count < 2 Then
Print "You must provide a sound device name"
Return
Endif
deviceName = Application.Args[1]
'ora la parte che legge i valori di alsa
' frequenza di campionamento (meglio sarebbe 48000)
fc = 44100
' Festlegen der Kanalanzahl (1=mono, 2=stereo)
channel = 2
' Registrieren von ALSA zur Aufnahme
err = snd_pcm_open(VarPtr(handle), deviceName, SND_PCM_STREAM_CAPTURE, 0)
If err < 0 Then Error.Raise("Fehler beim Öffnen des PCM Subsystems: " & snd_strerror(err))
' Einstellen der ALSA PCM Parameter
err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, channel, fc, 1, 0)
If err < 0 Then Error.Raise("Fehler beim Einstellen der PCM Parameter: " & snd_strerror(err))
$bStop = True
While $bStop ' läuft bis 'Stop' gedrückt wird
' Übernahme der Daten in das abuffer-Array
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] * buffer[i])
'iVol += CInt(buffer[i])
Next
'ivol = Abs(ivol) 'non so perche' possa venire un quadrato negativo
'hVol = iVol * 5
Try hVol = Sqr(iVol / SIZE)
'Print hvol * 0.43
RenderVolume 'hvol is the parameter
iVol = 0
' 1 ms Warten, um Programmeingaben vornehmen zu können
Wait 0.004
Wend
If $bStop = False Then snd_pcm_close(handle)
buffer.Clear()
End
Public Sub RenderVolume()
Dim volume As String
Dim i As Integer
Dim Max As Integer
Select Case hvol
Case 0
Print "tassenza segnale"
Case Else
'print hvol
max = CInt(100 - hvol) \ 2
' max = CInt(Log10(100 - hvol))
For i = 1 To max
volume = volume & "#"
Next
Print volume
End Select
If hvol > 100 Then
Print "ALTO!!!"
Endif
End
Ora la domanda e': come si fa a scrivere sempre sulla stessa riga della console (invece di far srivere una riga sotto l'altro)?
Domanda due (e qui e' dove ho abbandonato): come faccio ad avere il LEFT e RIGHT in due indicatori separati?
PS: ora devo interfacciare il gpio ......