Connected volume control GUI with Controller class, and made slider non-linear.

This should be reviewed, and a better algorith should be selected.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17375 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen
2006-05-08 20:40:58 +00:00
parent 5a5960830d
commit 131d97be80
5 changed files with 97 additions and 17 deletions
+13 -1
View File
@@ -60,6 +60,7 @@ Controller::Controller()
, fVideoPlayThread(-1)
, fStopAudioPlayback(false)
, fStopVideoPlayback(false)
, fSoundOutput(NULL)
{
}
@@ -251,6 +252,14 @@ Controller::VolumeDown()
}
void
Controller::SetVolume(float value)
{
if (fSoundOutput) // hack...
fSoundOutput->SetVolume(value);
}
bool
Controller::IsOverlayActive()
{
@@ -349,8 +358,9 @@ Controller::AudioPlayThread()
media_format fmt;
fmt.type = B_MEDIA_RAW_AUDIO;
fmt.u.raw_audio = media_multi_audio_format::wildcard;
#ifdef __HAIKU__
fmt.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT;
#endif
fAudioTrack->DecodedFormat(&fmt);
SoundOutput out(fName.String(), fmt.u.raw_audio);
@@ -360,9 +370,11 @@ Controller::AudioPlayThread()
int64 frames;
media_header mh;
fSoundOutput = &out;
while (!fStopAudioPlayback && B_OK == fAudioTrack->ReadFrames(buffer, &frames, &mh)) {
out.Play(buffer, frames * frame_size);
}
fSoundOutput = NULL;
}
+4
View File
@@ -27,6 +27,7 @@
class BBitmap;
class BMediaFile;
class BMediaTrack;
class SoundOutput;
class VideoView;
class Controller
@@ -63,6 +64,8 @@ public:
void VolumeUp();
void VolumeDown();
void SetVolume(float value);
private:
static int32 audio_play_thread(void *self);
@@ -95,6 +98,7 @@ private:
thread_id fVideoPlayThread;
volatile bool fStopAudioPlayback;
volatile bool fStopVideoPlayback;
SoundOutput * fSoundOutput;
};
+2 -2
View File
@@ -135,8 +135,8 @@ ControllerView::SkipForward()
void
ControllerView::SetVolume(float value)
{
printf("ControllerView::SetVolume(%.2f)\n", value);
// 0.0 ... 1.0
printf("ControllerView::SetVolume(%.4f)\n", value);
fController->SetVolume(value);
}
+73 -13
View File
@@ -40,8 +40,15 @@ enum {
#define VOLUME_MIN_WIDTH 70.0
#define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
#define kMaxVolume 1024
#define kMaxSeekPos 65535
// the range of the volume sliders (in dB)
#define kVolumeDbMax 6.0
#define kVolumeDbMin -60.0
// a power function for non linear sliders
#define kVolumeDbExpPositive 1.4 // for dB values > 0
#define kVolumeDbExpNegative 1.9 // for dB values < 0
#define kVolumeFactor 1000
#define kPositionFactor 65535
// constructor
TransportControlGroup::TransportControlGroup(BRect frame)
@@ -57,7 +64,7 @@ TransportControlGroup::TransportControlGroup(BRect frame)
// Seek Slider
fSeekSlider = new SeekSlider(frame, "seek slider",
new BMessage(MSG_SEEK),
0, kMaxSeekPos);
0, kPositionFactor);
fSeekSlider->ResizeToPreferred();
AddChild(fSeekSlider);
@@ -142,9 +149,11 @@ TransportControlGroup::TransportControlGroup(BRect frame)
// Volume Slider
fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
kVolumeSliderBitmapHeight - 1.0),
"volume slider", 0, kMaxVolume,
"volume slider",
_DbToGain(_ExponentialToLinear(kVolumeDbMin)) * kVolumeFactor,
_DbToGain(_ExponentialToLinear(kVolumeDbMax)) * kVolumeFactor,
new BMessage(MSG_SET_VOLUME));
fVolumeSlider->SetValue(128);
fVolumeSlider->SetValue(_DbToGain(_ExponentialToLinear(0.0)) * kVolumeFactor);
AddChild(fVolumeSlider);
}
@@ -252,6 +261,59 @@ void TransportControlGroup::SetVolume(float value) {}
void TransportControlGroup::ToggleMute() {}
void TransportControlGroup::SetPosition(float value) {}
// #pragma mark -
float
TransportControlGroup::_LinearToExponential(float db_in)
{
float db = db_in;
if (db >= 0) {
db = db * (pow(fabs(kVolumeDbMax), (1.0 / kVolumeDbExpPositive)) / fabs(kVolumeDbMax));
db = pow(db, kVolumeDbExpPositive);
} else {
db = -db;
db = db * (pow(fabs(kVolumeDbMin), (1.0 / kVolumeDbExpNegative)) / fabs(kVolumeDbMin));
db = pow(db, kVolumeDbExpNegative);
db = -db;
}
printf("_LinearToExponential %.4f => %.4f\n", db_in, db);
return db;
}
float
TransportControlGroup::_ExponentialToLinear(float db_in)
{
float db = db_in;
if (db >= 0) {
db = pow(db, (1.0 / kVolumeDbExpPositive));
db = db * (fabs(kVolumeDbMax) / pow(fabs(kVolumeDbMax), (1.0 / kVolumeDbExpPositive)));
} else {
db = -db;
db = pow(db, (1.0 / kVolumeDbExpNegative));
db = db * (fabs(kVolumeDbMin) / pow(fabs(kVolumeDbMin), (1.0 / kVolumeDbExpNegative)));
db = -db;
}
printf("_ExponentialToLinear %.4f => %.4f\n", db_in, db);
return db;
}
float
TransportControlGroup::_DbToGain(float db)
{
return pow(10.0, db / 20.0);
}
float
TransportControlGroup::_GainToDb(float gain)
{
return 20.0 * log10(gain);
}
// #pragma mark -
// SetEnabled
@@ -316,12 +378,6 @@ TransportControlGroup::SetMuted(bool mute)
fVolumeSlider->SetMuted(mute);
}
// Volume
uint32
TransportControlGroup::Volume() const
{
return fVolumeSlider->Value();
}
// #pragma mark -
@@ -473,7 +529,11 @@ TransportControlGroup::_SkipForward()
void
TransportControlGroup::_SetVolume()
{
SetVolume((float)(fVolumeSlider->Value() / 255.0));
float pos = fVolumeSlider->Value() / (float)kVolumeFactor;
float db = _ExponentialToLinear(_GainToDb(pos));
float gain = _DbToGain(db);
printf("_SetVolume: pos %.4f, db %.4f, gain %.4f\n", pos, db, gain);
SetVolume(gain);
}
// _ToggleMute
@@ -488,7 +548,7 @@ TransportControlGroup::_ToggleMute()
void
TransportControlGroup::_UpdatePosition()
{
SetPosition((float)(fSeekSlider->Value() / (float)kMaxSeekPos));
SetPosition(fSeekSlider->Value() / (float)kPositionFactor);
}
+5 -1
View File
@@ -67,7 +67,6 @@ class TransportControlGroup : public BView {
void SetAudioEnabled(bool enable);
void SetMuted(bool mute);
uint32 Volume() const;
private:
void _LayoutControls(BRect frame) const;
@@ -87,6 +86,11 @@ class TransportControlGroup : public BView {
void _ToggleMute();
void _UpdatePosition();
float _LinearToExponential(float db);
float _ExponentialToLinear(float db);
float _DbToGain(float db);
float _GainToDb(float gain);
SeekSlider* fSeekSlider;
VolumeSlider* fVolumeSlider;