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)
|
, fVideoPlayThread(-1)
|
||||||
, fStopAudioPlayback(false)
|
, fStopAudioPlayback(false)
|
||||||
, fStopVideoPlayback(false)
|
, fStopVideoPlayback(false)
|
||||||
|
, fSoundOutput(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +252,14 @@ Controller::VolumeDown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Controller::SetVolume(float value)
|
||||||
|
{
|
||||||
|
if (fSoundOutput) // hack...
|
||||||
|
fSoundOutput->SetVolume(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Controller::IsOverlayActive()
|
Controller::IsOverlayActive()
|
||||||
{
|
{
|
||||||
@@ -349,8 +358,9 @@ Controller::AudioPlayThread()
|
|||||||
media_format fmt;
|
media_format fmt;
|
||||||
fmt.type = B_MEDIA_RAW_AUDIO;
|
fmt.type = B_MEDIA_RAW_AUDIO;
|
||||||
fmt.u.raw_audio = media_multi_audio_format::wildcard;
|
fmt.u.raw_audio = media_multi_audio_format::wildcard;
|
||||||
|
#ifdef __HAIKU__
|
||||||
fmt.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT;
|
fmt.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT;
|
||||||
|
#endif
|
||||||
fAudioTrack->DecodedFormat(&fmt);
|
fAudioTrack->DecodedFormat(&fmt);
|
||||||
|
|
||||||
SoundOutput out(fName.String(), fmt.u.raw_audio);
|
SoundOutput out(fName.String(), fmt.u.raw_audio);
|
||||||
@@ -360,9 +370,11 @@ Controller::AudioPlayThread()
|
|||||||
int64 frames;
|
int64 frames;
|
||||||
media_header mh;
|
media_header mh;
|
||||||
|
|
||||||
|
fSoundOutput = &out;
|
||||||
while (!fStopAudioPlayback && B_OK == fAudioTrack->ReadFrames(buffer, &frames, &mh)) {
|
while (!fStopAudioPlayback && B_OK == fAudioTrack->ReadFrames(buffer, &frames, &mh)) {
|
||||||
out.Play(buffer, frames * frame_size);
|
out.Play(buffer, frames * frame_size);
|
||||||
}
|
}
|
||||||
|
fSoundOutput = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
class BBitmap;
|
class BBitmap;
|
||||||
class BMediaFile;
|
class BMediaFile;
|
||||||
class BMediaTrack;
|
class BMediaTrack;
|
||||||
|
class SoundOutput;
|
||||||
class VideoView;
|
class VideoView;
|
||||||
|
|
||||||
class Controller
|
class Controller
|
||||||
@@ -63,6 +64,8 @@ public:
|
|||||||
|
|
||||||
void VolumeUp();
|
void VolumeUp();
|
||||||
void VolumeDown();
|
void VolumeDown();
|
||||||
|
|
||||||
|
void SetVolume(float value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int32 audio_play_thread(void *self);
|
static int32 audio_play_thread(void *self);
|
||||||
@@ -95,6 +98,7 @@ private:
|
|||||||
thread_id fVideoPlayThread;
|
thread_id fVideoPlayThread;
|
||||||
volatile bool fStopAudioPlayback;
|
volatile bool fStopAudioPlayback;
|
||||||
volatile bool fStopVideoPlayback;
|
volatile bool fStopVideoPlayback;
|
||||||
|
SoundOutput * fSoundOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ ControllerView::SkipForward()
|
|||||||
void
|
void
|
||||||
ControllerView::SetVolume(float value)
|
ControllerView::SetVolume(float value)
|
||||||
{
|
{
|
||||||
printf("ControllerView::SetVolume(%.2f)\n", value);
|
printf("ControllerView::SetVolume(%.4f)\n", value);
|
||||||
// 0.0 ... 1.0
|
fController->SetVolume(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,15 @@ enum {
|
|||||||
#define VOLUME_MIN_WIDTH 70.0
|
#define VOLUME_MIN_WIDTH 70.0
|
||||||
#define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
|
#define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
|
||||||
|
|
||||||
#define kMaxVolume 1024
|
// the range of the volume sliders (in dB)
|
||||||
#define kMaxSeekPos 65535
|
#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
|
// constructor
|
||||||
TransportControlGroup::TransportControlGroup(BRect frame)
|
TransportControlGroup::TransportControlGroup(BRect frame)
|
||||||
@@ -57,7 +64,7 @@ TransportControlGroup::TransportControlGroup(BRect frame)
|
|||||||
// Seek Slider
|
// Seek Slider
|
||||||
fSeekSlider = new SeekSlider(frame, "seek slider",
|
fSeekSlider = new SeekSlider(frame, "seek slider",
|
||||||
new BMessage(MSG_SEEK),
|
new BMessage(MSG_SEEK),
|
||||||
0, kMaxSeekPos);
|
0, kPositionFactor);
|
||||||
fSeekSlider->ResizeToPreferred();
|
fSeekSlider->ResizeToPreferred();
|
||||||
AddChild(fSeekSlider);
|
AddChild(fSeekSlider);
|
||||||
|
|
||||||
@@ -142,9 +149,11 @@ TransportControlGroup::TransportControlGroup(BRect frame)
|
|||||||
// Volume Slider
|
// Volume Slider
|
||||||
fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
|
fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
|
||||||
kVolumeSliderBitmapHeight - 1.0),
|
kVolumeSliderBitmapHeight - 1.0),
|
||||||
"volume slider", 0, kMaxVolume,
|
"volume slider",
|
||||||
|
_DbToGain(_ExponentialToLinear(kVolumeDbMin)) * kVolumeFactor,
|
||||||
|
_DbToGain(_ExponentialToLinear(kVolumeDbMax)) * kVolumeFactor,
|
||||||
new BMessage(MSG_SET_VOLUME));
|
new BMessage(MSG_SET_VOLUME));
|
||||||
fVolumeSlider->SetValue(128);
|
fVolumeSlider->SetValue(_DbToGain(_ExponentialToLinear(0.0)) * kVolumeFactor);
|
||||||
AddChild(fVolumeSlider);
|
AddChild(fVolumeSlider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +261,59 @@ void TransportControlGroup::SetVolume(float value) {}
|
|||||||
void TransportControlGroup::ToggleMute() {}
|
void TransportControlGroup::ToggleMute() {}
|
||||||
void TransportControlGroup::SetPosition(float value) {}
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
// SetEnabled
|
// SetEnabled
|
||||||
@@ -316,12 +378,6 @@ TransportControlGroup::SetMuted(bool mute)
|
|||||||
fVolumeSlider->SetMuted(mute);
|
fVolumeSlider->SetMuted(mute);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
|
||||||
uint32
|
|
||||||
TransportControlGroup::Volume() const
|
|
||||||
{
|
|
||||||
return fVolumeSlider->Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
@@ -473,7 +529,11 @@ TransportControlGroup::_SkipForward()
|
|||||||
void
|
void
|
||||||
TransportControlGroup::_SetVolume()
|
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
|
// _ToggleMute
|
||||||
@@ -488,7 +548,7 @@ TransportControlGroup::_ToggleMute()
|
|||||||
void
|
void
|
||||||
TransportControlGroup::_UpdatePosition()
|
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 SetAudioEnabled(bool enable);
|
||||||
void SetMuted(bool mute);
|
void SetMuted(bool mute);
|
||||||
uint32 Volume() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _LayoutControls(BRect frame) const;
|
void _LayoutControls(BRect frame) const;
|
||||||
@@ -87,6 +86,11 @@ class TransportControlGroup : public BView {
|
|||||||
void _ToggleMute();
|
void _ToggleMute();
|
||||||
void _UpdatePosition();
|
void _UpdatePosition();
|
||||||
|
|
||||||
|
float _LinearToExponential(float db);
|
||||||
|
float _ExponentialToLinear(float db);
|
||||||
|
float _DbToGain(float db);
|
||||||
|
float _GainToDb(float gain);
|
||||||
|
|
||||||
SeekSlider* fSeekSlider;
|
SeekSlider* fSeekSlider;
|
||||||
|
|
||||||
VolumeSlider* fVolumeSlider;
|
VolumeSlider* fVolumeSlider;
|
||||||
|
|||||||
Reference in New Issue
Block a user