[RoLUG] GSleep 1.1 is out

Eduard Roccatello eduard@box.it
Ven 19 Set 2003 19:18:28 CEST


On Friday 19 September 2003 02:01, Enrico Marchetto wrote:
> domanda... Per usare il mio prog (o il tuo eddy...) bisogna attaccare
> qualcosa direttamente al lettore, perchè la sk audio è del tutto tagliata
> fuori. Esite la ioctl CDROMREADAUDIO, ma come si fa a "mandare" i byte
> alla sk audio? Che librerie/funzioni/quant'altro si possono usare? Io ho
> una SB 64 pci (no alsa... solito modulo es1371!), e mi basterebbe che
> funzionasse quella...
ti ringrazio per apprezzare il mio lavoro, cosa che non viene fatta da tutti 
ma e` la vita.
ioctl si occupa di controllare un device sotto linux e per farlo utilizza 
delle chiamate definite negli include del kernel.
quelle che riguardano la scheda audio si trovano in questo file
[kerneltree]/include/linux/soundcard.h

ioctl ha bisogno di un file descriptor, della definizione specifica per il 
device e di un parametro variabile (di solito un puntatore ad una 
struttura).
ti spiego con frammenti di codice che funzionano meglio delle mie parole 
ultimamente.

tu vuoi riprodurre qualcosa sulla scheda audio (/dev/dsp) e hai un file 
audio.wav nella stessa cartella dell'eseguibile

questo codice fa esattamente quello che vuoi:

[CODICE]
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/soundcard.h>

int main (void) {
	int cardFd, wavFd, formato, stereo, speed;
	char buffer[128];
	
	/* Apro il file in sola lettura */
	if ((wavFd = open("./audio.wav", O_RDONLY)) < 0) {
		perror("Apertura File");
		exit(-1);
	}

	/* Apro la scheda audio in sola scrittura */
	if ((cardFd = open("/dev/dsp", O_WRONLY)) < 0) {
		perror("Apertura Scheda");
		exit(-1);
	}

	/* AFMT_S16_LE 0x00000010 Little endian signed 16 */	
	formato = AFMT_S16_LE;
	stereo = 1;
	speed = 44100;

	/* Imposto il formato */
	if (ioctl(cardFd, SNDCTL_DSP_SETFMT, &formato)==-1) {
		perror("Formato");
		exit(-1);
	}
	/* Imposto la modalita` stereo */
	if (ioctl(cardFd, SNDCTL_DSP_STEREO, &stereo)==-1) {
		perror("Stereo");
		exit(-1);
	}
	/* Imposto il data rate a 44100 */
	if (ioctl(cardFd, SNDCTL_DSP_SPEED, &speed)==-1) {
		perror("Speed");
		exit(-1);
	}

	/* Salto l'header del file (non ci interessa per ora) "/
	lseek(wavFd, 40, 0);

	/* Leggo il file e lo scrivo sulla scheda audio */
	while (read(wavFd, buffer, sizeof(buffer)) != 0)
		write(cardFd, buffer, sizeof(buffer));

	/* Resetto la scheda audio e chiudo i file descriptor */
	ioctl(cardFd, SNDCTL_DSP_RESET, 0);
	close(cardFd);
	close(wavFd);
	return 0;
}
[/CODICE]

Ovviamente funziona perche i file wav PCM hanno lo stream non compresso 
direttamente nel file dopo un header di 40 byte.
Con i formati bisogna decodificare e dare in pasto alla scheda audio.

-- 
Eduard <Master^Shadow> Roccatello

Pcimprover.it Admin - http://www.pcimprover.it
S.P.I.N.E. Group - http://www.spine-group.org



Maggiori informazioni sulla lista RoLUG