1
/*
2
3
4
5
* QEMU Timer based audio emulation
*
* Copyright ( c ) 2004 - 2005 Vassili Karpov ( malc )
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
24
25
26
# include "qemu-common.h"
# include "audio.h"
# include "qemu-timer.h"
27
28
29
# define AUDIO_CAP "noaudio"
# include "audio_int.h"
30
31
32
typedef struct NoVoiceOut {
HWVoiceOut hw ;
33
int64_t old_ticks ;
34
} NoVoiceOut ;
35
36
37
38
39
typedef struct NoVoiceIn {
HWVoiceIn hw ;
int64_t old_ticks ;
} NoVoiceIn ;
40
41
static int no_run_out ( HWVoiceOut * hw )
42
{
43
44
NoVoiceOut * no = ( NoVoiceOut * ) hw ;
int live , decr , samples ;
45
46
47
int64_t now ;
int64_t ticks ;
int64_t bytes ;
48
49
50
51
52
live = audio_pcm_hw_get_live_out ( & no -> hw );
if ( ! live ) {
return 0 ;
}
53
54
55
56
57
58
59
now = qemu_get_clock ( vm_clock );
ticks = now - no -> old_ticks ;
bytes = ( ticks * hw -> info . bytes_per_second ) / ticks_per_sec ;
bytes = audio_MIN ( bytes , INT_MAX );
samples = bytes >> hw -> info . shift ;
60
61
no -> old_ticks = now ;
decr = audio_MIN ( live , samples );
62
63
64
hw -> rpos = ( hw -> rpos + decr ) % hw -> samples ;
return decr ;
}
65
66
67
68
69
static int no_write ( SWVoiceOut * sw , void * buf , int len )
{
return audio_pcm_sw_write ( sw , buf , len );
}
70
malc
authored
16 years ago
71
static int no_init_out ( HWVoiceOut * hw , struct audsettings * as )
72
{
73
audio_pcm_init_info ( & hw -> info , as );
74
hw -> samples = 1024 ;
75
76
return 0 ;
}
77
78
79
80
static void no_fini_out ( HWVoiceOut * hw )
{
( void ) hw ;
81
82
}
83
static int no_ctl_out ( HWVoiceOut * hw , int cmd , ...)
84
{
85
86
87
( void ) hw ;
( void ) cmd ;
return 0 ;
88
89
}
malc
authored
16 years ago
90
static int no_init_in ( HWVoiceIn * hw , struct audsettings * as )
91
{
92
audio_pcm_init_info ( & hw -> info , as );
93
hw -> samples = 1024 ;
94
95
96
return 0 ;
}
97
static void no_fini_in ( HWVoiceIn * hw )
98
99
100
101
{
( void ) hw ;
}
102
103
104
105
106
static int no_run_in ( HWVoiceIn * hw )
{
NoVoiceIn * no = ( NoVoiceIn * ) hw ;
int live = audio_pcm_hw_get_live_in ( hw );
int dead = hw -> samples - live ;
107
int samples = 0 ;
108
109
110
111
112
if ( dead ) {
int64_t now = qemu_get_clock ( vm_clock );
int64_t ticks = now - no -> old_ticks ;
int64_t bytes = ( ticks * hw -> info . bytes_per_second ) / ticks_per_sec ;
113
114
115
116
117
118
no -> old_ticks = now ;
bytes = audio_MIN ( bytes , INT_MAX );
samples = bytes >> hw -> info . shift ;
samples = audio_MIN ( samples , dead );
}
119
120
121
122
123
124
125
126
127
128
129
130
131
return samples ;
}
static int no_read ( SWVoiceIn * sw , void * buf , int size )
{
int samples = size >> sw -> info . shift ;
int total = sw -> hw -> total_samples_captured - sw -> total_hw_samples_acquired ;
int to_clear = audio_MIN ( samples , total );
audio_pcm_info_clear_buf ( & sw -> info , buf , to_clear );
return to_clear ;
}
static int no_ctl_in ( HWVoiceIn * hw , int cmd , ...)
132
133
134
135
136
137
138
139
140
141
142
143
144
{
( void ) hw ;
( void ) cmd ;
return 0 ;
}
static void * no_audio_init ( void )
{
return & no_audio_init ;
}
static void no_audio_fini ( void * opaque )
{
145
( void ) opaque ;
146
147
}
148
static struct audio_pcm_ops no_pcm_ops = {
149
150
151
152
153
154
155
156
157
158
159
no_init_out ,
no_fini_out ,
no_run_out ,
no_write ,
no_ctl_out ,
no_init_in ,
no_fini_in ,
no_run_in ,
no_read ,
no_ctl_in
160
161
};
162
163
164
165
166
167
168
169
170
171
172
173
struct audio_driver no_audio_driver = {
INIT_FIELD ( name = ) "none" ,
INIT_FIELD ( descr = ) "Timer based audio emulation" ,
INIT_FIELD ( options = ) NULL ,
INIT_FIELD ( init = ) no_audio_init ,
INIT_FIELD ( fini = ) no_audio_fini ,
INIT_FIELD ( pcm_ops = ) & no_pcm_ops ,
INIT_FIELD ( can_be_default = ) 1 ,
INIT_FIELD ( max_voices_out = ) INT_MAX ,
INIT_FIELD ( max_voices_in = ) INT_MAX ,
INIT_FIELD ( voice_size_out = ) sizeof ( NoVoiceOut ),
INIT_FIELD ( voice_size_in = ) sizeof ( NoVoiceIn )
174
};