Graphics.pm 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package Plugins::SqueezeESP32::Graphics;
  2. use strict;
  3. use base qw(Slim::Display::Squeezebox2);
  4. use Slim::Utils::Prefs;
  5. use Slim::Utils::Log;
  6. my $prefs = preferences('plugin.squeezeesp32');
  7. my $log = logger('plugin.squeezeesp32');
  8. my $VISUALIZER_NONE = 0;
  9. my $VISUALIZER_VUMETER = 1;
  10. my $VISUALIZER_SPECTRUM_ANALYZER = 2;
  11. my $VISUALIZER_WAVEFORM = 3;
  12. my $VISUALIZER_VUMETER_ESP32 = 0x11;
  13. my $VISUALIZER_SPECTRUM_ANALYZER_ESP32 = 0x12;
  14. my %SPECTRUM_DEFAULTS = (
  15. scale => 25,
  16. small => {
  17. size => 25,
  18. band => 5.33
  19. },
  20. full => {
  21. band => 8
  22. },
  23. );
  24. {
  25. #__PACKAGE__->mk_accessor('array', 'modes');
  26. __PACKAGE__->mk_accessor('rw', 'modes');
  27. __PACKAGE__->mk_accessor('rw', qw(vfdmodel));
  28. }
  29. sub new {
  30. my $class = shift;
  31. my $client = shift;
  32. my $display = $class->SUPER::new($client);
  33. my $cprefs = $prefs->client($client);
  34. $cprefs->init( {
  35. width => 128,
  36. small_VU => 15,
  37. spectrum => \%SPECTRUM_DEFAULTS,
  38. } );
  39. $prefs->migrateClient(2, sub {
  40. my ($cprefs, $client) = @_;
  41. sanitizeSpectrum($cprefs->get('spectrum'));
  42. 1;
  43. });
  44. $display->init_accessor(
  45. modes => $display->build_modes,
  46. # Only seems to matter for screensaver and update to decide font. Not
  47. # any value is acceptable, so use Boom value which seems to be best
  48. # compromise
  49. vfdmodel => 'graphic-160x32',
  50. );
  51. return $display;
  52. }
  53. =comment
  54. sub modes {
  55. return \@modes;
  56. }
  57. =cut
  58. sub nmodes {
  59. return scalar($#{shift->modes()});
  60. }
  61. sub displayWidth {
  62. my $display = shift;
  63. my $client = $display->client;
  64. # if we're showing the always-on visualizer & the current buttonmode
  65. # hasn't overridden, then use the playing display mode to index
  66. # into the display width, otherwise, it's fullscreen.
  67. my $mode = 0;
  68. if ( $display->showVisualizer() && !defined($client->modeParam('visu')) ) {
  69. my $cprefs = preferences('server')->client($client);
  70. $mode = $cprefs->get('playingDisplayModes')->[ $cprefs->get('playingDisplayMode') ];
  71. }
  72. if ($display->widthOverride) {
  73. my $artwork = $prefs->client($client)->get('artwork');
  74. if ($artwork->{'enable'} && $artwork->{'y'} < 32 && ($client->isPlaying || $client->isPaused)) {
  75. return ($artwork->{x} || $display->widthOverride) + ($display->modes->[$mode || 0]{_width} || 0);
  76. } else {
  77. return $display->widthOverride + ($display->modes->[$mode || 0]{_width} || 0);
  78. }
  79. } else {
  80. return $display->modes->[$mode || 0]{width};
  81. }
  82. }
  83. sub brightnessMap {
  84. return (0 .. 5);
  85. }
  86. =comment
  87. sub bytesPerColumn {
  88. return 4;
  89. }
  90. =cut
  91. # I don't think LMS renderer handles properly screens other than 32 pixels. It
  92. # seems that all we get is a 32 pixel-tall data with anything else padded to 0
  93. # i.e. if we try 64 pixels height, bytes 0..3 and 4..7 will contains the same
  94. # pattern than the 32 pixels version, where one would have expected bytes 4..7
  95. # to be empty
  96. sub displayHeight {
  97. return 32;
  98. }
  99. sub sanitizeSpectrum {
  100. my ($spectrum) = shift;
  101. $spectrum->{small}->{size} ||= $SPECTRUM_DEFAULTS{small}->{size};
  102. $spectrum->{small}->{band} ||= $SPECTRUM_DEFAULTS{small}->{band};
  103. $spectrum->{full}->{band} ||= $SPECTRUM_DEFAULTS{full}->{band};
  104. return $spectrum;
  105. }
  106. sub build_modes {
  107. my $client = shift->client;
  108. my $cprefs = $prefs->client($client);
  109. my $artwork = $cprefs->get('artwork');
  110. my $disp_width = $cprefs->get('width') || 128;
  111. # if artwork is in main display, reduce width but when artwork is (0,0) fake it
  112. my $width = ($artwork->{'enable'} && $artwork->{'y'} < 32 && $artwork->{'x'}) ? $artwork->{'x'} : $disp_width;
  113. my $width_low = ($artwork->{'enable'} && $artwork->{'x'} && ($artwork->{'y'} >= 32 || $disp_width - $artwork->{'x'} > 32)) ? $artwork->{'x'} : $disp_width;
  114. my $small_VU = $cprefs->get('small_VU');
  115. my $spectrum = sanitizeSpectrum($cprefs->get('spectrum'));
  116. my $small_spectrum_pos = { x => $width - int ($spectrum->{small}->{size} * $width / 100),
  117. width => int ($spectrum->{small}->{size} * $width / 100),
  118. };
  119. my $small_VU_pos = { x => $width - int ($small_VU * $width / 100),
  120. width => int ($small_VU * $width / 100),
  121. };
  122. my @modes = (
  123. # mode 0
  124. { desc => ['BLANK'],
  125. bar => 0, secs => 0, width => $width,
  126. params => [$VISUALIZER_NONE] },
  127. # mode 1
  128. { desc => ['PROGRESS_BAR'],
  129. bar => 1, secs => 0, width => $width,
  130. params => [$VISUALIZER_NONE] },
  131. # mode 2
  132. { desc => ['ELAPSED'],
  133. bar => 0, secs => 1, width => $width,
  134. params => [$VISUALIZER_NONE] },
  135. # mode 3
  136. { desc => ['ELAPSED', 'AND', 'PROGRESS_BAR'],
  137. bar => 1, secs => 1, width => $width,
  138. params => [$VISUALIZER_NONE] },
  139. # mode 4
  140. { desc => ['REMAINING'],
  141. bar => 0, secs => -1, width => $width,
  142. params => [$VISUALIZER_NONE] },
  143. # mode 5
  144. { desc => ['CLOCK'],
  145. bar => 0, secs => 0, width => $width, clock => 1,
  146. params => [$VISUALIZER_NONE] },
  147. # mode 6
  148. { desc => ['SETUP_SHOWBUFFERFULLNESS'],
  149. bar => 0, secs => 0, width => $width, fullness => 1,
  150. params => [$VISUALIZER_NONE] },
  151. # mode 7
  152. { desc => ['VISUALIZER_VUMETER_SMALL'],
  153. bar => 0, secs => 0, width => $width, _width => -$small_VU_pos->{'width'},
  154. # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space)
  155. params => [$VISUALIZER_VUMETER_ESP32, $small_VU_pos->{'width'}, 32, $small_VU_pos->{'x'}, 0, 2] },
  156. # mode 8
  157. { desc => ['VISUALIZER_SPECTRUM_ANALYZER_SMALL'],
  158. bar => 0, secs => 0, width => $width, _width => -$small_spectrum_pos->{'width'},
  159. # extra parameters (width, height, col (< 0 = from right), row (< 0 = from bottom), left_space, #bars, scale)
  160. params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $small_spectrum_pos->{width}, 32, $small_spectrum_pos->{'x'}, 0, 2, $small_spectrum_pos->{'width'} / $spectrum->{small}->{band}, $spectrum->{scale}] },
  161. # mode 9
  162. { desc => ['VISUALIZER_VUMETER'],
  163. bar => 0, secs => 0, width => $width,
  164. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 0] },
  165. # mode 10
  166. { desc => ['VISUALIZER_ANALOG_VUMETER'],
  167. bar => 0, secs => 0, width => $width,
  168. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 1] },
  169. # mode 11
  170. { desc => ['VISUALIZER_SPECTRUM_ANALYZER'],
  171. bar => 0, secs => 0, width => $width,
  172. # extra parameters (bars)
  173. params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $width_low, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
  174. );
  175. my @extra = (
  176. # mode E1
  177. { desc => ['VISUALIZER_VUMETER', 'AND', 'ELAPSED'],
  178. bar => 0, secs => 1, width => $width,
  179. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 0] },
  180. # mode E2
  181. { desc => ['VISUALIZER_ANALOG_VUMETER', 'AND', 'ELAPSED'],
  182. bar => 0, secs => 1, width => $width,
  183. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 1] },
  184. # mode E3
  185. { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'ELAPSED'],
  186. bar => 0, secs => 1, width => $width,
  187. # extra parameters (bars)
  188. params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $width_low, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
  189. # mode E4
  190. { desc => ['VISUALIZER_VUMETER', 'AND', 'REMAINING'],
  191. bar => 0, secs => -1, width => $width,
  192. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 0] },
  193. # mode E5
  194. { desc => ['VISUALIZER_ANALOG_VUMETER', 'AND', 'REMAINING'],
  195. bar => 0, secs => -1, width => $width,
  196. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 1] },
  197. # mode E6
  198. { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'REMAINING'],
  199. bar => 0, secs => -1, width => $width,
  200. # extra parameters (bars)
  201. params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $width_low, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
  202. # mode E7
  203. { desc => ['VISUALIZER_VUMETER', 'AND', 'PROGRESS_BAR', 'AND', 'REMAINING'],
  204. bar => 1, secs => -1, width => $width,
  205. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 0] },
  206. # mode E8
  207. { desc => ['VISUALIZER_ANALOG_VUMETER', 'AND', 'PROGRESS_BAR', 'AND', 'REMAINING'],
  208. bar => 1, secs => -1, width => $width,
  209. params => [$VISUALIZER_VUMETER_ESP32, $width_low, 1] },
  210. # mode E9
  211. { desc => ['VISUALIZER_SPECTRUM_ANALYZER', 'AND', 'PROGRESS_BAR', 'AND', 'REMAINING'],
  212. bar => 1, secs => -1, width => $width,
  213. # extra parameters (bars)
  214. params => [$VISUALIZER_SPECTRUM_ANALYZER_ESP32, $width_low, int ($width/$spectrum->{full}->{band}), $spectrum->{scale}] },
  215. );
  216. @modes = (@modes, @extra) if $cprefs->get('height') > 32;
  217. return \@modes;
  218. }
  219. 1;