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