Differenze tra le versioni di "Eseguire una traccia di un CD-Audio con le risorse di linux/cdrom.h e le funzioni esterne di ALSA"
Da Gambas-it.org - Wikipedia.
Riga 1: | Riga 1: | ||
− | Di seguito mostriamo un esempio per eseguire una traccia di un CD-Audio mediante le risorse dichiarate nel file header "''/usr/include/linux/cdrom.h''" e le funzioni esterne di ALSA. | + | Di seguito mostriamo un esempio per eseguire una traccia di un CD-Audio mediante le risorse dichiarate nel file header "''/usr/include/linux/cdrom.h'' " e le funzioni esterne di ALSA. |
<BR>Dopo aver lanciato il programma, far scorrere in fondo la console/Terminale e immettere il numero della traccia a destra del testo azzurro mostrato. | <BR>Dopo aver lanciato il programma, far scorrere in fondo la console/Terminale e immettere il numero della traccia a destra del testo azzurro mostrato. | ||
Library "libc:6" | Library "libc:6" |
Versione delle 08:16, 18 mag 2021
Di seguito mostriamo un esempio per eseguire una traccia di un CD-Audio mediante le risorse dichiarate nel file header "/usr/include/linux/cdrom.h " e le funzioni esterne di ALSA.
Dopo aver lanciato il programma, far scorrere in fondo la console/Terminale e immettere il numero della traccia a destra del testo azzurro mostrato.
Library "libc:6" Public Struct cdrom_tochdr cdth_trk0 As Byte cdth_trk1 As Byte End Struct Public Struct cdrom_ti cdti_trk0 As Byte cdti_ind0 As Byte cdti_trk1 As Byte cdti_ind1 As Byte End Struct Public Struct cdrom_tocentry cdte_track As Byte cdte_adr As Byte cdte_format As Short minute As Byte second As Byte frame As Byte lba As Integer cdte_datamode As Byte End Struct Private Const CDROMREADTOCHDR As Long = &5305 Private Const CDROMREADTOCENTRY As Long = &5306 Private Const CDROMSTART As Long = &5308 Private Const CDROMREADAUDIO As Long = &530E Private Const CDROM_MSF As Long = 2 Private Const CD_FRAMES As Integer = 75 Private Const CD_FRAMESIZE_RAW As Integer = 2352 ' int ioctl (int __fd, unsigned long int __request, ...) ' Perform the I/O control operation specified by REQUEST on FD. Private Extern ioctl_HDR(__fd As Integer, _request As Long, param As Cdrom_tochdr) As Integer Exec "ioctl" ' int ioctl (int __fd, unsigned long int __request, ...) ' Perform the I/O control operation specified by REQUEST on FD. Private Extern ioctl_TOC(__fd As Integer, _request As Long, param As Cdrom_tocentry) As Integer Exec "ioctl" ' int ioctl (int __fd, unsigned long int __request, ...) ' Perform the I/O control operation specified by REQUEST on FD. Private Extern ioctl_RA(__fd As Integer, _request As Long, param As Pointer) As Integer Exec "ioctl" ' int ioctl (int __fd, unsigned long int __request, ...) ' Perform the I/O control operation specified by REQUEST on FD. Private Extern ioctl_STA(__fd As Integer, _request As Long, param As Pointer) As Integer Exec "ioctl" Library "libasound:2" Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 Private Const SND_PCM_FORMAT_S16_LE As Integer = 2 Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 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(pcm As Pointer, nome As String, stream As Integer, mode 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_set_params (snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int canali, 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, formatI As Integer, accessI As Integer, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer ' snd_pcm_sframes_t snd_pcm_writei (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size) ' Write interleaved frames to a PCM. Private Extern snd_pcm_writei(pcm As Pointer, buffer As Pointer, uframes As Long) As Integer ' int snd_pcm_drain (snd_pcm_t *pcm) ' Stop a PCM preserving pending frames. Private Extern snd_pcm_drain(pcm As Pointer) As Integer ' int snd_pcm_close (snd_pcm_t *pcm) ' Close PCM handle. Private Extern snd_pcm_close(pcm As Pointer) As Integer Public Sub Main() Dim fl As File Dim handle, buffer As Pointer Dim hdr As New Cdrom_tochdr Dim index As New Cdrom_ti Dim ttcc As Cdrom_tocentry[] Dim trc, m, s As Byte Dim sec1, sec2 As Short Dim ts As String Dim i, t, frame, somma, err As Integer Dim st As Stream Dim buf As New Byte[CD_FRAMES * CD_FRAMESIZE_RAW] ' Imposta e apre in lettura il file-device del driver del CDROM contenente il CD-Audio da eseguire: fl = Open "/dev/sr0" For Read If IsNull(fl) Then Error.Raise("ERRORE !") ' Rende subito attivo il lettore CDROM: ioctl_STA(fl.Handle, CDROMSTART, 0) ioctl_HDR(fl.Handle, CDROMREADTOCHDR, hdr) Print "Numero Tracce audio presenti: "; hdr.cdth_trk1 ttcc = New Cdrom_tocentry[hdr.cdth_trk1 + 2] ' Acquisisce informazioni dalla TOC per ciascuna traccia presente nel CD-Audio: For i = 1 To hdr.cdth_trk1 + 1 ttcc[i] = New Cdrom_tocentry t = i ' Se è stata scelta l'ultima traccia, il valore di "t" deve essere = &hAA (170), ' per ottenere la marcatura temporale della fine di tale ultima traccia, che corrisponde all'intera durata del CD-Audio: If t == hdr.cdth_trk1 + 1 Then t = &AA Tempo(fl.Handle, t, ttcc[i]) Next ' Mostra la durata del CD-Audio e delle singole tracce audio presenti: Print "Durata totale del CD-Audio: "; Date(0, 0, 0, 0, 0, 0, ((ttcc[ttcc.Max].minute * 60) + ttcc[ttcc.Max].second) * 1000) Print Print "Durata delle Tracce" For i = 1 To ttcc.Max - 1 Print "Traccia: " & i, Date(0, 0, 0, 0, 0, 0, CInt((((ttcc[i + 1].minute * 60) + ttcc[i + 1].second)) - (((ttcc[i].minute * 60) + ttcc[i].second))) * 1000) Next Print ' Chiede che sia immesso nello spazio della console il numero della traccia audio da eseguire: Write #File.Out, " \e[34mInserire il numero della traccia audio da eseguire... \e[1m\e[31m" Flush #File.Out ' Dopo aver scritto il numero della traccia da eseguire, attende che sia premuto il tasto "Invio": Input ts trc = CByte(Val(ts)) ' Calcola la distanza temporale dell'inizio dei dati della traccia da eseguire rispetto all'inizio del CD-Audio: sec1 = (ttcc[trc].minute * 60) + ttcc[trc].second ' Calcola la distanza temporale dell'inizio dei dati della traccia, successiva a quella prescelta, dall'inizio del CD-Audio: sec2 = (ttcc[trc + 1].minute * 60) + ttcc[trc + 1].second ' Calcola la durata temporale della traccia audio da eseguire: Print "\n\e[0mEsecuzione audio della traccia n. "; ts & " - Durata: " & CStr(Date(0, 0, 0, 0, 0, 0, (sec2 - sec1) * 1000)) Print index.cdti_trk0 = hdr.cdth_trk0 index.cdti_trk1 = hdr.cdth_trk1 buffer = Alloc(SizeOf(gb.Byte), 24) err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_PLAYBACK, 0) If err < 0 Then Error.Raise("Errore nell'apertura del subsistema PCM: " & snd_strerror(err)) err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 44100, 1, 500000) If err < 0 Then Error.Raise("Errore nell'impostazione dei parametri audio: " & snd_strerror(err)) st = Memory buffer For Write Seek #st, 4 Write #st, CDROM_MSF As Byte Seek #st, 8 Write #st, CD_FRAMES As Integer Seek #st, 16 Write #st, buf.Data As Pointer ' I due valori del ciclo "For" sono espressi in secondi. ' Il primo valore corrisponde alla distanza temporale dell'inizio della traccia audio prescelta dall'inizio dei dati audio presenti nel CD-Audio; ' ovvero dall'inizio dell'audio sino alla fine della traccia, precedente a quella che deve essere eseguita, + 2 secondi senza dati. ' Il secondo valore del ciclo "For" rappresenta la distanza temporale dei primi dati audio della traccia successiva a quella prescelta. ' Tale valore viene comunque ridotto di un'unità per garantire che non si eseguano i primi dati audio di tale traccia successiva. For i = sec1 To (sec2 - 1) m = Fix(i / 60) s = i Mod 60 Seek #st, 0 Write #st, m As Byte ' minuti Write #st, s As Byte ' secondi ioctl_RA(fl.Handle, CDROMREADAUDIO, buffer) For frame = 0 To CD_FRAMES - 1 ' Il secondo parametro potrà anche essere: buf.Data + (frame * CD_FRAMESIZE_RAW) somma += snd_pcm_writei(handle, Pointer@(buffer + 16) + (frame * CD_FRAMESIZE_RAW), CD_FRAMESIZE_RAW / 4) Write "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / 44100) * 1000) Next Next snd_pcm_drain(handle) ' Va in chiusura: st.Close Free(buffer) fl.Close ' Al termine dell'esecuzione chiude il subsistema PCM: err = snd_pcm_close(handle) If err == 0 Then Print "\nChiusura dell'interfaccia PCM: regolare." End Private Procedure Tempo(fd As Integer, t As Byte, ent As Cdrom_tocentry) ent.cdte_track = t ent.cdte_format = CDROM_MSF ioctl_TOC(fd, CDROMREADTOCENTRY, ent) End