… | |
… | |
161 | our $SDL_ACTIVE; |
161 | our $SDL_ACTIVE; |
162 | our %SDL_CB; |
162 | our %SDL_CB; |
163 | |
163 | |
164 | our $SDL_MIXER; |
164 | our $SDL_MIXER; |
165 | our $MUSIC_DEFAULT = "in_a_heartbeat.ogg"; |
165 | our $MUSIC_DEFAULT = "in_a_heartbeat.ogg"; |
166 | our @MUSIC_WANT; |
166 | our $MUSIC_WANT; # arryref of ambient music |
|
|
167 | our @MUSIC_HAVE; # ambient music we want now |
167 | our $MUSIC_START; |
168 | our $MUSIC_START; |
168 | our $MUSIC_PLAYING_DATA; |
169 | our $MUSIC_PLAYING_DATA; |
169 | our $MUSIC_PLAYING_META; |
170 | our $MUSIC_PLAYING_META; |
170 | our $MUSIC_PLAYER; |
171 | our $MUSIC_PLAYER; |
171 | our $MUSIC_RESUME = 30; # resume music when players less than these many seconds before |
172 | our $MUSIC_RESUME = 30; # resume music when players less than these many seconds before |
… | |
… | |
200 | if (my $chunk = $AUDIO_CHUNK{$face}) { |
201 | if (my $chunk = $AUDIO_CHUNK{$face}) { |
201 | for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { |
202 | for (grep $_->[0] >= Event::time, @{(delete $AUDIO_PLAY{$face}) || []}) { |
202 | my (undef, $dx, $dy, $vol) = @$_; |
203 | my (undef, $dx, $dy, $vol) = @$_; |
203 | |
204 | |
204 | my $channel = CFPlus::Channel::find; |
205 | my $channel = CFPlus::Channel::find; |
205 | $channel->volume (128 + $vol); |
206 | $channel->volume ($vol * 128 / 255); |
206 | $dx = $dx / 10 * 255; |
207 | $dx = $dx / 10 * 255; |
207 | $channel->set_panning ((min 255, 255 - $dx), (min 255, 255 + $dx)); |
208 | $channel->set_panning (255 - $dx, 255 + $dx); |
208 | |
209 | |
209 | # my $angle = $dx ? : $dx < 0 ? |
210 | # my $angle = $dx ? : $dx < 0 ? |
210 | # my $distance = -$vol; |
211 | # my $distance = -$vol; |
211 | # $channel->set_position ($angle, $distance); |
212 | # $channel->set_position ($angle, $distance); |
212 | |
213 | |
… | |
… | |
217 | my $meta = $CONN->{sound_meta}{$face} |
218 | my $meta = $CONN->{sound_meta}{$face} |
218 | or return; |
219 | or return; |
219 | |
220 | |
220 | # fetch from database |
221 | # fetch from database |
221 | CFPlus::DB::get res_data => $meta->{name}, sub { |
222 | CFPlus::DB::get res_data => $meta->{name}, sub { |
222 | my $vol = $meta->{meta}{volume} || 1; |
|
|
223 | my $rwops = new CFPlus::RW $_[0]; |
223 | my $rwops = new CFPlus::RW $_[0]; |
224 | my $chunk = new CFPlus::MixChunk $rwops; |
224 | my $chunk = new CFPlus::MixChunk $rwops; |
225 | $chunk->volume ($vol * 128); |
225 | $chunk->volume (($meta->{meta}{volume} || 1) * 128); |
226 | $AUDIO_CHUNK{$face} = $chunk; |
226 | $AUDIO_CHUNK{$face} = $chunk; |
227 | |
227 | |
228 | audio_sound_push ($face); |
228 | audio_sound_push ($face); |
229 | }; |
229 | }; |
230 | } |
230 | } |
… | |
… | |
247 | my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1; |
247 | my $volume = $MUSIC_PLAYING_META->{meta}{volume} || 1; |
248 | my $base = $CFG->{bgm_volume}; |
248 | my $base = $CFG->{bgm_volume}; |
249 | CFPlus::MixMusic::volume $base * $volume * 128; |
249 | CFPlus::MixMusic::volume $base * $volume * 128; |
250 | } |
250 | } |
251 | |
251 | |
|
|
252 | sub audio_music_push { |
|
|
253 | my @have = |
|
|
254 | grep $_, |
|
|
255 | map $CONN->{music_meta}{$_}, |
|
|
256 | @$MUSIC_WANT; |
|
|
257 | |
|
|
258 | if (@have) { |
|
|
259 | @MUSIC_HAVE = @have; |
|
|
260 | &audio_music_changed (); |
|
|
261 | } |
|
|
262 | } |
|
|
263 | |
252 | sub audio_music_set_ambient { |
264 | sub audio_music_set_ambient { |
253 | my ($songs) = @_; |
265 | my ($songs) = @_; |
254 | |
266 | |
255 | my @want = |
267 | $MUSIC_WANT = $songs; |
256 | grep $_, |
|
|
257 | map $CONN->{music_meta}{$_}, |
|
|
258 | @$songs; |
|
|
259 | |
268 | |
260 | if (@want) { |
269 | audio_music_push; |
261 | @MUSIC_WANT = @want; |
|
|
262 | &audio_music_changed (); |
|
|
263 | } |
|
|
264 | } |
270 | } |
265 | |
271 | |
266 | sub audio_music_start { |
272 | sub audio_music_start { |
267 | my $meta = $MUSIC_PLAYING_META; |
273 | my $meta = $MUSIC_PLAYING_META; |
268 | |
274 | |
… | |
… | |
302 | |
308 | |
303 | sub audio_music_changed { |
309 | sub audio_music_changed { |
304 | return unless $CFG->{bgm_enable}; |
310 | return unless $CFG->{bgm_enable}; |
305 | return unless $SDL_MIXER; |
311 | return unless $SDL_MIXER; |
306 | |
312 | |
307 | # default MUSIC_WANT == MUSIC_DEFAULT |
313 | # default MUSIC_HAVE == MUSIC_DEFAULT |
308 | @MUSIC_WANT = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_WANT; |
314 | @MUSIC_HAVE = { path => CFPlus::find_rcfile "music/$MUSIC_DEFAULT" } unless @MUSIC_HAVE; |
309 | |
315 | |
310 | # if the currently playing song is acceptable, let it continue |
316 | # if the currently playing song is acceptable, let it continue |
311 | return if $MUSIC_PLAYING_META |
317 | return if $MUSIC_PLAYING_META |
312 | && grep $MUSIC_PLAYING_META == $_, @MUSIC_WANT; |
318 | && grep $MUSIC_PLAYING_META == $_, @MUSIC_HAVE; |
313 | |
319 | |
314 | my $NOW = time; |
320 | my $NOW = time; |
315 | |
321 | |
316 | if ($MUSIC_PLAYING_META) { |
322 | if ($MUSIC_PLAYING_META) { |
317 | $MUSIC_PLAYING_META->{stop_time} = $NOW; |
323 | $MUSIC_PLAYING_META->{stop_time} = $NOW; |
318 | $MUSIC_PLAYING_META->{stop_pos} = $NOW - $MUSIC_START; |
324 | $MUSIC_PLAYING_META->{stop_pos} = $NOW - $MUSIC_START; |
319 | CFPlus::MixMusic::fade_out 1000; |
325 | CFPlus::MixMusic::fade_out 1000; |
320 | } else { |
326 | } else { |
321 | # sort by stop time, oldest first |
327 | # sort by stop time, oldest first |
322 | @MUSIC_WANT = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_WANT; |
328 | @MUSIC_HAVE = sort { $a->{stop_time} <=> $b->{stop_time} } @MUSIC_HAVE; |
323 | |
329 | |
324 | # if the most recently-played piece played very recently, |
330 | # if the most recently-played piece played very recently, |
325 | # resume it, else choose the oldest piece for rotation. |
331 | # resume it, else choose the oldest piece for rotation. |
326 | $MUSIC_PLAYING_META = |
332 | $MUSIC_PLAYING_META = |
327 | $MUSIC_WANT[-1]{stop_time} > $NOW - $MUSIC_RESUME |
333 | $MUSIC_HAVE[-1]{stop_time} > $NOW - $MUSIC_RESUME |
328 | ? $MUSIC_WANT[-1] |
334 | ? $MUSIC_HAVE[-1] |
329 | : $MUSIC_WANT[0]; |
335 | : $MUSIC_HAVE[0]; |
330 | |
336 | |
331 | audio_music_start; |
337 | audio_music_start; |
332 | } |
338 | } |
333 | } |
339 | } |
334 | |
340 | |