… | |
… | |
181 | acmd $record_init; |
181 | acmd $record_init; |
182 | acmd $record_set, $record_vol; |
182 | acmd $record_set, $record_vol; |
183 | acmd $playback_off; |
183 | acmd $playback_off; |
184 | |
184 | |
185 | my @send_jobs; |
185 | my @send_jobs; |
|
|
186 | my $send_requeue; |
186 | my ($curfreq, $curmode); |
187 | my ($curfreq, $curmode); |
187 | my $pipeline = 4; |
188 | my $pipeline = 4; |
188 | |
189 | |
189 | my $rbuf; |
190 | my $rbuf; |
190 | my @resp_jobs; |
191 | my @resp_jobs; |
… | |
… | |
192 | sub send_scheduler { |
193 | sub send_scheduler { |
193 | while (@send_jobs |
194 | while (@send_jobs |
194 | && @resp_jobs < $pipeline |
195 | && @resp_jobs < $pipeline |
195 | && (!@resp_jobs || !$resp_jobs[-1]{exclusive}) |
196 | && (!@resp_jobs || !$resp_jobs[-1]{exclusive}) |
196 | ) { |
197 | ) { |
|
|
198 | if ($send_requeue) { |
|
|
199 | # re-sort queue |
|
|
200 | $send_requeue = 0; |
|
|
201 | |
|
|
202 | @send_jobs = sort { |
|
|
203 | $b->{nice} <=> $a->{nice} |
|
|
204 | || $b->{mode} <=> $a->{mode} |
|
|
205 | || $b->{freq} <=> $a->{freq}; |
|
|
206 | } @send_jobs; |
|
|
207 | } |
|
|
208 | |
197 | my $job = (pop_heap @send_jobs)->[1]; |
209 | my $job = pop @send_jobs; |
198 | |
210 | |
199 | my ($cmd, @exp); |
211 | my ($cmd, @exp); |
200 | |
212 | |
201 | if ($curmode != $job->{mode}) { |
213 | if ($curmode != $job->{mode}) { |
202 | $cmd .= "MD$job->{mode}\015\012"; |
214 | $cmd .= "MD$job->{mode}\015\012"; |
… | |
… | |
205 | |
217 | |
206 | if ($curfreq != $job->{freq}) { |
218 | if ($curfreq != $job->{freq}) { |
207 | $cmd .= "RF$job->{freq}\015\012"; |
219 | $cmd .= "RF$job->{freq}\015\012"; |
208 | $curfreq = $job->{freq}; |
220 | $curfreq = $job->{freq}; |
209 | } |
221 | } |
|
|
222 | |
|
|
223 | printf "\rMD%d RF%9d %4d %4d ", $curmode, $curfreq, $job->{nice}, scalar @send_jobs; |
210 | |
224 | |
211 | $job->{exp} = []; |
225 | $job->{exp} = []; |
212 | $job->{res} = []; |
226 | $job->{res} = []; |
213 | |
227 | |
214 | for (@{ $job->{cmd} }) { |
228 | for (@{ $job->{cmd} }) { |
… | |
… | |
274 | my $job = bless { |
288 | my $job = bless { |
275 | freq => round $freq, |
289 | freq => round $freq, |
276 | mode => $mode, |
290 | mode => $mode, |
277 | cmd => \@cmd, |
291 | cmd => \@cmd, |
278 | done => new Coro::Signal, |
292 | done => new Coro::Signal, |
|
|
293 | nice => $nice, |
279 | }, job::; |
294 | }, job::; |
280 | |
295 | |
281 | if (@cmd && ref $cmd[-1]) { |
296 | if (@cmd && ref $cmd[-1]) { |
282 | $job->{exclusive} = pop @cmd; |
297 | $job->{exclusive} = pop @cmd; |
283 | } |
298 | } |
284 | |
299 | |
285 | push_heap @send_jobs, [$nice, $job]; |
300 | push @send_jobs, $job; |
|
|
301 | $send_requeue = 1; |
286 | |
302 | |
287 | send_scheduler; |
303 | send_scheduler; |
288 | |
304 | |
289 | $job |
305 | $job |
290 | } |
306 | } |
… | |
… | |
297 | my ($nice, $mode, $center, $radius) = @_; |
313 | my ($nice, $mode, $center, $radius) = @_; |
298 | |
314 | |
299 | $radius = List::Util::max RESOLUTION, $radius * 0.1; |
315 | $radius = List::Util::max RESOLUTION, $radius * 0.1; |
300 | |
316 | |
301 | my @level = map [$_->{freq}, (List::Util::sum lm $_->result) / 5], |
317 | my @level = map [$_->{freq}, (List::Util::sum lm $_->result) / 5], |
302 | map +(job $nice, $mode, $center + $radius * $_, (delay 0.0020, "LM=LM") x 5), |
318 | map +(job $nice, $mode, $center + $radius * $_, (delay 0.020, "LM=LM") x 5), |
303 | -10 .. 10; |
319 | -10 .. 10; |
304 | |
320 | |
305 | my ($tune, $weight); |
321 | my ($tune, $weight); |
306 | for (@level) { |
322 | for (@level) { |
307 | my ($f, $w) = @$_; |
323 | my ($f, $w) = @$_; |
… | |
… | |
310 | |
326 | |
311 | $tune += $f * $w; |
327 | $tune += $f * $w; |
312 | $weight += $w; |
328 | $weight += $w; |
313 | } |
329 | } |
314 | |
330 | |
|
|
331 | my $lm = ($weight / @level) ** (1/8); |
|
|
332 | |
315 | (int ($tune / $weight / RESOLUTION) * RESOLUTION, $weight ** 0.1 * 100) |
333 | (int ($tune / $weight / RESOLUTION) * RESOLUTION, $lm * 100) |
316 | } |
334 | } |
317 | |
335 | |
318 | sub sweep { |
336 | sub sweep { |
319 | my ($nice, $freqs, $cb) = @_; |
337 | my ($nice, $freqs, $cb) = @_; |
320 | |
338 | |
321 | my $job; |
339 | my @jobs = map { |
|
|
340 | job $nice, $_->[0], $_->[1], "LM=LM"; |
|
|
341 | } @$freqs; |
322 | |
342 | |
323 | for (@$freqs, undef) { |
343 | $cb->($freqs->[$_], lm $jobs[$_]->result) |
324 | my ($mode, $freq, $width) = $_ ? @$_ : (); |
344 | for 0 .. $#jobs; |
325 | |
|
|
326 | my $next_job = $freq && job $nice, $mode, $freq, delay 0.050, "LM=LM"; |
|
|
327 | |
|
|
328 | $cb->($mode, $freq, $width, lm $job->result) |
|
|
329 | if $job; |
|
|
330 | |
|
|
331 | $job = $next_job; |
|
|
332 | } |
|
|
333 | } |
345 | } |
334 | |
346 | |
335 | ############################################################################# |
347 | ############################################################################# |
336 | # raw aearch |
348 | # raw search |
337 | |
349 | |
338 | async { |
350 | async { |
339 | my $nice = 1000; |
351 | my $nice = 1000; |
340 | |
352 | |
341 | while () { |
353 | while () { |
… | |
… | |
345 | limit 1000", |
357 | limit 1000", |
346 | $NOW - SEARCH_INTERVAL_MIN; |
358 | $NOW - SEARCH_INTERVAL_MIN; |
347 | |
359 | |
348 | if (@freq) { |
360 | if (@freq) { |
349 | sweep $nice, \@freq, sub { |
361 | sweep $nice, \@freq, sub { |
350 | my ($mode, $freq, $width, $lm) = @_; |
362 | my ($info, $lm) = @_; |
351 | |
363 | |
352 | sql_exec "update freq set search_time = ?, search_level = ? |
364 | sql_exec "update freq set search_time = ?, search_level = ? |
353 | where mode = ? and freq = ?", |
365 | where mode = ? and freq = ?", |
354 | $NOW, $lm, |
366 | $NOW, $lm, |
355 | $mode, $freq; |
367 | $info->[0], $info->[1]; |
356 | }; |
368 | }; |
357 | } else { |
369 | } else { |
358 | Coro::Timer::sleep 60; |
370 | Coro::Timer::sleep 60; |
359 | } |
371 | } |
360 | } |
372 | } |
… | |
… | |
365 | |
377 | |
366 | async { |
378 | async { |
367 | my $nice = 500; |
379 | my $nice = 500; |
368 | |
380 | |
369 | while () { |
381 | while () { |
370 | my $st = sql_exec \my ($aft_time, $mode, $freq, $width, $activity_level), |
382 | my @info = sql_fetchall |
371 | "select aft_time, mode, freq, width, activity_level |
383 | "select mode, freq, width, activity_level |
372 | from freq |
384 | from freq |
373 | where (search_level >= activity_level |
385 | where (search_level >= activity_level |
374 | or aft_time > 0) |
386 | or aft_time > 0) |
375 | and aft_time < ? |
387 | and aft_time < ? |
376 | order by aft_time, mode, freq |
388 | order by mode, freq |
377 | limit 10", |
389 | limit 100", |
378 | $NOW; |
390 | $NOW; |
379 | |
391 | |
380 | if ($st->rows) { |
392 | if (@info) { |
381 | while ($st->fetch) { |
393 | sweep $nice, \@info, sub { |
382 | my @lm = lm +(job $nice, $mode, $freq, delay 0.050, "LM=LM")->result; |
394 | my ($info, $lm) = @_; |
|
|
395 | my ($mode, $freq, $width, $activity_level) = @$info; |
383 | |
396 | |
384 | if ($lm[0] >= $activity_level) { |
397 | if ($lm >= $activity_level) { |
385 | my ($tune, $weight) = aft $nice, $mode, $freq, $width * 0.9; |
398 | my ($tune, $weight) = aft $nice, $mode, $freq, $width * 0.9; |
386 | |
399 | |
|
|
400 | print "$mode $tune($freq) $lm>=$activity_level "; |
|
|
401 | |
387 | if ($freq - 0.5 * $width <= $tune && $tune <= $freq + 0.5 * $width) { |
402 | if ($freq - 0.5 * $width <= $tune && $tune <= $freq + 0.5 * $width) { |
|
|
403 | print "tuned\n"; |
388 | sql_exec "update freq set aft_time = ?, aft_freq = ?, aft_level = ? |
404 | sql_exec "update freq set aft_time = ?, aft_freq = ?, aft_level = ? |
389 | where mode = ? and freq = ?", |
405 | where mode = ? and freq = ?", |
390 | $NOW + 86400 - 3600, $tune, $weight, |
406 | $NOW + 86400*5 - (rand 86400), $tune, $weight, |
391 | $mode, $freq; |
407 | $mode, $freq; |
392 | } else { |
408 | } else { |
393 | # outlier |
409 | # outlier |
|
|
410 | print "outlier\n"; |
394 | sql_exec "update freq set aft_time = ?, aft_level = 0 |
411 | sql_exec "update freq set aft_time = ?, aft_level = 0 |
395 | where mode = ? and freq = ?", |
412 | where mode = ? and freq = ?", |
396 | $NOW + 86400 + 3600, |
413 | $NOW + 86400*7 - (rand 86400), |
397 | $mode, $freq; |
414 | $mode, $freq; |
398 | } |
415 | } |
399 | } else { |
416 | } else { |
400 | # currently inactive |
417 | # currently inactive |
401 | sql_exec "update freq set aft_time = ? |
418 | sql_exec "update freq set aft_time = ? |
402 | where mode = ? and freq = ?", |
419 | where mode = ? and freq = ?", |
403 | $NOW + 3600, |
420 | $NOW + 57, |
404 | $mode, $freq; |
421 | $mode, $freq; |
405 | } |
422 | } |
406 | } |
423 | }; |
407 | } else { |
424 | } else { |
408 | Coro::Timer::sleep 60; |
425 | Coro::Timer::sleep 10; |
409 | } |
426 | } |
410 | } |
427 | } |
411 | }; |
428 | }; |
412 | |
429 | |
413 | ############################################################################# |
430 | ############################################################################# |
414 | # scan active freqs |
431 | # scan active freqs |
415 | |
432 | |
416 | async { |
433 | async { |
417 | return; |
434 | return; |
418 | my $nice = 100; |
435 | my $nice = 100; |
419 | |
436 | |
420 | while () { |
437 | while () { |
421 | my $st = sql_exec \my ($mode, $freq, $width, $activity_level), |
438 | my $st = sql_exec \my ($mode, $freq, $width, $activity_level), |
422 | "select mode, aft_freq, width, activity_level |
439 | "select mode, aft_freq, width, activity_level |
… | |
… | |
426 | |
443 | |
427 | if ($st->rows) { |
444 | if ($st->rows) { |
428 | my @jobs; |
445 | my @jobs; |
429 | |
446 | |
430 | while ($st->fetch) { |
447 | while ($st->fetch) { |
431 | push @jobs, [$activity_level, job $nice, $mode, $freq, delay 0.030, "LM=LM"]; |
448 | push @jobs, [$activity_level, job $nice, $mode, $freq, delay 0.040, "LM=LM"]; |
432 | } |
449 | } |
433 | |
450 | |
434 | for (@jobs) { |
451 | for (@jobs) { |
435 | my ($activity_level, $job) = @$_; |
452 | my ($activity_level, $job) = @$_; |
436 | |
453 | |
… | |
… | |
439 | if ($lm[0] >= $activity_level) { |
456 | if ($lm[0] >= $activity_level) { |
440 | warn "scan $job->{mode} $job->{freq} @lm\n"; |
457 | warn "scan $job->{mode} $job->{freq} @lm\n"; |
441 | (job $nice-1, $mode, $job->{freq}, "LM=LM", sub { |
458 | (job $nice-1, $mode, $job->{freq}, "LM=LM", sub { |
442 | # (job $nice-1, 0, 98400000, "LM=LM", sub { |
459 | # (job $nice-1, 0, 98400000, "LM=LM", sub { |
443 | acmd $playback_on; |
460 | acmd $playback_on; |
444 | Coro::Timer::sleep 0.5; |
461 | Coro::Timer::sleep 1; |
445 | # my $data = 0.5 + (1 / 65536) * float unpack "v*", record_nsamples $record_rate * 0.1; |
462 | # my $data = 0.5 + (1 / 65536) * float unpack "v*", record_nsamples $record_rate * 0.1; |
446 | acmd $playback_off; |
463 | acmd $playback_off; |
447 | #$data = sin +(1/480) * xvals zeroes 48000; |
464 | #$data = sin +(1/480) * xvals zeroes 48000; |
448 | # $data->reshape (100, $record_rate / 100); |
465 | # $data->reshape (100, $record_rate / 100); |
449 | # |
466 | # |
… | |
… | |
460 | } |
477 | } |
461 | } |
478 | } |
462 | }; |
479 | }; |
463 | |
480 | |
464 | ############################################################################# |
481 | ############################################################################# |
|
|
482 | |
|
|
483 | $| = 1; |
465 | |
484 | |
466 | Coro::Event::loop; |
485 | Coro::Event::loop; |
467 | |
486 | |
468 | __END__ |
487 | __END__ |
469 | mysql -e "delete from freq" aor |
488 | mysql -e "delete from freq" aor |