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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user