2011-07-27 14 views
5

Quiero escribir un controlador de tarjeta de sonido virtual que debe ser utilizado por el sistema linux para la reproducción y captura de audio. El controlador usará un buffer para lectura/escritura de datos de audio. He escrito el siguiente controlador básico:Registrar un controlador de tarjeta de sonido en Linux

#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/sound.h> 

#include <linux/sysctl.h> 
#include <linux/device.h> 

#include <linux/slab.h> /* kmalloc() */ 
#include <linux/gfp.h> 
#include <asm/uaccess.h> /* copy_from/to_user */ 
#include <linux/major.h> 
#include <linux/fs.h> 
#include <linux/pci.h> 
#include <linux/err.h> 

#include <sound/core.h> 

static char* mod_name = "prosip"; 

MODULE_LICENSE("GPL"); 
MODULE_VERSION("0.0.1111"); 
MODULE_AUTHOR("DD-DDD"); 
MODULE_DESCRIPTION("proSip Virtual Sound Card"); 

// 
static int ver_major = 133; 

static int ver_minor = 3; 

// 
static int buffer_size = 0; 
static char* buffer; 
static int read_count = 0; 

/* Declaration of memory.c functions */ 
int prosip_open(struct inode *inode, struct file *filp); 
int prosip_release(struct inode *inode, struct file *filp); 

// 
ssize_t prosip_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 
ssize_t prosip_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos); 

// 
int prosip_ioctl(struct inode *inode,struct file *file,unsigned int ioctl_num,unsigned long ioctl_param); 

// 
static int __init prosip_init(void); 
static void __exit prosip_exit(void); 

/* Structure that declares the usual file access functions */ 
struct file_operations sound_fops = 
{ 
owner: 
    THIS_MODULE, 
read: 
    prosip_read, 
write: 
    prosip_write, 
open: 
    prosip_open, 
release: 
    prosip_release, 
ioctl: 
    prosip_ioctl 
}; 


/* Declaration of the init and exit functions */ 
module_init(prosip_init); 
module_exit(prosip_exit); 

static int __init prosip_init(void) 
{ 
    int ret = -1; 
    buffer_size = 0; 

    printk("<1>[prosip] Init...!\n"); 

    ret = register_sound_dsp(&sound_fops, ver_minor); 

    if(ret < 0) 
    { 
     printk("<1> [prosip] Registration failure\n"); 
     // 
     return ret; 
    } 
    else 
    { 
     ver_minor = ret; 
     // 
     printk("<1> [prosip] DSP Registered succesfully with id %d\n", ret); 
    } 

    buffer = kmalloc(101, GFP_KERNEL); 

    if(buffer == 0) 
    { 
     printk("<1>[prosip] Failed to allocate buffer !!!\n"); 
     // 
     return -ENOMEM; 
    } 

    // 
    return 0; 
} 

static void __exit prosip_exit(void) 
{ 
    printk("<1> [prosip] Sound Exit...\n"); 

    unregister_sound_special(ver_minor); 

    if(buffer) 
    { 
     kfree(buffer); 
    } 

} 

/* Declaration of memory.c functions */ 
int prosip_open(struct inode *inode, struct file *filp) 
{ 
    printk("<1> [prosip] Sound Open... \n"); 

    try_module_get(THIS_MODULE); 

    return 0; 
} 

// 
int prosip_release(struct inode *inode, struct file *filp) 
{ 
    printk("<1> [MySound] Sound Release... \n"); 

    module_put(THIS_MODULE); 

    return 0; 
} 

// 
ssize_t prosip_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 
{ 
    printk("<1> [prosip] Sound read...\n"); 
    printk("<1> [prosip] Writing Count: %d\n", count); 

    if(buffer == 0) 
    { 
     printk("<1> NULL buffer!!! Unable to read"); 
     return 0; 
    } 

    // 
    count = buffer_size; 

    if(read_count == 0) 
    { 
     read_count = buffer_size; 
    } 
    else 
    { 
     read_count = 0; 
    } 

    copy_to_user(buf, buffer, buffer_size); 

    printk("<1> [prosip] Buffer: %s, buf: %s, Count: %d\n", buffer, buf, count); 

    return read_count; 
} 

// 
ssize_t prosip_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 
{ 
    printk("<1> [prosip] Sound write...!\n"); 
    printk("<1> [prosip] Writing Count: %d\n", count); 

    // 
    if(buffer == 0) 
    { 
     printk("<1> NULL buffer!!! Unable to write"); 

     return 0; 
    } 

    copy_from_user(buffer, buf, count); 

    buffer[count] = 0; 
    buffer_size = count; 

    printk("<1> [MySound] Writing Buffer: %s, Count: %d\n", buffer, count); 

    return count; 
} 

/* 
* This function is called whenever a process tries to do an ioctl on our 
* device file. 
* 
*/ 
int prosip_ioctl(struct inode *inode, 
       struct file *file, 
       unsigned int ioctl_num, 
       unsigned long ioctl_param) 
{ 
    // 
    return 0; 
} 

insmod ing este módulo crea un conductor en /dev/dsp. También se encuentra en /sys/devices/virtual/sound/dsp/, por lo que el sistema lo reconoce como un controlador de audio virtual.

Todavía no puedo elegir este dispositivo para reproducir y capturar aplicaciones. ¿Qué más tengo que hacer para que este controlador sea enumerado por las aplicaciones de audio?

+0

Creo que implementa un hardware falso por un controlador de kernel debería ser posible e independiente de alsa o OSS. Implementos para alsa no tiene sentido para mí. Por yo tampoco sé cómo hacerlo. – deFreitas

Respuesta

1

El pozo /dev/dsp era el nodo del dispositivo utilizado para una tarjeta de sonido con el antiguo sistema de sonido OSS en Linux, pero en estos días prácticamente todo buscará dispositivos basados ​​en el nuevo sistema de sonido ALSA.

Algunos softwares todavía soportan OSS pero es posible que necesite darle opciones especiales, o cambiar la configuración, para decirle que use OSS en lugar de ALSA.

Los dispositivos ALSA se encuentran en /dev/snd y normalmente no se accede directamente, ya que son más complicados que los antiguos dispositivos OSS. En cambio, libasound se usa normalmente para interactuar con ellos.

+2

Gracias por su respuesta. De hecho, he leído la guía para escribir el controlador de dispositivo en ALSA. Pero este controlador debe estar conectado a ALSA y no puedo acceder al controlador ** directamente ** desde el sistema sin usar 'libasound'. ¿Hay alguna forma de escribir un controlador virtual usando la API ALSA a la que se puede acceder directamente? – Khaled

+0

Pero si escribo un controlador de dispositivo Linux (¿quién habla con el hardware) entonces tengo que adaptarlo a alsa? ¿Alsa no necesita identificar mi tarjeta de sonido falsa y trabajar con ella? – deFreitas

Cuestiones relacionadas