OSDN Git Service

Imported UnkoTim211
[timidity41/timidity41.git] / timidity / aq.c
1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20     aq.c - Audio queue.
21               Written by Masanao Izumo <mo@goice.co.jp>
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif /* HAVE_CONFIG_H */
27
28 #ifdef __POCC__
29 #include <sys/types.h>
30 #endif //for off_t
31 #include <stdio.h>
32 #include <stdlib.h>
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif /* HAVE_UNISTD_H */
36
37 #ifndef NO_STRING_H
38 #include <string.h>
39 #else
40 #include <strings.h>
41 #endif
42
43 #include "timidity.h"
44 #include "common.h"
45 #include "output.h"
46 #include "aq.h"
47 #include "timer.h"
48 #include "controls.h"
49 #include "miditrace.h"
50 #include "instrum.h"
51 #include "playmidi.h"
52
53
54 #define TEST_SPARE_RATE 0.9
55 #define MAX_BUCKET_TIME 0.5
56 ///r
57 #define MAX_FILLED_TIME 3000.0 // def 2.0
58
59
60 static int32 device_qsize;
61 ///r
62 static int32 Bps = 1;   /* Bytes per sample frame */
63 static int32 bucket_size;
64 static int32 nbuckets = 0;
65 static double bucket_time;
66 int32 aq_fill_buffer_flag = 0;
67 static int32 aq_start_count;
68 static int32 aq_add_count;
69
70 static int32 play_counter, play_offset_counter;
71 static double play_start_time;
72
73 typedef struct _AudioBucket
74 {
75     uint8 *data;
76     int32 len;
77     struct _AudioBucket *next;
78 } AudioBucket;
79
80 static AudioBucket *base_buckets = NULL;
81 static AudioBucket *allocated_bucket_list = NULL;
82 static AudioBucket *head = NULL;
83 static AudioBucket *tail = NULL;
84
85 static void alloc_soft_queue(void);
86 static void set_bucket_size(int32 size);
87 static int32 add_play_bucket(const uint8 *buf, int32 n);
88 static void reuse_audio_bucket(AudioBucket *bucket);
89 static AudioBucket *next_allocated_bucket(void);
90 static void flush_buckets(void);
91 static int32 aq_fill_one(void);
92 static void aq_wait_ticks(void);
93 static int32 estimate_queue_size(void);
94
95 /* effect.c */
96 extern void init_effect(void);
97 extern void do_effect(DATA_T *buf, int32 count);
98
99
100 ///r
101 int aq_calc_fragsize(void)
102 {
103     int bps, bs;
104     double dq, bt;
105
106         bps = get_encoding_sample_size(play_mode->encoding);
107     bs = audio_buffer_size * bps;
108     dq = play_mode->rate * MAX_FILLED_TIME * bps;
109     while(bs * 2 > dq)
110         bs /= 2;
111
112     bt = (double)bs / bps * div_playmode_rate;
113     while(bt > MAX_BUCKET_TIME)
114     {
115         bs /= 2;
116         bt = (double)bs / bps * div_playmode_rate;
117     }
118
119     return bs;
120 }
121 ///r
122 void aq_setup(void)
123 {
124     int32 frag_size;
125
126     /* Initialize Bps, bucket_size, device_qsize, and bucket_time */
127
128     Bps = get_encoding_sample_size(play_mode->encoding);
129     general_output_convert_setup();
130
131     if (play_mode->acntl(PM_REQ_GETFRAGSIZ, &frag_size) == -1)
132         frag_size = audio_buffer_size * Bps;
133     set_bucket_size(frag_size);
134     bucket_time = (double)bucket_size / Bps * div_playmode_rate;
135
136     if (IS_STREAM_TRACE)
137     {
138         if (play_mode->acntl(PM_REQ_GETQSIZ, &device_qsize) == -1)
139             device_qsize = estimate_queue_size();
140         if (bucket_size * 2 > device_qsize) {
141           ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
142                     "Warning: Audio buffer is too small.");
143           device_qsize = 0;
144         } else {
145           device_qsize -= device_qsize % Bps; /* Round Bps */
146           ctl->cmsg(CMSG_INFO, VERB_DEBUG,
147                     "Audio device queue size: %d bytes", device_qsize);
148           ctl->cmsg(CMSG_INFO, VERB_DEBUG,
149                     "Write bucket size: %d bytes (%d msec)",
150                     bucket_size, (int)(bucket_time * 1000 + 0.5));
151         }
152     }
153     else
154     {
155         device_qsize = 0;
156         free_soft_queue();
157         nbuckets = 0;
158     }
159
160     init_effect();
161     aq_add_count = 0;
162 }
163
164 void aq_set_soft_queue(double soft_buff_time, double fill_start_time)
165 {
166     static double last_soft_buff_time, last_fill_start_time;
167     int nb;
168
169     /* for re-initialize */
170     if(soft_buff_time < 0)
171         soft_buff_time = last_soft_buff_time;
172     if(fill_start_time < 0)
173         fill_start_time = last_fill_start_time;
174
175     nb = (int)(soft_buff_time / bucket_time);
176     if(nb == 0)
177                 aq_start_count = 0;
178     else
179                 aq_start_count = (int32)(fill_start_time * play_mode->rate);
180     aq_fill_buffer_flag = (aq_start_count > 0);
181
182     if(nbuckets != nb)
183     {
184                 nbuckets = nb;
185                 alloc_soft_queue();
186     }
187
188     last_soft_buff_time = soft_buff_time;
189     last_fill_start_time = fill_start_time;
190 }
191
192 /* Estimates the size of audio device queue.
193  * About sun audio, there are long-waiting if buffer of device audio is full.
194  * So it is impossible to completely estimate the size.
195  */
196 static int32 estimate_queue_size(void)
197 {
198     uint8 *nullsound;
199     double tb, init_time, chunktime;
200     int32 qbytes, max_qbytes;
201     int32 ntries;
202         
203 #ifdef ALIGN_SIZE
204     nullsound = (uint8*) aligned_malloc(bucket_size, ALIGN_SIZE);
205 #else
206     nullsound = (uint8*) safe_malloc(bucket_size);
207 #endif
208     memset(nullsound, 0, bucket_size);
209     if (play_mode->encoding & (PE_ULAW | PE_ALAW))
210         general_output_convert((DATA_T*)nullsound, bucket_size / Bps);
211     tb = play_mode->rate * Bps * TEST_SPARE_RATE;
212     ntries = 1;
213     max_qbytes = play_mode->rate * MAX_FILLED_TIME * Bps;
214
215   retry:
216     chunktime = (double)bucket_size / Bps * div_playmode_rate;
217     qbytes = 0;
218
219     init_time = get_current_calender_time();    /* Start */
220     for(;;)
221     {
222                 double start, diff;
223
224                 start = get_current_calender_time();
225                 if(start - init_time > 1.0) /* ?? */
226                 {
227                         ctl->cmsg(CMSG_WARNING, VERB_DEBUG,
228                                   "Warning: Audio test is terminated");
229                         break;
230                 }
231                 play_mode->output_data(nullsound, bucket_size);
232                 diff = get_current_calender_time() - start;
233 ///r
234                 if(diff > chunktime * DIV_2 || chunktime < diff)
235         //              if(qbytes > 1024*512) // ??
236                         break;
237                 qbytes += (int32)((chunktime - diff) * tb);
238
239                 if(qbytes > max_qbytes)
240                 {
241                         qbytes = max_qbytes;
242                         break;
243                 }
244     }
245     play_mode->acntl(PM_REQ_DISCARD, NULL);
246
247     if(bucket_size * 2 > qbytes)
248     {
249                 if(ntries == 4)
250                 {
251                         ctl->cmsg(CMSG_ERROR, VERB_NOISY,
252                                   "Can't estimate audio queue length");
253                         set_bucket_size(audio_buffer_size * Bps);
254                         free(nullsound);
255                         return 2 * audio_buffer_size * Bps;
256                 }
257
258                 ctl->cmsg(CMSG_WARNING, VERB_DEBUG,
259                           "Retry to estimate audio queue length (%d times)",
260                           ntries);
261                 set_bucket_size(divi_2(bucket_size));
262                 ntries++;
263                 goto retry;
264     }
265         
266 #ifdef ALIGN_SIZE
267     aligned_free(nullsound);
268 #else
269     free(nullsound);
270 #endif
271
272     return qbytes;
273 }
274
275 /* Send audio data to play_mode->output_data() */
276 static int aq_output_data(uint8 *buff, int nbytes)
277 {
278     int i;
279
280     play_counter += nbytes / Bps;
281
282     while(nbytes > 0)
283     {
284         i = nbytes;
285         if(i > bucket_size)
286             i = bucket_size;
287         if(play_mode->output_data(buff, i) == -1)
288             return -1;
289         nbytes -= i;
290         buff += i;
291     }
292
293     return 0;
294 }
295
296 extern void do_effect2(uint8 *buf, int32 count); // effect.c
297
298 int aq_add(DATA_T *samples, int32 count)
299 {
300     int32 nbytes, i;
301     uint8 *buff;
302
303         if(!(play_mode->flag & PF_PCM_STREAM))
304         return 0;
305
306     if(!count)
307     {
308                 if(!aq_fill_buffer_flag)
309                         return aq_fill_nonblocking();
310                 return 0;
311     }
312         
313         aq_add_count += count;
314     nbytes = general_output_convert(samples, count);
315     buff = (uint8 *)samples;
316     do_effect2(buff, count);
317
318     if(device_qsize == 0 || nbuckets == 0)
319       return play_mode->output_data(buff, nbytes);
320
321     aq_fill_buffer_flag = (aq_add_count <= aq_start_count);
322
323     if(!aq_fill_buffer_flag && aq_fill_nonblocking() == -1)
324             return -1;
325
326     if(!ctl->trace_playing)
327     {
328                 while((i = add_play_bucket(buff, nbytes)) < nbytes)
329                 {
330                         buff += i;
331                         nbytes -= i;
332                         if(head && head->len == bucket_size)
333                         {
334                                 if(aq_fill_one() == -1)
335                                         return -1;
336                         }
337                         aq_fill_buffer_flag = 0;
338                 }
339                 return 0;
340     }
341
342     trace_loop();
343     while((i = add_play_bucket(buff, nbytes)) < nbytes)
344     {
345         /* Software buffer is full.
346          * Write one bucket to audio device.
347          */
348                 buff += i;
349                 nbytes -= i;
350                 aq_wait_ticks();
351                 trace_loop();
352                 if(aq_fill_nonblocking() == -1)
353                         return -1;
354                 aq_fill_buffer_flag = 0;
355     }
356     return 0;
357 }
358
359 static void set_bucket_size(int32 size)
360 {
361 //    if (size == bucket_size)
362 //      return;
363     bucket_size = size;
364 //    if (nbuckets != 0)
365         alloc_soft_queue();
366 }
367
368 /* alloc_soft_queue() (re-)initializes audio buckets. */
369 static void alloc_soft_queue(void)
370 {
371     int i;
372     uint8 *base;
373         int32 nb = nbuckets > 1 ? nbuckets : 1;
374
375     free_soft_queue();
376 ///r def safe_malloc(
377     base_buckets = (AudioBucket*) safe_large_malloc(nb * sizeof(AudioBucket));
378     base = (uint8*) safe_large_malloc(nb * bucket_size);
379     base_buckets[0].len = 0;
380     base_buckets[0].next = 0;
381     for (i = 0; i < nb; i++)
382         base_buckets[i].data = base + i * bucket_size;
383     flush_buckets();
384 }
385
386 void free_soft_queue(void)
387 {
388     if(base_buckets)
389     {
390         free(base_buckets[0].data);
391         free(base_buckets);
392         base_buckets = NULL;
393     }
394 }
395
396 /* aq_fill_one() transfers one audio bucket to device. */
397 static int aq_fill_one(void)
398 {
399     AudioBucket *tmp;
400         
401     if (!head)
402         return 0;
403     if(aq_output_data(head->data, bucket_size) == -1)
404         return -1;
405     tmp = head;
406     head = head->next;
407     reuse_audio_bucket(tmp);
408     return 0;
409 }
410
411 /* aq_fill_nonblocking() transfers some audio buckets to device.
412  * This function is non-blocking.  But it is possible to block because
413  * of miss-estimated aq_fillable() calculation.
414  */
415 int aq_fill_nonblocking(void)
416 {
417     int32 i, nfills;
418     AudioBucket *tmp;
419
420     if(!head || head->len != bucket_size || !IS_STREAM_TRACE)
421                 return 0;
422
423     nfills = (aq_fillable() * Bps) / bucket_size;
424     for(i = 0; i < nfills; i++)
425     {
426                 if(!head || head->len != bucket_size)
427                         break;
428                 if(aq_output_data(head->data, bucket_size) == -1)
429                         return RC_ERROR;
430                 tmp = head;
431                 head = head->next;
432                 reuse_audio_bucket(tmp);
433     }
434     return 0;
435 }
436
437 int32 aq_samples(void)
438 {
439     double realtime, es;
440     int s;
441
442     if(play_mode->acntl(PM_REQ_GETSAMPLES, &s) != -1)
443     {
444         /* Reset counter & timer */
445                 if(play_counter)
446                 {
447                         play_start_time = get_current_calender_time();
448                         play_offset_counter = s;
449                         play_counter = 0;
450                 }
451                 return s;
452     }
453
454     if(!IS_STREAM_TRACE)
455         return -1;
456
457     realtime = get_current_calender_time();
458     if(play_counter == 0)
459     {
460                 play_start_time = realtime;
461                 return play_offset_counter;
462     }
463     es = play_mode->rate * (realtime - play_start_time);
464
465     if(es >= play_counter)
466     {
467         /* Ouch!
468          * Audio device queue may be empty!
469          * Reset counters.
470          */
471                 play_offset_counter += play_counter;
472                 play_counter = 0;
473                 play_start_time = realtime;
474                 return play_offset_counter;
475     }
476
477     return (int32)es + play_offset_counter;
478 }
479
480 int32 aq_filled(void)
481 {
482     double realtime, es;
483     int filled;
484
485     if(!IS_STREAM_TRACE)
486         return 0;
487
488     if(play_mode->acntl(PM_REQ_GETFILLED, &filled) != -1)
489       return filled;
490
491     realtime = get_current_calender_time();
492     if(play_counter == 0)
493     {
494                 play_start_time = realtime;
495                 return 0;
496     }
497     es = play_mode->rate * (realtime - play_start_time);
498     if(es >= play_counter)
499     {
500                 /* out of play counter */
501                 play_offset_counter += play_counter;
502                 play_counter = 0;
503                 play_start_time = realtime;
504                 return 0;
505     }
506     return play_counter - (int32)es;
507 }
508
509 int32 aq_soft_filled(void)
510 {
511     int32 bytes;
512     AudioBucket *cur;
513
514     bytes = 0;
515     for(cur = head; cur != NULL; cur = cur->next)
516                 bytes += cur->len;
517     return bytes / Bps;
518 }
519
520 int32 aq_fillable(void)
521 {
522     int fillable;
523     if(!IS_STREAM_TRACE)
524                 return 0;
525     if(play_mode->acntl(PM_REQ_GETFILLABLE, &fillable) != -1)
526                 return fillable;
527     return device_qsize / Bps - aq_filled();
528 }
529
530 double aq_filled_ratio(void)
531 {
532     double ratio;
533
534     if(!IS_STREAM_TRACE)
535                 return 1.0;
536     ratio = (double)aq_filled() * Bps / device_qsize;
537     if(ratio > 1.0)
538                 return 1.0; /* for safety */
539     return ratio;
540 }
541 ///r
542 int aq_get_dev_queuesize(void)
543 {
544     if(!IS_STREAM_TRACE)
545                 return 0;
546     return device_qsize / Bps;
547 }
548
549 int aq_soft_flush(void)
550 {
551     int rc;
552
553     while(head)
554     {
555                 if(head->len < bucket_size)
556                 {
557                         /* Add silence code */
558                         memset (head->data + head->len, 0, bucket_size - head->len);
559                         head->len = bucket_size;
560                 }
561                 if(aq_fill_one() == -1)
562                         return RC_ERROR;
563                 trace_loop();
564                 rc = check_apply_control();
565                 if(RC_IS_SKIP_FILE(rc))
566                 {
567                         play_mode->acntl(PM_REQ_DISCARD, NULL);
568                         flush_buckets();
569                         return rc;
570                 }
571     }
572     play_mode->acntl(PM_REQ_OUTPUT_FINISH, NULL);
573     return RC_NONE;
574 }
575
576 int aq_flush(int discard)
577 {
578     int rc;
579     int more_trace;
580
581     /* to avoid infinite loop */
582     double t, timeout_expect;
583
584     aq_add_count = 0;
585     init_effect();
586
587     if(discard)
588     {
589                 trace_flush();
590                 if(play_mode->acntl(PM_REQ_DISCARD, NULL) != -1)
591                 {
592                         flush_buckets();
593                         return RC_NONE;
594                 }
595                 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
596                           "ERROR: Can't discard audio buffer");
597     }
598
599     if(!IS_STREAM_TRACE)
600     {
601                 play_mode->acntl(PM_REQ_FLUSH, NULL);
602                 play_counter = play_offset_counter = 0;
603                 return RC_NONE;
604     }
605         
606     rc = aq_soft_flush();
607
608     if(RC_IS_SKIP_FILE(rc)){
609         return rc;
610         }
611
612     more_trace = 1;
613     t = get_current_calender_time();
614     timeout_expect = t + (double)aq_filled() * div_playmode_rate;
615
616     while(more_trace || aq_filled() > 0)
617     {
618                 rc = check_apply_control();
619                 if(RC_IS_SKIP_FILE(rc))
620                 {
621                         play_mode->acntl(PM_REQ_DISCARD, NULL);
622                         flush_buckets();
623                         return rc;
624                 }
625                 more_trace = trace_loop();
626
627                 t = get_current_calender_time();
628                 if(t >= timeout_expect - 0.1)
629                   break;
630 ///r
631                 if(!more_trace){
632                         const uint32 max_wait = 200 * 1000;
633                         uint32 wait = (timeout_expect - t) * 100000;
634 //                      usleep((uint32)((double)aq_filled() * div_playmode_rate * 1000000.0)); // while aq_filled() > 0
635 //                      usleep((unsigned long)(200000)); // \82Ä\82«\82Æ\81[\82È\8cÅ\92è\92l 20ms
636                         usleep(wait < max_wait ? wait : max_wait);
637                 }else
638                   aq_wait_ticks();
639     }
640     trace_flush();
641     play_mode->acntl(PM_REQ_FLUSH, NULL);
642     flush_buckets();
643     return RC_NONE;
644 }
645
646 /* Wait a moment */
647 static void aq_wait_ticks(void)
648 {
649     int32 trace_wait, wait_samples;
650 ///r
651 #ifdef USE_TRACE_TIMER
652         return;
653 #endif
654         trace_wait = trace_wait_samples();
655     if(device_qsize == 0 || trace_wait == 0)
656                 return; /* No wait */
657
658     wait_samples = (device_qsize / Bps) * 0.2; // def 20%
659     if(trace_wait != -1 && trace_wait < wait_samples) /* There are more trace events */
660         wait_samples = trace_wait;
661     usleep((unsigned int)((double)wait_samples * div_playmode_rate * 1000000.0));
662 }
663
664 /* add_play_bucket() attempts to add buf to audio bucket.
665  * It returns actually added bytes.
666  */
667 static int32 add_play_bucket(const uint8 *buf, int n)
668 {
669     int total;
670
671     if(n == 0)
672         return 0;
673
674     if(!nbuckets) {
675       play_mode->output_data((uint8 *)buf, n);
676           aq_output_data((uint8*)buf, n);
677       return n;
678     }
679
680     if(head == NULL)
681                 head = tail = next_allocated_bucket();
682
683     total = 0;
684     while(n > 0)
685     {
686                 int i;
687
688                 if(tail->len == bucket_size)
689                 {
690                         AudioBucket *b;
691                         if((b = next_allocated_bucket()) == NULL)
692                         break;
693                         if(head == NULL)
694                                 head = tail = b;
695                         else
696                                 tail = tail->next = b;
697                 }
698
699                 i = bucket_size - tail->len;
700                 if(i > n)
701                         i = n;
702                 memcpy(tail->data + tail->len, buf + total, i);
703                 total += i;
704                 n     -= i;
705                 tail->len += i;
706     }
707
708     return total;
709 }
710
711 /* Flush and clear audio bucket */
712 static void flush_buckets(void)
713 {
714     int i;
715
716     allocated_bucket_list = NULL;
717     for(i = 0; i < nbuckets; i++)
718         reuse_audio_bucket(&base_buckets[i]);
719     head = tail = NULL;
720     aq_fill_buffer_flag = (aq_start_count > 0);
721     play_counter = play_offset_counter = 0;
722 }
723
724 /* next_allocated_bucket() gets free bucket.  If all buckets is used, it
725  * returns NULL.
726  */
727 static AudioBucket *next_allocated_bucket(void)
728 {
729     AudioBucket *b;
730         
731     if (!allocated_bucket_list)
732         return NULL;
733     b = allocated_bucket_list;
734     allocated_bucket_list = allocated_bucket_list->next;
735     b->len = 0;
736     b->next = NULL;
737     return b;
738 }
739
740 /* Reuse specified bucket */
741 static void reuse_audio_bucket(AudioBucket *bucket)
742 {
743     bucket->len = 0;
744     bucket->next = allocated_bucket_list;
745     allocated_bucket_list = bucket;
746 }
747
748 ///r
749 // kobarin
750 void free_audio_bucket(void)
751 {
752     free_soft_queue();
753     nbuckets = 0;
754 }