~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmidi/bag.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
    bag -- A quick hack to buffer audio data between TiMidity and an
 
4
           external player program.
 
5
 
 
6
    This program is in the Public Domain. It is distributed without
 
7
    much hope that it will be useful, and WITHOUT ANY WARRANTY;
 
8
    definitely without any implied warranty of MERCHANTABILITY or
 
9
    FITNESS FOR ANY PURPOSE.
 
10
 
 
11
    bag may enable you to play complex files at higher output rates,
 
12
    but it's a bit of a pain to use.
 
13
 
 
14
    Here's a usage example for Linux. splay is a program that (with
 
15
    this invocation) plays audio data from stdin. Your flag
 
16
    requirements may vary.
 
17
 
 
18
                timidity -id -Or1lsS -o- -s22 -p48 filenames |
 
19
                bag -b 2M -t 1M -c 4k |
 
20
                splay -b16 -s22 -S
 
21
 
 
22
*/
 
23
 
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include <limits.h>
 
28
#include <sys/time.h>
 
29
#include <sys/types.h>
 
30
#include <unistd.h>
 
31
#include <errno.h>
 
32
 
 
33
static int bytes(char *s)
 
34
{
 
35
  int i;
 
36
  i=atoi(s);
 
37
  while (*s>='0' && *s<='9')
 
38
    s++;
 
39
 
 
40
  switch(*s)
 
41
    {
 
42
    case 'm':
 
43
    case 'M':
 
44
      i *= 1024;
 
45
    case 'k':
 
46
    case 'K':
 
47
      i *= 1024;
 
48
    }
 
49
  return i;
 
50
}
 
51
 
 
52
int main(int argc, char **argv)
 
53
{
 
54
  int bs=1024*1024, rs=4*1024, ws=4*1024, cs=4*1024, thresh=64*1024;
 
55
  int c, junk=0, verbosity=0, flush_and_go=0;
 
56
  char *bag, *head, *tail;
 
57
  extern char *optarg; /* for Sun's gcc */
 
58
 
 
59
  fd_set readfds, writefds, brokefds;
 
60
  struct timeval tmo;
 
61
 
 
62
  while ((c=getopt(argc, argv, "b:t:r:w:c:hv"))>0)
 
63
    switch(c)
 
64
      {
 
65
      case 'b': bs=bytes(optarg); break;
 
66
      case 't': thresh=bytes(optarg); break;
 
67
      case 'r': rs=bytes(optarg); break;
 
68
      case 'w': ws=bytes(optarg); break;
 
69
      case 'c': rs=ws=bytes(optarg); break;
 
70
      case 'v': verbosity++; break;
 
71
      case '?':
 
72
      case 'h':
 
73
        printf("\nBag usage:\n\n"
 
74
               "  timidity -id -Or[format options] -o- [options and filenames] |\n"
 
75
               "  bag [bag options] | audio_player [player options]\n\n"
 
76
               "Bag options:\n\n"
 
77
               "  -b size    Set buffer size (default %d)\n"
 
78
               "  -r size    Set read chunk size (default %d)\n"
 
79
               "  -w size    Set write chunk size (default %d)\n"
 
80
               "  -c size    Set read/write chunk size\n"
 
81
               "  -t size    Set start threshold for writing (default %d)\n"
 
82
               "  -v         Verbose mode\n"
 
83
               "  -h         This help screen\n\n"
 
84
               ,bs,rs,ws,thresh);
 
85
        return 0;
 
86
      }
 
87
 
 
88
  if (ws>rs) cs=ws;
 
89
  else cs=rs;
 
90
  if (bs < ws+rs)
 
91
    {
 
92
      bs=ws+rs;
 
93
      fprintf(stderr, "bag: Buffer size increased to %d bytes\n", bs);
 
94
    }
 
95
  if (thresh > (bs-rs))
 
96
    {
 
97
      thresh=bs-rs;
 
98
      fprintf(stderr, "bag: Threshold lowered to %d bytes\n", bs);
 
99
    }
 
100
 
 
101
  head=tail=bag=malloc(bs);
 
102
  junk=0;
 
103
  while (!flush_and_go)
 
104
    {
 
105
      FD_ZERO(&readfds);
 
106
      FD_ZERO(&writefds);
 
107
      FD_ZERO(&brokefds);
 
108
 
 
109
      if (junk<(bs-rs))
 
110
        FD_SET(STDIN_FILENO, &readfds);
 
111
 
 
112
      if (junk>ws && junk>thresh)
 
113
        {
 
114
          FD_SET(STDOUT_FILENO, &writefds);
 
115
          thresh=0;
 
116
        }
 
117
      
 
118
      FD_SET(STDIN_FILENO, &brokefds);
 
119
      FD_SET(STDOUT_FILENO, &brokefds);
 
120
      
 
121
      tmo.tv_sec=1;
 
122
      tmo.tv_usec=0;
 
123
#ifdef HPUX
 
124
      if ((c=select(FD_SETSIZE,(int *) &readfds,(int *) &writefds, (int *) &brokefds, &tmo))<0)
 
125
#else
 
126
      if ((c=select(FD_SETSIZE, &readfds, &writefds, &brokefds, &tmo))<0)
 
127
#endif
 
128
        perror("\nbag: select");
 
129
 
 
130
      if (verbosity)
 
131
        fprintf(stderr, "\rbag: %8d bytes", junk);
 
132
 
 
133
      if (FD_ISSET(STDOUT_FILENO, &brokefds))
 
134
        {
 
135
          fprintf(stderr, "\nbag: Elvis has left the building\n");
 
136
          return 1;
 
137
        }
 
138
 
 
139
      if (FD_ISSET(STDIN_FILENO, &readfds))
 
140
        {
 
141
          if ((c=read(STDIN_FILENO, head, 
 
142
                      (head+rs >= bag+bs) ? (bag+bs-head) : rs))<=0)
 
143
            {
 
144
              if (c==0 || errno!=EAGAIN)
 
145
                flush_and_go=1;
 
146
            }
 
147
          else
 
148
            {
 
149
              junk+=c;
 
150
              head+=c;
 
151
              if (head>=bag+bs)
 
152
                head-=bs;
 
153
            }
 
154
        }
 
155
      else if (FD_ISSET(STDIN_FILENO, &brokefds))
 
156
        flush_and_go=1;
 
157
 
 
158
      if (flush_and_go || FD_ISSET(STDOUT_FILENO, &writefds))
 
159
        do
 
160
          {
 
161
            c=(tail+ws >= bag+bs) ? (bag+bs-tail) : ws;
 
162
            if (c>junk) c=junk;
 
163
            
 
164
            if (flush_and_go && verbosity)
 
165
              fprintf(stderr, "\rbag: Flushing, %8d bytes", junk);
 
166
            
 
167
            c=write(STDOUT_FILENO, tail, c);
 
168
            junk -= c;
 
169
            tail += c;
 
170
            if (tail>=bag+bs)
 
171
              tail-=bs;
 
172
          } while (flush_and_go && junk);
 
173
    }
 
174
  if (verbosity)
 
175
    fprintf(stderr, "\nbag: All done\n");
 
176
  return 0;
 
177
}