source: roaraudio/libroar/file.c @ 563:3fe83012ebc6

Last change on this file since 563:3fe83012ebc6 was 563:3fe83012ebc6, checked in by phi, 16 years ago

added support for RIFF/WAVE

File size: 2.5 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  } else if ( strncmp(buf, "MThd", 4) == 0 ) {
19   codec = ROAR_CODEC_MIDI_FILE;
20  } else if ( strncmp(buf, "RIFF", 4) == 0 ) {
21   if ( len > 15 ) {
22    if ( strncmp(buf+8, "WAVEfmt ", 8) == 0 )
23     codec = ROAR_CODEC_RIFF_WAVE;
24   }
25  }
26 }
27
28 return codec;
29}
30
31ssize_t roar_file_send_raw (int out, int in) {
32 ssize_t r = 0;
33 ssize_t ret;
34 int len;
35 char buf[BUFSIZE];
36#ifdef __linux__
37 int cork_new = 1, cork_old;
38 socklen_t cork_len = sizeof(int);
39
40 if ( getsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, &cork_len) == -1 ) {
41  cork_old = -1;
42 } else {
43  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_new, sizeof(int));
44 }
45#endif
46
47#ifdef ROAR_HAVE_LINUX_SENDFILE
48 while ((ret = sendfile(out, in, NULL, BUFMAX)) > 0)
49  r += ret;
50#endif
51
52 // TODO: try mmap here!
53
54 while ((len = read(in, buf, BUFSIZE)) > 0)
55  r += write(out, buf, len);
56
57#ifdef __linux__
58 if ( cork_old != -1 )
59  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, cork_len);
60#endif
61 return r;
62}
63
64ssize_t roar_file_play (struct roar_connection * con, char * file, int exec) {
65 int codec = -1;
66 int in, out = -1;
67 struct roar_stream s;
68 ssize_t r = 0;
69 int len;
70 char buf[BUFSIZE];
71 int rate = ROAR_RATE_DEFAULT, channels = ROAR_CHANNELS_DEFAULT, bits = ROAR_BITS_DEFAULT;
72
73 if ( !con )
74  return -1;
75
76 if ( !file )
77  return -1;
78
79 if ( (in = open(file, O_RDONLY, 0644)) == -1 ) {
80  return -1;
81 }
82
83 if ((len = read(in, buf, BUFSIZE)) < 1) {
84  close(in);
85  return -1;
86 }
87
88 codec = roar_file_codecdetect(buf, len);
89
90 if ( codec == -1 ) {
91  close(in);
92  return -1;
93 }
94
95 if ( exec ) {
96  if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) {
97   close(in);
98   return -1;
99  }
100
101  if ( roar_stream_connect(con, &s, ROAR_DIR_PLAY) == -1 ) {
102   close(in);
103   return -1;
104  }
105
106  if ( roar_stream_exec(con, &s) == -1 ) {
107   close(in);
108   return -1;
109  }
110
111  shutdown(con->fh, SHUT_RD);
112
113  out = con->fh;
114 } else {
115  if ( (out = roar_simple_new_stream(con, rate, channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) {
116   close(in);
117   return -1;
118  }
119 }
120
121 write(out, buf, len);
122
123 r = roar_file_send_raw(out, in);
124
125 close(out);
126
127 if ( exec ) {
128  con->fh = -1;
129 }
130
131 close(in);
132
133 return r;
134}
135
136//ll
Note: See TracBrowser for help on using the repository browser.