source: roaraudio/libroar/file.c @ 217:48dcd8412a44

Last change on this file since 217:48dcd8412a44 was 217:48dcd8412a44, checked in by phi, 16 years ago

set TCP_CORK while sending large blocks of data via TCP

File size: 2.2 KB
Line 
1//file.c:
2
3#include "libroar.h"
4
5#define BUFSIZE 8192
6#define BUFMAX  65536
7
8int roar_file_codecdetect(char * buf, int len) {
9 int codec = -1;
10
11 if ( len > 3 ) {
12  if ( strncmp(buf, "OggS", 4) == 0 ) {
13   codec = ROAR_CODEC_OGG_GENERAL;
14   if ( len > 34 ) { // this is 7 bytes after the end of the header
15    if ( strncmp(buf+28, "\001vorbis", 7) == 0 )
16     codec = ROAR_CODEC_OGG_VORBIS;
17   }
18  }
19 }
20
21 return codec;
22}
23
24ssize_t roar_file_send_raw (int out, int in) {
25 ssize_t r = 0;
26 ssize_t ret;
27 int len;
28 char buf[BUFSIZE];
29#ifdef __linux__
30 int cork_new = 1, cork_old;
31 socklen_t cork_len = sizeof(int);
32
33 getsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, &cork_len);
34 setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_new, sizeof(int));
35#endif
36
37#ifdef ROAR_HAVE_LINUX_SENDFILE
38 while ((ret = sendfile(out, in, NULL, BUFMAX)) > 0)
39  r += ret;
40#endif
41
42 // TODO: try mmap here!
43
44 while ((len = read(in, buf, BUFSIZE)) > 0)
45  r += write(out, buf, len);
46
47#ifdef __linux__
48 setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, cork_len);
49#endif
50 return r;
51}
52
53ssize_t roar_file_play (struct roar_connection * con, char * file, int exec) {
54 int codec = -1;
55 int in, out = -1;
56 struct roar_stream s;
57 ssize_t r = 0;
58 int len;
59 char buf[BUFSIZE];
60 int rate = ROAR_RATE_DEFAULT, channels = ROAR_CHANNELS_DEFAULT, bits = ROAR_BITS_DEFAULT;
61
62 if ( !con )
63  return -1;
64
65 if ( !file )
66  return -1;
67
68 if ( (in = open(file, O_RDONLY, 0644)) == -1 ) {
69  return -1;
70 }
71
72 if ((len = read(in, buf, BUFSIZE)) < 1) {
73  close(in);
74  return -1;
75 }
76
77 codec = roar_file_codecdetect(buf, len);
78
79 if ( codec == -1 ) {
80  close(in);
81  return -1;
82 }
83
84 if ( exec ) {
85  if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) {
86   close(in);
87   return -1;
88  }
89
90  if ( roar_stream_connect(con, &s, ROAR_DIR_PLAY) == -1 ) {
91   close(in);
92   return -1;
93  }
94
95  if ( roar_stream_exec(con, &s) == -1 ) {
96   close(in);
97   return -1;
98  }
99
100  shutdown(con->fh, SHUT_RD);
101
102  out = con->fh;
103 } else {
104  if ( (out = roar_simple_new_stream(con, rate, channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) {
105   close(in);
106   return -1;
107  }
108 }
109
110 write(out, buf, len);
111
112 r = roar_file_send_raw(out, in);
113
114 close(out);
115
116 if ( exec ) {
117  con->fh = -1;
118 }
119
120 close(in);
121
122 return r;
123}
124
125//ll
Note: See TracBrowser for help on using the repository browser.