Compare commits
2 Commits
941cae8042
...
7d45dde84e
Author | SHA1 | Date |
---|---|---|
Preston Baxter | 7d45dde84e | |
Preston Baxter | 69e26d6a55 |
|
@ -6,3 +6,4 @@
|
||||||
*.mod.c
|
*.mod.c
|
||||||
*.symvers
|
*.symvers
|
||||||
*.cache
|
*.cache
|
||||||
|
*.o.d
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ obj-m += aes67.o
|
||||||
CC=gcc
|
CC=gcc
|
||||||
KERN_DIR=/lib/modules/$(shell uname -r)/build/
|
KERN_DIR=/lib/modules/$(shell uname -r)/build/
|
||||||
|
|
||||||
host:
|
default:
|
||||||
$(MAKE) -C $(KERN_DIR) M=$$PWD modules
|
$(MAKE) -C $(KERN_DIR) M=$$PWD modules
|
||||||
clean:
|
clean:
|
||||||
make -C $(KERN_DIR) M=$(PWD) clean
|
make -C $(KERN_DIR) M=$(PWD) clean
|
||||||
|
|
95
aes67.c
95
aes67.c
|
@ -4,9 +4,14 @@
|
||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/socket.h>
|
||||||
|
#include <linux/net.h>
|
||||||
|
#include <linux/in.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <net/net_namespace.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/initval.h>
|
#include <sound/initval.h>
|
||||||
|
@ -21,6 +26,8 @@ static struct platform_device *devices[SNDRV_CARDS];
|
||||||
|
|
||||||
#define CARD_NAME "AES67 Virtual Soundcard"
|
#define CARD_NAME "AES67 Virtual Soundcard"
|
||||||
|
|
||||||
|
#define AES67_NET_SUCCESS 0
|
||||||
|
|
||||||
module_param_array(index, int, NULL, 0444);
|
module_param_array(index, int, NULL, 0444);
|
||||||
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
|
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
|
||||||
module_param_array(id, charp, NULL, 0444);
|
module_param_array(id, charp, NULL, 0444);
|
||||||
|
@ -38,9 +45,17 @@ MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/* Definistion of AES67 Virtual SoundCard */
|
/* Definistion of AES67 Virtual SoundCard */
|
||||||
struct aes67 {
|
struct aes67 {
|
||||||
|
/* ALSA Soundcard*/
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
|
/* PCM Device Soundcard*/
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
|
/* Linux Device */
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
/* Socket */
|
||||||
|
struct socket *socket;
|
||||||
|
|
||||||
|
/* Receiving Work Queue */
|
||||||
|
struct work_struct receive_work;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Forward declarations
|
//Forward declarations
|
||||||
|
@ -49,7 +64,16 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard);
|
||||||
/* Destructor */
|
/* Destructor */
|
||||||
static int snd_aes67_free(struct aes67 *virtcard)
|
static int snd_aes67_free(struct aes67 *virtcard)
|
||||||
{
|
{
|
||||||
|
/* free card */
|
||||||
|
snd_printk(KERN_INFO "Freeing Soundcard\n");
|
||||||
snd_card_free(virtcard->card);
|
snd_card_free(virtcard->card);
|
||||||
|
|
||||||
|
/* free socket */
|
||||||
|
if (virtcard->socket) {
|
||||||
|
snd_printk(KERN_INFO "Freeing Socket\n");
|
||||||
|
sock_release(virtcard->socket);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(virtcard);
|
kfree(virtcard);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +115,27 @@ static int snd_aes67_create(struct snd_card *card, struct aes67 **rvirtcard)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create socket */
|
||||||
|
err = sock_create_kern(&init_net, PF_INET, SOCK_DGRAM, IPPROTO_UDP,
|
||||||
|
&virtcard->socket);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_printk(KERN_ERR
|
||||||
|
"Failed to create socket for virtual soundcard\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr = { .sin_family = AF_INET,
|
||||||
|
.sin_port = htons(9375),
|
||||||
|
.sin_addr = { htonl(INADDR_LOOPBACK) } };
|
||||||
|
|
||||||
|
virtcard->socket->ops->bind(virtcard->socket, (struct sockaddr *)&addr,
|
||||||
|
sizeof(addr));
|
||||||
|
if (err < 0) {
|
||||||
|
snd_printk(KERN_ERR
|
||||||
|
"Failed to bind socket for virtual soundcard\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add PCM */
|
/* Add PCM */
|
||||||
err = snd_aes67_new_pcm(virtcard);
|
err = snd_aes67_new_pcm(virtcard);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -99,7 +144,6 @@ static int snd_aes67_create(struct snd_card *card, struct aes67 **rvirtcard)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
snd_printk(KERN_INFO "Successfully created AES67\n");
|
snd_printk(KERN_INFO "Successfully created AES67\n");
|
||||||
*rvirtcard = virtcard;
|
*rvirtcard = virtcard;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -150,6 +194,39 @@ error:
|
||||||
snd_card_free(card);
|
snd_card_free(card);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
/* Network functions */
|
||||||
|
|
||||||
|
static void aes67_rx_net(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct aes67 *virtcard = container_of(work, struct aes67, receive_work);
|
||||||
|
struct kvec iv;
|
||||||
|
struct msghdr msg = {};
|
||||||
|
size_t recv_buf_size = 4096;
|
||||||
|
int ret, buflen;
|
||||||
|
void *recv_buf;
|
||||||
|
/* Read lock socket */
|
||||||
|
|
||||||
|
/* Loop Receive */
|
||||||
|
recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);
|
||||||
|
if (!recv_buf) {
|
||||||
|
snd_printk(KERN_ERR
|
||||||
|
"Failed to allocate network receive buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
iv.iov_base = recv_buf;
|
||||||
|
iv.iov_len = recv_buf_size;
|
||||||
|
|
||||||
|
msglen = kernel_recvmsg(virtcard->socket, &msg, &iv, 1, iv.iov_len, MSG_DONTWAIT);
|
||||||
|
|
||||||
|
} while (ret == AES67_NET_SUCCESS);
|
||||||
|
|
||||||
|
/* Handle stream end */
|
||||||
|
snd_printk(KERN_INFO "Finished Receiving work queue\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* PCM Shenaniagians */
|
/* PCM Shenaniagians */
|
||||||
/* Playback definition */
|
/* Playback definition */
|
||||||
|
@ -243,9 +320,13 @@ static int snd_aes67_pcm_prepare(struct snd_pcm_substream *substream)
|
||||||
|
|
||||||
static int snd_aes67_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
static int snd_aes67_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||||
{
|
{
|
||||||
|
struct aes67 *chip = snd_pcm_substream_chip(substream);
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
/* do something to start the PCM engine */
|
INIT_WORK(&chip->receive_work, aes67_rx_net);
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
/* do something to stop the PCM engine */
|
/* do something to stop the PCM engine */
|
||||||
|
@ -303,7 +384,8 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard)
|
||||||
snd_printk(KERN_INFO "Initializing PCM for Virtual Soundcard");
|
snd_printk(KERN_INFO "Initializing PCM for Virtual Soundcard");
|
||||||
err = snd_pcm_new(virtcard->card, CARD_NAME, 0, 1, 1, &pcm);
|
err = snd_pcm_new(virtcard->card, CARD_NAME, 0, 1, 1, &pcm);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
snd_printk(KERN_INFO "Failed initializing PCM for Virtual Soundcard");
|
snd_printk(KERN_INFO
|
||||||
|
"Failed initializing PCM for Virtual Soundcard");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,8 +401,8 @@ static int snd_aes67_new_pcm(struct aes67 *virtcard)
|
||||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_aes67_capture_ops);
|
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_aes67_capture_ops);
|
||||||
/*Da buffers*/
|
/*Da buffers*/
|
||||||
snd_printk(KERN_INFO "Settig PCM managed buffer");
|
snd_printk(KERN_INFO "Settig PCM managed buffer");
|
||||||
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DEV_LOWLEVEL, virtcard->dev, 64 * 1024,
|
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DEV_LOWLEVEL, virtcard->dev,
|
||||||
64 * 1024);
|
64 * 1024, 64 * 1024);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,5 +474,4 @@ static void __exit alsa_card_aes67_exit(void)
|
||||||
platform_driver_unregister(&snd_aes67_driver);
|
platform_driver_unregister(&snd_aes67_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(alsa_card_aes67_init)
|
module_init(alsa_card_aes67_init) module_exit(alsa_card_aes67_exit)
|
||||||
module_exit(alsa_card_aes67_exit)
|
|
||||||
|
|
Loading…
Reference in New Issue