1 /*
2  * Copyright (C) 2002 2003 2009 2010, Magnus Hjorth
3  *
4  * This file is part of mhWaveEdit.
5  *
6  * mhWaveEdit 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  * mhWaveEdit 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 mhWaveEdit; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 
22 
23 /* This is the "dummy" sound driver. It pretends to output and input data but
24  * does nothing. It it used if no supported sound libraries were found. It also
25  * has some debugging code built into it to check that the program does not call
26  * the sound driver in a wrong way. (e.g. not calling sound_init first).
27  */
28 
29 #ifdef HAVE_SYS_TIME_H
30 #include <sys/time.h>
31 #endif
32 #ifdef HAVE_TIME_H
33 #include <time.h>
34 #endif
35 
36 #include "sound.h"
37 
38 static struct {
39      gint state;
40      int lasttime;
41      Dataformat format;
42      gint input_bytes_available;
43      gint output_bytes_buffered;
44 } dummy_data = {1};
45 
46 
dummy_init(gboolean silent)47 static gboolean dummy_init(gboolean silent)
48 {
49      g_assert(dummy_data.state == 1);
50      dummy_data.state = 2;
51      return TRUE;
52 }
53 
dummy_quit(void)54 static void dummy_quit(void)
55 {
56      g_assert(dummy_data.state == 2);
57      dummy_data.state = 5;
58 }
59 
dummy_output_select_format(Dataformat * format,gboolean silent,GVoidFunc ready_func)60 static gint dummy_output_select_format(Dataformat *format, gboolean silent,
61 				       GVoidFunc ready_func)
62 {
63      g_assert(dummy_data.state == 2);
64      dummy_data.state = 3;
65      memcpy(&dummy_data.format,format,sizeof(Dataformat));
66      dummy_data.output_bytes_buffered = 0;
67      return 0;
68 }
69 
dummy_output_stop(gboolean must_flush)70 static gboolean dummy_output_stop(gboolean must_flush)
71 {
72      g_assert(dummy_data.state == 2 || dummy_data.state == 3);
73      dummy_data.state = 2;
74      return TRUE;
75 }
76 
dummy_output_checkbuf(void)77 static void dummy_output_checkbuf(void)
78 {
79      time_t t;
80      t = time(0);
81      if (t != dummy_data.lasttime) {
82 	  dummy_data.output_bytes_buffered -=
83 	       dummy_data.format.samplerate*dummy_data.format.samplebytes;
84 	  if (dummy_data.output_bytes_buffered < 0 || t > dummy_data.lasttime+1)
85 	       dummy_data.output_bytes_buffered = 0;
86 	  dummy_data.lasttime = t;
87      }
88 }
89 
dummy_output_want_data(void)90 static gboolean dummy_output_want_data(void)
91 {
92      g_assert(dummy_data.state == 3);
93      dummy_output_checkbuf();
94      return (dummy_data.output_bytes_buffered <
95 	     2 * dummy_data.format.samplerate * dummy_data.format.samplebytes);
96 }
97 
dummy_output_play(gchar * buffer,guint bufsize)98 static guint dummy_output_play(gchar *buffer, guint bufsize)
99 {
100      gint i;
101      g_assert(dummy_data.state == 3);
102      dummy_output_checkbuf();
103      i = 2*dummy_data.format.samplerate*dummy_data.format.samplebytes;
104      i -= dummy_data.output_bytes_buffered;
105      if (i > bufsize) i = bufsize;
106      dummy_data.output_bytes_buffered += i;
107      return i;
108 }
109 
dummy_output_clear_buffers(void)110 static void dummy_output_clear_buffers(void)
111 {
112      g_assert(dummy_data.state == 3);
113      dummy_data.output_bytes_buffered = 0;
114 }
115 
dummy_input_supported_formats(gboolean * complete)116 static GList *dummy_input_supported_formats(gboolean *complete)
117 {
118      g_assert(dummy_data.state == 2);
119      *complete = FALSE;
120      return NULL;
121 }
122 
dummy_input_select_format(Dataformat * format,gboolean silent,GVoidFunc ready_func)123 static gint dummy_input_select_format(Dataformat *format, gboolean silent,
124 				      GVoidFunc ready_func)
125 {
126      g_assert(dummy_data.state == 2);
127      /* if (format->samplerate < 100000 && format->samplerate > 0) return -1; */
128      memcpy(&dummy_data.format,format,sizeof(Dataformat));
129      dummy_data.input_bytes_available = 0;
130      dummy_data.state = 4;
131      return 0;
132 }
133 
dummy_input_stop(void)134 static void dummy_input_stop(void)
135 {
136      g_assert(dummy_data.state == 4 || dummy_data.state == 2);
137      dummy_data.state = 2;
138 }
139 
dummy_input_store(Ringbuf * buffer)140 static void dummy_input_store(Ringbuf *buffer)
141 {
142      guint32 i;
143      time_t t;
144      g_assert(dummy_data.state == 4);
145      t = time(0);
146      if (t != dummy_data.lasttime) {
147 	  dummy_data.input_bytes_available +=
148 	       dummy_data.format.samplerate * dummy_data.format.samplebytes;
149 	  dummy_data.lasttime = t;
150      }
151      i = MIN(ringbuf_freespace(buffer),dummy_data.input_bytes_available);
152      dummy_data.input_bytes_available -= ringbuf_enqueue_zeroes(buffer,i);
153 }
154 
155