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 137: | Riga 137: | ||
Write #st, buf.Data As Pointer | Write #st, buf.Data As Pointer | ||
− | <FONT Color=gray>' ''I due valori 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 dall'inizio dei dati 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 | + | ' ''ovvero dall'inizio dell'audio sino alla fine della traccia, precedente a quella che deve essere eseguita, + 2 secondi senza dati.'' |
− | For i = sec1 To sec2 | + | ' ''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 della traccia successiva a quella prescelta.''</font> | ||
+ | For i = sec1 To (sec2 - 1) | ||
m = Fix(i / 60) | m = Fix(i / 60) | ||
s = i Mod 60 | s = i Mod 60 |
Versione delle 17:01, 4 ago 2019
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.
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 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" 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 toc As New Cdrom_tocentry Dim trc, m, s As Byte Dim sec1, sec2 As Short Dim ts As String Dim i, 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 !") ioctl_HDR(fl.Handle, CDROMREADTOCHDR, hdr) Print "Numero Tracce audio presenti: "; hdr.cdth_trk1 ' Chiede che sia immesso nello spazio della console il numero della traccia audio da eseguire: Write #File.Out, "Inserire il numero della traccia audio da eseguire... \e[1m\e[31m" Flush #File.Out ' Dopo aver scritto il numero della traccia da eseguire, va premuto il tasto "Invio": Input ts trc = CByte(Val(ts)) Tempo(fl.Handle, trc, toc) sec1 = (toc.minute * 60) + toc.second ' Se è impostata l'ultima traccia, il valore di "trc" deve essere = &hAA (170), per ottenere la marcatura temporale ' della fine di tale traccia (qui si sottrae di un'unità, poiché nella chiamata di funzione il valore del 2° parametro è incrementato): If trc == hdr.cdth_trk1 Then trc = &AA - 1 Tempo(fl.Handle, trc + 1, toc) sec2 = (toc.minute * 60) + toc.second 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 della traccia successiva a quella prescelta. 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