History

Merge branch 'master' of https://github.com/duncanthrax/scream.git

duncanthrax committed 11 years ago

Commit 9aa660b2 parents 2a8d579 38f70a13 files · +86 −0Browse files

Unified · Split

3 files
  1. README.md +11 −0
  2. Receivers/pulseaudio/Makefile +4 −0
  3. Receivers/pulseaudio/scream-pulse.c +71 −0
README.md+11−0
@@ -0,0 +1,11 @@
1+Scream - Virtual network sound card for Microsoft Windows
2+--------------------------
3+
4+Scream is a virtual device driver for Windows that provides a
5+discrete sound device. Audio played through this device is
6+published on your local network as a PCM multicast stream.
7+
8+Receivers on the network can pick up the stream and play it
9+through their own audio outputs. A simple server for Linux
10+(interfacing with PulseAudio) is provided.
11+
Receivers/pulseaudio/Makefile+4−0
@@ -0,0 +1,4 @@
1+CC=gcc
2+
3+scream-pulse:
4+ $(CC) -o scream-pulse scream-pulse.c -lpulse-simple -lpulse
Receivers/pulseaudio/scream-pulse.c+71−0
@@ -0,0 +1,71 @@
1+#include <stdio.h>
2+#include <string.h>
3+#include <pulse/simple.h>
4+#include <pulse/error.h>
5+
6+#include <sys/socket.h>
7+#include <netinet/in.h>
8+
9+#define MULTICAST_TARGET "239.255.77.77"
10+#define MULTICAST_PORT 4010
11+#define MAX_SO_PACKETSIZE 1764
12+#define MIN_PA_PACKETSIZE MAX_SO_PACKETSIZE
13+#define BUFFER_SIZE MIN_PA_PACKETSIZE * 2
14+
15+int main(int argc, char*argv[]) {
16+ int sockfd, error;
17+ ssize_t n;
18+ int offset;
19+ struct sockaddr_in servaddr;
20+ struct ip_mreq imreq;
21+ pa_simple *s;
22+ pa_sample_spec ss;
23+ unsigned char buf[BUFFER_SIZE];
24+
25+ ss.format = PA_SAMPLE_S16NE;
26+ ss.channels = 2;
27+ ss.rate = 44100;
28+ s = pa_simple_new(NULL,
29+ "Scream",
30+ PA_STREAM_PLAYBACK,
31+ NULL,
32+ "Audio",
33+ &ss,
34+ NULL,
35+ NULL,
36+ NULL
37+ );
38+ if (!s) goto BAIL;
39+
40+ sockfd = socket(AF_INET,SOCK_DGRAM,0);
41+
42+ memset((void *)&servaddr, 0, sizeof(servaddr));
43+ servaddr.sin_family = AF_INET;
44+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
45+ servaddr.sin_port = htons(MULTICAST_PORT);
46+ bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
47+
48+ imreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_TARGET);
49+ imreq.imr_interface.s_addr = INADDR_ANY;
50+
51+ setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
52+ (const void *)&imreq, sizeof(struct ip_mreq));
53+
54+ offset = 0;
55+ for (;;) {
56+ n = recvfrom(sockfd, &buf[offset], MAX_SO_PACKETSIZE, 0, NULL, 0);
57+ if (n > 0) {
58+ offset += n;
59+ if (offset >= MIN_PA_PACKETSIZE) {
60+ if (pa_simple_write(s, buf, offset, &error) < 0) {
61+ printf("pa_simple_write() failed: %s\n", pa_strerror(error));
62+ goto BAIL;
63+ }
64+ offset = 0;
65+ }
66+ }
67+ }
68+
69+ BAIL:
70+ if (s) pa_simple_free(s);
71+};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t