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.
(Una versione intermedia di uno stesso utente non è mostrata) | |||
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 "<FONT Color=blue>libc:6</font>" |
Public Struct cdrom_tochdr | Public Struct cdrom_tochdr | ||
Riga 51: | Riga 51: | ||
− | Library "libasound:2" | + | Library "<FONT Color=red>libasound:2.0.0</font>" |
Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 | Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 | ||
Riga 82: | Riga 82: | ||
− | + | Public Sub Main() | |
Dim fl As File | Dim fl As File | ||
Riga 95: | Riga 95: | ||
Dim st As Stream | Dim st As Stream | ||
Dim buf As New Byte[CD_FRAMES * CD_FRAMESIZE_RAW] | Dim buf As New Byte[CD_FRAMES * CD_FRAMESIZE_RAW] | ||
− | + | ||
<FONT Color=gray>' ''Imposta e apre in lettura il file-device del driver del CDROM contenente il CD-Audio da eseguire:''</font> | <FONT Color=gray>' ''Imposta e apre in lettura il file-device del driver del CDROM contenente il CD-Audio da eseguire:''</font> | ||
− | fl = Open "/dev/<FONT Color= | + | fl = Open "/dev/<FONT Color=red>sr0</font>" For Read |
− | + | ||
− | |||
<FONT Color=gray>' ''Rende subito attivo il lettore CDROM:''</font> | <FONT Color=gray>' ''Rende subito attivo il lettore CDROM:''</font> | ||
ioctl_STA(fl.Handle, CDROMSTART, 0) | ioctl_STA(fl.Handle, CDROMSTART, 0) | ||
Riga 112: | Riga 111: | ||
ttcc[i] = New Cdrom_tocentry | ttcc[i] = New Cdrom_tocentry | ||
t = i | t = i | ||
− | <FONT Color=gray>' ''Se è stata scelta l'ultima traccia, il valore di "t" deve essere = &hAA (170), | + | <FONT Color=gray>' ''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:''</font> |
− | |||
If t == hdr.cdth_trk1 + 1 Then t = &AA | If t == hdr.cdth_trk1 + 1 Then t = &AA | ||
Tempo(fl.Handle, t, ttcc[i]) | Tempo(fl.Handle, t, ttcc[i]) | ||
Riga 119: | Riga 117: | ||
<FONT Color=gray>' ''Mostra la durata del CD-Audio e delle singole tracce audio presenti:''</font> | <FONT Color=gray>' ''Mostra la durata del CD-Audio e delle singole tracce audio presenti:''</font> | ||
− | Print "Durata totale del CD-Audio: "; | + | Print "Durata totale del CD-Audio: "; Time(0, 0, 0, ((ttcc[ttcc.Max].minute * 60) + ttcc[ttcc.Max].second) * 1000) |
Print | Print | ||
Print "Durata delle Tracce" | Print "Durata delle Tracce" | ||
For i = 1 To ttcc.Max - 1 | For i = 1 To ttcc.Max - 1 | ||
Print "Traccia: " & | Print "Traccia: " & | ||
− | i, | + | i, Time(0, 0, 0, CInt((((ttcc[i + 1].minute * 60) + ttcc[i + 1].second)) - (((ttcc[i].minute * 60) + ttcc[i].second))) * 1000) |
Next | Next | ||
Print | Print | ||
<FONT Color=gray>' ''Chiede che sia immesso nello spazio della console il numero della traccia audio da eseguire:''</font> | <FONT Color=gray>' ''Chiede che sia immesso nello spazio della console il numero della traccia audio da eseguire:''</font> | ||
− | Write | + | Write " \e[34mInserire il numero della traccia audio da eseguire... \e[1m\e[31m" |
− | Flush | + | Flush |
<FONT Color=gray>' ''Dopo aver scritto il numero della traccia da eseguire, attende che sia premuto il tasto "Invio":''</font> | <FONT Color=gray>' ''Dopo aver scritto il numero della traccia da eseguire, attende che sia premuto il tasto "Invio":''</font> | ||
Input ts | Input ts | ||
Riga 142: | Riga 140: | ||
<FONT Color=gray>' ''Calcola la durata temporale della traccia audio da eseguire:''</font> | <FONT Color=gray>' ''Calcola la durata temporale della traccia audio da eseguire:''</font> | ||
Print "\n\e[0mEsecuzione audio della traccia n. "; ts & | Print "\n\e[0mEsecuzione audio della traccia n. "; ts & | ||
− | " - Durata: " & CStr( | + | " - Durata: " & CStr(Time(0, 0, 0, (sec2 - sec1) * 1000)) |
Print | Print | ||
Riga 165: | Riga 163: | ||
<FONT Color=gray>' ''I due valori del ciclo "For" sono espressi in secondi.'' | <FONT Color=gray>' ''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; | + | ' ''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.'' | ' ''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.''</font> | ' ''Tale valore viene comunque ridotto di un'unità per garantire che non si eseguano i primi dati audio di tale traccia successiva.''</font> | ||
Riga 181: | Riga 178: | ||
<FONT Color=gray>' ''Il secondo parametro potrà anche essere: buf.Data + (frame * CD_FRAMESIZE_RAW)''</font> | <FONT Color=gray>' ''Il secondo parametro potrà anche essere: buf.Data + (frame * CD_FRAMESIZE_RAW)''</font> | ||
somma += snd_pcm_writei(handle, Pointer@(buffer + 16) + (frame * CD_FRAMESIZE_RAW), CD_FRAMESIZE_RAW / 4) | somma += snd_pcm_writei(handle, Pointer@(buffer + 16) + (frame * CD_FRAMESIZE_RAW), CD_FRAMESIZE_RAW / 4) | ||
− | Write "\rTempo trascorso: " & | + | Write "\rTempo trascorso: " & Time(0, 0, 0, (somma / 44100) * 1000) |
Next | Next | ||
Next | Next | ||
Riga 195: | Riga 192: | ||
If err == 0 Then Print "\nChiusura dell'interfaccia PCM: regolare." | 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_track = t | ||
Riga 204: | Riga 201: | ||
ioctl_TOC(fd, CDROMREADTOCENTRY, ent) | ioctl_TOC(fd, CDROMREADTOCENTRY, ent) | ||
− | + | End |
Versione attuale delle 16:48, 4 lug 2024
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.0.0" 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 ' 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: "; Time(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, Time(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 " \e[34mInserire il numero della traccia audio da eseguire... \e[1m\e[31m" Flush ' 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(Time(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: " & Time(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