3 * Implements the MidiEventMeter class.
5 * Copyright 2013, Haiku, Inc. All rights reserved.
6 * Distributed under the terms of the MIT License.
8 * Revisions by Pete Goodeve
10 * Copyright 1999, Be Incorporated. All Rights Reserved.
11 * This file may be used under the terms of the Be Sample Code License.
14 #include "MidiEventMeter.h"
17 #include <MidiRoster.h>
18 #include <MidiProducer.h>
19 #include <MidiConsumer.h>
22 #include "CountEventConsumer.h"
24 static const BRect
METER_BOUNDS(0, 0, 7, 31);
26 // If we get this number of events per pulse or greater, we will
27 // max out the event meter.
28 // Value was determined empirically based on my banging on a MIDI
29 // keyboard controller with a pulse of 200ms.
30 static const int32 METER_SCALE
= 10;
33 MidiEventMeter::MidiEventMeter(int32 producerID
)
38 BMidiRoster
* roster
= BMidiRoster::MidiRoster();
40 BMidiProducer
* producer
= roster
->FindProducer(producerID
);
41 if (producer
!= NULL
) {
43 name
<< producer
->Name() << " Event Meter";
44 fCounter
= new CountEventConsumer(name
.String());
45 producer
->Connect(fCounter
);
52 MidiEventMeter::~MidiEventMeter()
60 MidiEventMeter::Pulse(BView
* view
)
62 int32 newLevel
= fMeterLevel
;
63 if (fCounter
!= NULL
) {
64 newLevel
= CalcMeterLevel(fCounter
->CountEvents());
67 if (newLevel
!= fMeterLevel
) {
68 fMeterLevel
= newLevel
;
69 view
->Invalidate(BRect(METER_BOUNDS
).InsetBySelf(1, 1));
75 MidiEventMeter::Bounds() const
82 MidiEventMeter::Draw(BView
* view
)
84 const rgb_color METER_BLACK
= { 0, 0, 0, 255 };
85 const rgb_color METER_GREY
= { 180, 180, 180, 255 };
86 const rgb_color METER_GREEN
= { 0, 255, 0, 255 };
91 BPoint lt
= METER_BOUNDS
.LeftTop();
92 BPoint rb
= METER_BOUNDS
.RightBottom();
93 view
->BeginLineArray(4);
94 view
->AddLine(BPoint(lt
.x
, lt
.y
), BPoint(rb
.x
- 1, lt
.y
), METER_BLACK
);
95 view
->AddLine(BPoint(rb
.x
, lt
.y
), BPoint(rb
.x
, rb
.y
- 1), METER_BLACK
);
96 view
->AddLine(BPoint(rb
.x
, rb
.y
), BPoint(lt
.x
+ 1, rb
.y
), METER_BLACK
);
97 view
->AddLine(BPoint(lt
.x
, rb
.y
), BPoint(lt
.x
, lt
.y
+ 1), METER_BLACK
);
101 BRect cell
= METER_BOUNDS
;
103 cell
.bottom
= cell
.top
+ (cell
.Height() + 1) / 5;
106 const float kTintArray
[] =
113 for (int32 i
= 4; i
>= 0; i
--) {
115 if (fMeterLevel
> i
) {
116 color
= tint_color(METER_GREEN
, kTintArray
[i
]);
120 view
->SetHighColor(color
);
121 view
->FillRect(cell
);
122 cell
.OffsetBy(0, cell
.Height() + 1);
130 MidiEventMeter::CalcMeterLevel(int32 eventCount
) const
132 // we use an approximately logarithmic scale for determing the actual
133 // drawn meter level, so that low-density event streams show up well.
136 else if (eventCount
< (int32
)(0.5 * METER_SCALE
))
138 else if (eventCount
< (int32
)(0.75 * METER_SCALE
))
140 else if (eventCount
< (int32
)(0.9 * METER_SCALE
))
142 else if (eventCount
< METER_SCALE
)