* now supports several audio formats for VUView and ScopeView
* cleanup git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31760 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,12 +9,13 @@
|
|||||||
#include "RecorderWindow.h"
|
#include "RecorderWindow.h"
|
||||||
|
|
||||||
|
|
||||||
RecorderApp::RecorderApp(const char * signature) :
|
RecorderApp::RecorderApp(const char* signature)
|
||||||
BApplication(signature), fRecorderWin(NULL)
|
: BApplication(signature), fRecorderWin(NULL)
|
||||||
{
|
{
|
||||||
fRecorderWin = new RecorderWindow();
|
fRecorderWin = new RecorderWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RecorderApp::~RecorderApp()
|
RecorderApp::~RecorderApp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
class RecorderWindow;
|
class RecorderWindow;
|
||||||
|
|
||||||
class RecorderApp : public BApplication {
|
class RecorderApp : public BApplication {
|
||||||
public:
|
public:
|
||||||
RecorderApp(const char * signature);
|
RecorderApp(const char * signature);
|
||||||
virtual ~RecorderApp();
|
virtual ~RecorderApp();
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
private:
|
private:
|
||||||
RecorderWindow* fRecorderWin;
|
RecorderWindow* fRecorderWin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RECORDERAPP_H */
|
#endif /* RECORDERAPP_H */
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
* Copyright 2005, Jérôme Duval. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers and Producers)
|
* Inspired by SoundCapture from Be newsletter (Media Kit Basics:
|
||||||
|
* Consumers and Producers)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
@@ -61,7 +62,8 @@ static const float MIN_HEIGHT = 336.0f;
|
|||||||
static const float XPOS = 100.0f;
|
static const float XPOS = 100.0f;
|
||||||
static const float YPOS = 200.0f;
|
static const float YPOS = 200.0f;
|
||||||
|
|
||||||
#define FOURCC(a,b,c,d) ((((uint32)(d)) << 24) | (((uint32)(c)) << 16) | (((uint32)(b)) << 8) | ((uint32)(a)))
|
#define FOURCC(a,b,c,d) ((((uint32)(d)) << 24) | (((uint32)(c)) << 16) \
|
||||||
|
| (((uint32)(b)) << 8) | ((uint32)(a)))
|
||||||
|
|
||||||
struct riff_struct
|
struct riff_struct
|
||||||
{
|
{
|
||||||
@@ -97,8 +99,8 @@ struct wave_struct
|
|||||||
|
|
||||||
|
|
||||||
RecorderWindow::RecorderWindow() :
|
RecorderWindow::RecorderWindow() :
|
||||||
BWindow(BRect(XPOS,YPOS,XPOS+MIN_WIDTH,YPOS+MIN_HEIGHT), "SoundRecorder", B_TITLED_WINDOW,
|
BWindow(BRect(XPOS,YPOS,XPOS+MIN_WIDTH,YPOS+MIN_HEIGHT), "SoundRecorder",
|
||||||
B_ASYNCHRONOUS_CONTROLS | B_NOT_V_RESIZABLE | B_NOT_ZOOMABLE),
|
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_V_RESIZABLE | B_NOT_ZOOMABLE),
|
||||||
fPlayer(NULL),
|
fPlayer(NULL),
|
||||||
fSoundList(NULL),
|
fSoundList(NULL),
|
||||||
fPlayFile(NULL),
|
fPlayFile(NULL),
|
||||||
@@ -135,7 +137,7 @@ RecorderWindow::RecorderWindow() :
|
|||||||
|
|
||||||
RecorderWindow::~RecorderWindow()
|
RecorderWindow::~RecorderWindow()
|
||||||
{
|
{
|
||||||
// The sound consumer and producer are Nodes; it has to be Release()d and the Roster
|
// The sound consumer and producer are Nodes; it has to be released and the Roster
|
||||||
// will reap it when it's done.
|
// will reap it when it's done.
|
||||||
if (fRecordNode) {
|
if (fRecordNode) {
|
||||||
fRecordNode->Release();
|
fRecordNode->Release();
|
||||||
@@ -154,9 +156,9 @@ RecorderWindow::~RecorderWindow()
|
|||||||
// Clean up items in list view.
|
// Clean up items in list view.
|
||||||
if (fSoundList) {
|
if (fSoundList) {
|
||||||
fSoundList->DeselectAll();
|
fSoundList->DeselectAll();
|
||||||
for (int ix=0; ix<fSoundList->CountItems(); ix++) {
|
for (int i = 0; i < fSoundList->CountItems(); i++) {
|
||||||
WINDOW((stderr, "clean up item %d\n", ix+1));
|
WINDOW((stderr, "clean up item %d\n", i+1));
|
||||||
SoundListItem * item = dynamic_cast<SoundListItem *>(fSoundList->ItemAt(ix));
|
SoundListItem* item = dynamic_cast<SoundListItem *>(fSoundList->ItemAt(i));
|
||||||
if (item) {
|
if (item) {
|
||||||
if (item->IsTemp()) {
|
if (item->IsTemp()) {
|
||||||
item->Entry().Remove(); // delete temp file
|
item->Entry().Remove(); // delete temp file
|
||||||
@@ -241,8 +243,8 @@ RecorderWindow::InitWindow()
|
|||||||
// Create the window header with controls
|
// Create the window header with controls
|
||||||
BRect r(Bounds());
|
BRect r(Bounds());
|
||||||
r.bottom = r.top + 175;
|
r.bottom = r.top + 175;
|
||||||
BBox *background = new BBox(r, "_background", B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
|
BBox *background = new BBox(r, "_background", B_FOLLOW_LEFT_RIGHT
|
||||||
B_WILL_DRAW|B_FRAME_EVENTS|B_NAVIGABLE_JUMP, B_NO_BORDER);
|
| B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP, B_NO_BORDER);
|
||||||
AddChild(background);
|
AddChild(background);
|
||||||
|
|
||||||
|
|
||||||
@@ -265,7 +267,8 @@ RecorderWindow::InitWindow()
|
|||||||
r.right -= 26;
|
r.right -= 26;
|
||||||
r.top = 115;
|
r.top = 115;
|
||||||
r.bottom = r.top + 30;
|
r.bottom = r.top + 30;
|
||||||
fTrackSlider = new TrackSlider(r, "trackSlider", new BMessage(POSITION_CHANGED), B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP);
|
fTrackSlider = new TrackSlider(r, "trackSlider", new BMessage(POSITION_CHANGED),
|
||||||
|
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||||
background->AddChild(fTrackSlider);
|
background->AddChild(fTrackSlider);
|
||||||
|
|
||||||
BRect buttonRect;
|
BRect buttonRect;
|
||||||
@@ -274,16 +277,16 @@ RecorderWindow::InitWindow()
|
|||||||
buttonRect = BRect(BPoint(0,0), kSkipButtonSize);
|
buttonRect = BRect(BPoint(0,0), kSkipButtonSize);
|
||||||
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-7, 25));
|
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-7, 25));
|
||||||
fRewindButton = new TransportButton(buttonRect, "Rewind",
|
fRewindButton = new TransportButton(buttonRect, "Rewind",
|
||||||
kSkipBackBitmapBits, kPressedSkipBackBitmapBits, kDisabledSkipBackBitmapBits,
|
kSkipBackBitmapBits, kPressedSkipBackBitmapBits,
|
||||||
new BMessage(REWIND));
|
kDisabledSkipBackBitmapBits, new BMessage(REWIND));
|
||||||
background->AddChild(fRewindButton);
|
background->AddChild(fRewindButton);
|
||||||
|
|
||||||
// Button for stopping recording or playback
|
// Button for stopping recording or playback
|
||||||
buttonRect = BRect(BPoint(0,0), kStopButtonSize);
|
buttonRect = BRect(BPoint(0,0), kStopButtonSize);
|
||||||
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-48, 25));
|
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-48, 25));
|
||||||
fStopButton = new TransportButton(buttonRect, "Stop",
|
fStopButton = new TransportButton(buttonRect, "Stop",
|
||||||
kStopButtonBitmapBits, kPressedStopButtonBitmapBits, kDisabledStopButtonBitmapBits,
|
kStopButtonBitmapBits, kPressedStopButtonBitmapBits,
|
||||||
new BMessage(STOP));
|
kDisabledStopButtonBitmapBits, new BMessage(STOP));
|
||||||
background->AddChild(fStopButton);
|
background->AddChild(fStopButton);
|
||||||
|
|
||||||
// Button for starting playback of selected sound
|
// Button for starting playback of selected sound
|
||||||
@@ -297,8 +300,8 @@ RecorderWindow::InitWindow()
|
|||||||
buttonRect = BRect(BPoint(0,0), kSkipButtonSize);
|
buttonRect = BRect(BPoint(0,0), kSkipButtonSize);
|
||||||
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-133, 25));
|
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-133, 25));
|
||||||
fForwardButton = new TransportButton(buttonRect, "Forward",
|
fForwardButton = new TransportButton(buttonRect, "Forward",
|
||||||
kSkipForwardBitmapBits, kPressedSkipForwardBitmapBits, kDisabledSkipForwardBitmapBits,
|
kSkipForwardBitmapBits, kPressedSkipForwardBitmapBits,
|
||||||
new BMessage(FORWARD));
|
kDisabledSkipForwardBitmapBits, new BMessage(FORWARD));
|
||||||
background->AddChild(fForwardButton);
|
background->AddChild(fForwardButton);
|
||||||
|
|
||||||
// Button to start recording (or waiting for sound)
|
// Button to start recording (or waiting for sound)
|
||||||
@@ -312,7 +315,8 @@ RecorderWindow::InitWindow()
|
|||||||
buttonRect = BRect(BPoint(0,0), kDiskButtonSize);
|
buttonRect = BRect(BPoint(0,0), kDiskButtonSize);
|
||||||
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-250, 21));
|
buttonRect.OffsetTo(background->Bounds().LeftBottom() - BPoint(-250, 21));
|
||||||
fSaveButton = new TransportButton(buttonRect, "Save",
|
fSaveButton = new TransportButton(buttonRect, "Save",
|
||||||
kDiskButtonBitmapsBits, kPressedDiskButtonBitmapsBits, kDisabledDiskButtonBitmapsBits, new BMessage(SAVE));
|
kDiskButtonBitmapsBits, kPressedDiskButtonBitmapsBits,
|
||||||
|
kDisabledDiskButtonBitmapsBits, new BMessage(SAVE));
|
||||||
fSaveButton->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
fSaveButton->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
||||||
background->AddChild(fSaveButton);
|
background->AddChild(fSaveButton);
|
||||||
|
|
||||||
@@ -327,13 +331,15 @@ RecorderWindow::InitWindow()
|
|||||||
|
|
||||||
buttonRect = BRect(BPoint(0,0), kSpeakerIconBitmapSize);
|
buttonRect = BRect(BPoint(0,0), kSpeakerIconBitmapSize);
|
||||||
buttonRect.OffsetTo(background->Bounds().RightBottom() - BPoint(121, 17));
|
buttonRect.OffsetTo(background->Bounds().RightBottom() - BPoint(121, 17));
|
||||||
SpeakerView *speakerView = new SpeakerView(buttonRect, B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
SpeakerView *speakerView = new SpeakerView(buttonRect,
|
||||||
|
B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
||||||
speakerView->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
speakerView->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
||||||
background->AddChild(speakerView);
|
background->AddChild(speakerView);
|
||||||
|
|
||||||
buttonRect = BRect(BPoint(0,0), BPoint(84, 19));
|
buttonRect = BRect(BPoint(0,0), BPoint(84, 19));
|
||||||
buttonRect.OffsetTo(background->Bounds().RightBottom() - BPoint(107, 20));
|
buttonRect.OffsetTo(background->Bounds().RightBottom() - BPoint(107, 20));
|
||||||
fVolumeSlider = new VolumeSlider(buttonRect, "volumeSlider", B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
fVolumeSlider = new VolumeSlider(buttonRect, "volumeSlider",
|
||||||
|
B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
||||||
fVolumeSlider->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
fVolumeSlider->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
||||||
background->AddChild(fVolumeSlider);
|
background->AddChild(fVolumeSlider);
|
||||||
|
|
||||||
@@ -362,8 +368,8 @@ RecorderWindow::InitWindow()
|
|||||||
fSoundList = new SoundListView(r, "Sound List", B_FOLLOW_ALL);
|
fSoundList = new SoundListView(r, "Sound List", B_FOLLOW_ALL);
|
||||||
fSoundList->SetSelectionMessage(new BMessage(SOUND_SELECTED));
|
fSoundList->SetSelectionMessage(new BMessage(SOUND_SELECTED));
|
||||||
fSoundList->SetViewColor(216, 216, 216);
|
fSoundList->SetViewColor(216, 216, 216);
|
||||||
BScrollView *scroller = new BScrollView("scroller", fSoundList, B_FOLLOW_ALL,
|
BScrollView *scroller = new BScrollView("scroller", fSoundList,
|
||||||
0, false, true, B_FANCY_BORDER);
|
B_FOLLOW_ALL, 0, false, true, B_FANCY_BORDER);
|
||||||
fBottomBox->AddChild(scroller);
|
fBottomBox->AddChild(scroller);
|
||||||
|
|
||||||
r = fBottomBox->Bounds();
|
r = fBottomBox->Bounds();
|
||||||
@@ -425,18 +431,19 @@ RecorderWindow::InitWindow()
|
|||||||
char selected_name[B_MEDIA_NAME_LENGTH] = "Default Input";
|
char selected_name[B_MEDIA_NAME_LENGTH] = "Default Input";
|
||||||
BMessage * msg;
|
BMessage * msg;
|
||||||
BMenuItem * item;
|
BMenuItem * item;
|
||||||
for (int ix=0; ix<real_count; ix++) {
|
for (int i = 0; i < real_count; i++) {
|
||||||
msg = new BMessage(INPUT_SELECTED);
|
msg = new BMessage(INPUT_SELECTED);
|
||||||
msg->AddData("node", B_RAW_TYPE, &dni[ix], sizeof(dni[ix]));
|
msg->AddData("node", B_RAW_TYPE, &dni[i], sizeof(dni[i]));
|
||||||
item = new BMenuItem(dni[ix].name, msg);
|
item = new BMenuItem(dni[i].name, msg);
|
||||||
popup->AddItem(item);
|
popup->AddItem(item);
|
||||||
media_node_id ni[12];
|
media_node_id ni[12];
|
||||||
int32 ni_count = 12;
|
int32 ni_count = 12;
|
||||||
error = fRoster->GetInstancesFor(dni[ix].addon, dni[ix].flavor_id, ni, &ni_count);
|
error = fRoster->GetInstancesFor(dni[i].addon, dni[i].flavor_id,
|
||||||
|
ni, &ni_count);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
for (int iy=0; iy<ni_count; iy++)
|
for (int j = 0; j < ni_count; j++)
|
||||||
if (ni[iy] == fAudioInputNode.node) {
|
if (ni[j] == fAudioInputNode.node) {
|
||||||
strcpy(selected_name, dni[ix].name);
|
strcpy(selected_name, dni[i].name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,7 +579,8 @@ RecorderWindow::MessageReceived(BMessage * message)
|
|||||||
}
|
}
|
||||||
if (message->FindInt64("right", &right) == B_OK) {
|
if (message->FindInt64("right", &right) == B_OK) {
|
||||||
if (fPlayTrack)
|
if (fPlayTrack)
|
||||||
fPlayLimit = MIN(fPlayFrames, (off_t)(right * fPlayFormat.u.raw_audio.frame_rate/1000000LL));
|
fPlayLimit = MIN(fPlayFrames,
|
||||||
|
(off_t)(right * fPlayFormat.u.raw_audio.frame_rate/1000000LL));
|
||||||
fScopeView->SetRightTime(right);
|
fScopeView->SetRightTime(right);
|
||||||
}
|
}
|
||||||
if (message->FindInt64("left", &left) == B_OK) {
|
if (message->FindInt64("left", &left) == B_OK) {
|
||||||
@@ -632,7 +640,8 @@ RecorderWindow::Record(BMessage * message)
|
|||||||
}
|
}
|
||||||
// Reserve space on disk (creates fewer fragments)
|
// Reserve space on disk (creates fewer fragments)
|
||||||
err = fRecFile.SetSize(4 * fRecordFormat.u.raw_audio.channel_count
|
err = fRecFile.SetSize(4 * fRecordFormat.u.raw_audio.channel_count
|
||||||
* fRecordFormat.u.raw_audio.frame_rate * (fRecordFormat.u.raw_audio.format & 0xf));
|
* fRecordFormat.u.raw_audio.frame_rate * (fRecordFormat.u.raw_audio.format
|
||||||
|
& media_raw_audio_format::B_AUDIO_SIZE_MASK));
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
ErrorAlert("record a sound that long", err);
|
ErrorAlert("record a sound that long", err);
|
||||||
fRecEntry.Remove();
|
fRecEntry.Remove();
|
||||||
@@ -653,10 +662,11 @@ RecorderWindow::Record(BMessage * message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And get it going...
|
// And get it going...
|
||||||
bigtime_t then = fRecordNode->TimeSource()->Now()+50000LL;
|
bigtime_t then = fRecordNode->TimeSource()->Now() + 50000LL;
|
||||||
fRoster->StartNode(fRecordNode->Node(), then);
|
fRoster->StartNode(fRecordNode->Node(), then);
|
||||||
if (fAudioInputNode.kind & B_TIME_SOURCE) {
|
if (fAudioInputNode.kind & B_TIME_SOURCE) {
|
||||||
fRoster->StartNode(fAudioInputNode, fRecordNode->TimeSource()->RealTimeFor(then, 0));
|
fRoster->StartNode(fAudioInputNode,
|
||||||
|
fRecordNode->TimeSource()->RealTimeFor(then, 0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fRoster->StartNode(fAudioInputNode, then);
|
fRoster->StartNode(fAudioInputNode, then);
|
||||||
@@ -684,7 +694,8 @@ RecorderWindow::Play(BMessage * message)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fPlayLimit = MIN(fPlayFrames, (off_t)(fTrackSlider->RightTime() * fPlayFormat.u.raw_audio.frame_rate / 1000000LL));
|
fPlayLimit = MIN(fPlayFrames, (off_t)(fTrackSlider->RightTime()
|
||||||
|
* fPlayFormat.u.raw_audio.frame_rate / 1000000LL));
|
||||||
fPlayTrack->SeekToTime(fTrackSlider->MainTime());
|
fPlayTrack->SeekToTime(fTrackSlider->MainTime());
|
||||||
fPlayFrame = fPlayTrack->CurrentFrame();
|
fPlayFrame = fPlayTrack->CurrentFrame();
|
||||||
|
|
||||||
@@ -813,7 +824,8 @@ RecorderWindow::Selected(BMessage * message)
|
|||||||
return;
|
return;
|
||||||
status_t err = UpdatePlayFile(pItem, true);
|
status_t err = UpdatePlayFile(pItem, true);
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
ErrorAlert("recognize this file as a media file", err == B_MEDIA_NO_HANDLER ? B_OK : err);
|
ErrorAlert("recognize this file as a media file",
|
||||||
|
err == B_MEDIA_NO_HANDLER ? B_OK : err);
|
||||||
RemoveCurrentSoundItem();
|
RemoveCurrentSoundItem();
|
||||||
}
|
}
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
@@ -828,11 +840,13 @@ RecorderWindow::MakeRecordConnection(const media_node & input)
|
|||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
status_t err = fRoster->GetFreeOutputsFor(input, &fAudioOutput, 1, &count, B_MEDIA_RAW_AUDIO);
|
status_t err = fRoster->GetFreeOutputsFor(input, &fAudioOutput, 1, &count, B_MEDIA_RAW_AUDIO);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): couldn't get free outputs from audio input node\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" couldn't get free outputs from audio input node\n"));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (count < 1) {
|
if (count < 1) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): no free outputs from audio input node\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" no free outputs from audio input node\n"));
|
||||||
return B_BUSY;
|
return B_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,11 +857,13 @@ RecorderWindow::MakeRecordConnection(const media_node & input)
|
|||||||
// TODO: explain this
|
// TODO: explain this
|
||||||
err = fRoster->GetFreeInputsFor(fRecordNode->Node(), &fRecInput, 1, &count, B_MEDIA_RAW_AUDIO);
|
err = fRoster->GetFreeInputsFor(fRecordNode->Node(), &fRecInput, 1, &count, B_MEDIA_RAW_AUDIO);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): couldn't get free inputs for sound recorder\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" couldn't get free inputs for sound recorder\n"));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (count < 1) {
|
if (count < 1) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): no free inputs for sound recorder\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" no free inputs for sound recorder\n"));
|
||||||
return B_BUSY;
|
return B_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,14 +879,16 @@ RecorderWindow::MakeRecordConnection(const media_node & input)
|
|||||||
media_node use_time_source;
|
media_node use_time_source;
|
||||||
BTimeSource * tsobj = fRoster->MakeTimeSourceFor(input);
|
BTimeSource * tsobj = fRoster->MakeTimeSourceFor(input);
|
||||||
if (! tsobj) {
|
if (! tsobj) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): couldn't clone time source from audio input node\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" couldn't clone time source from audio input node\n"));
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the time source in effect to our own Node.
|
// Apply the time source in effect to our own Node.
|
||||||
err = fRoster->SetTimeSourceFor(fRecordNode->Node().node, tsobj->Node().node);
|
err = fRoster->SetTimeSourceFor(fRecordNode->Node().node, tsobj->Node().node);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): couldn't set the sound recorder's time source\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" couldn't set the sound recorder's time source\n"));
|
||||||
tsobj->Release();
|
tsobj->Release();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -882,7 +900,8 @@ RecorderWindow::MakeRecordConnection(const media_node & input)
|
|||||||
// Tell the consumer where we want data to go.
|
// Tell the consumer where we want data to go.
|
||||||
err = fRecordNode->SetHooks(RecordFile, NotifyRecordFile, this);
|
err = fRecordNode->SetHooks(RecordFile, NotifyRecordFile, this);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): couldn't set the sound recorder's hook functions\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" couldn't set the sound recorder's hook functions\n"));
|
||||||
tsobj->Release();
|
tsobj->Release();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -890,7 +909,8 @@ RecorderWindow::MakeRecordConnection(const media_node & input)
|
|||||||
// Using the same structs for input and output is OK in BMediaRoster::Connect().
|
// Using the same structs for input and output is OK in BMediaRoster::Connect().
|
||||||
err = fRoster->Connect(fAudioOutput.source, fRecInput.destination, &fRecordFormat, &fAudioOutput, &fRecInput);
|
err = fRoster->Connect(fAudioOutput.source, fRecInput.destination, &fRecordFormat, &fAudioOutput, &fRecInput);
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
CONNECT((stderr, "RecorderWindow::MakeRecordConnection(): failed to connect sound recorder to audio input node.\n"));
|
CONNECT((stderr, "RecorderWindow::MakeRecordConnection():"
|
||||||
|
" failed to connect sound recorder to audio input node.\n"));
|
||||||
tsobj->Release();
|
tsobj->Release();
|
||||||
fRecordNode->SetHooks(0, 0, 0);
|
fRecordNode->SetHooks(0, 0, 0);
|
||||||
return err;
|
return err;
|
||||||
@@ -913,7 +933,8 @@ RecorderWindow::BreakRecordConnection()
|
|||||||
// If we are the last connection, the Node will stop automatically since it
|
// If we are the last connection, the Node will stop automatically since it
|
||||||
// has nowhere to send data to.
|
// has nowhere to send data to.
|
||||||
err = fRoster->StopNode(fRecInput.node, 0);
|
err = fRoster->StopNode(fRecInput.node, 0);
|
||||||
err = fRoster->Disconnect(fAudioOutput.node.node, fAudioOutput.source, fRecInput.node.node, fRecInput.destination);
|
err = fRoster->Disconnect(fAudioOutput.node.node, fAudioOutput.source,
|
||||||
|
fRecInput.node.node, fRecInput.destination);
|
||||||
fAudioOutput.source = media_source::null;
|
fAudioOutput.source = media_source::null;
|
||||||
fRecInput.destination = media_destination::null;
|
fRecInput.destination = media_destination::null;
|
||||||
return err;
|
return err;
|
||||||
@@ -1175,8 +1196,8 @@ RecorderWindow::RemoveCurrentSoundItem() {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RecorderWindow::RecordFile(void * cookie, bigtime_t timestamp,
|
RecorderWindow::RecordFile(void* cookie, bigtime_t timestamp,
|
||||||
void * data, size_t size, const media_raw_audio_format & format)
|
void* data, size_t size, const media_raw_audio_format &format)
|
||||||
{
|
{
|
||||||
// Callback called from the SoundConsumer when receiving buffers.
|
// Callback called from the SoundConsumer when receiving buffers.
|
||||||
RecorderWindow * window = (RecorderWindow *)cookie;
|
RecorderWindow * window = (RecorderWindow *)cookie;
|
||||||
@@ -1185,7 +1206,7 @@ RecorderWindow::RecordFile(void * cookie, bigtime_t timestamp,
|
|||||||
// Write the data to file (we don't buffer or guard file access
|
// Write the data to file (we don't buffer or guard file access
|
||||||
// or anything)
|
// or anything)
|
||||||
window->fRecFile.WriteAt(window->fRecSize, data, size);
|
window->fRecFile.WriteAt(window->fRecSize, data, size);
|
||||||
window->fVUView->ComputeNextLevel(data, size);
|
window->fVUView->ComputeLevels(data, size, format.format);
|
||||||
window->fRecSize += size;
|
window->fRecSize += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1204,7 +1225,8 @@ RecorderWindow::NotifyRecordFile(void * cookie, int32 code, ...)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RecorderWindow::PlayFile(void * cookie, void * data, size_t size, const media_raw_audio_format & format)
|
RecorderWindow::PlayFile(void * cookie, void * data, size_t size,
|
||||||
|
const media_raw_audio_format & format)
|
||||||
{
|
{
|
||||||
// Callback called from the SoundProducer when producing buffers.
|
// Callback called from the SoundProducer when producing buffers.
|
||||||
RecorderWindow * window = (RecorderWindow *)cookie;
|
RecorderWindow * window = (RecorderWindow *)cookie;
|
||||||
@@ -1219,7 +1241,7 @@ RecorderWindow::PlayFile(void * cookie, void * data, size_t size, const media_ra
|
|||||||
}
|
}
|
||||||
int64 frames = 0;
|
int64 frames = 0;
|
||||||
window->fPlayTrack->ReadFrames(data, &frames);
|
window->fPlayTrack->ReadFrames(data, &frames);
|
||||||
window->fVUView->ComputeNextLevel(data, size/frame_size);
|
window->fVUView->ComputeLevels(data, size / frame_size, format.format);
|
||||||
window->fPlayFrame += size/frame_size;
|
window->fPlayFrame += size/frame_size;
|
||||||
window->PostMessage(UPDATE_TRACKSLIDER);
|
window->PostMessage(UPDATE_TRACKSLIDER);
|
||||||
} else {
|
} else {
|
||||||
@@ -1229,7 +1251,8 @@ RecorderWindow::PlayFile(void * cookie, void * data, size_t size, const media_ra
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RecorderWindow::NotifyPlayFile(void * cookie, BSoundPlayer::sound_player_notification code, ...)
|
RecorderWindow::NotifyPlayFile(void * cookie,
|
||||||
|
BSoundPlayer::sound_player_notification code, ...)
|
||||||
{
|
{
|
||||||
if ((code == BSoundPlayer::B_STOPPED) || (code == BSoundPlayer::B_SOUND_DONE)) {
|
if ((code == BSoundPlayer::B_STOPPED) || (code == BSoundPlayer::B_SOUND_DONE)) {
|
||||||
RecorderWindow * window = (RecorderWindow *)cookie;
|
RecorderWindow * window = (RecorderWindow *)cookie;
|
||||||
@@ -1300,7 +1323,8 @@ RecorderWindow::CopyTarget(BMessage *msg)
|
|||||||
|
|
||||||
// write data
|
// write data
|
||||||
bigtime_t diffTime = fTrackSlider->RightTime() - fTrackSlider->LeftTime();
|
bigtime_t diffTime = fTrackSlider->RightTime() - fTrackSlider->LeftTime();
|
||||||
int64 framesToWrite = (int64) (diffTime * fPlayFormat.u.raw_audio.frame_rate / 1000000LL);
|
int64 framesToWrite = (int64) (diffTime
|
||||||
|
* fPlayFormat.u.raw_audio.frame_rate / 1000000LL);
|
||||||
int32 frameSize = (fPlayFormat.u.raw_audio.format & 0xf)
|
int32 frameSize = (fPlayFormat.u.raw_audio.format & 0xf)
|
||||||
* fPlayFormat.u.raw_audio.channel_count;
|
* fPlayFormat.u.raw_audio.channel_count;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
* Copyright 2005, Jérôme Duval. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers and Producers)
|
* Inspired by SoundCapture from Be newsletter (Media Kit Basics:
|
||||||
|
* Consumers and Producers)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -14,6 +15,8 @@
|
|||||||
#include "DrawingTidbits.h"
|
#include "DrawingTidbits.h"
|
||||||
#include "ScopeView.h"
|
#include "ScopeView.h"
|
||||||
|
|
||||||
|
#define SAMPLES_COUNT 20000
|
||||||
|
|
||||||
//#define TRACE 1
|
//#define TRACE 1
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
#define TRACE(x...) printf(x)
|
#define TRACE(x...) printf(x)
|
||||||
@@ -28,13 +31,11 @@ ScopeView::ScopeView(BRect rect, uint32 resizeFlags)
|
|||||||
fBitmapView(NULL),
|
fBitmapView(NULL),
|
||||||
fIsRendering(false),
|
fIsRendering(false),
|
||||||
fMediaTrack(NULL),
|
fMediaTrack(NULL),
|
||||||
fQuitting(false),
|
|
||||||
fMainTime(0),
|
fMainTime(0),
|
||||||
fRightTime(1000000),
|
fRightTime(1000000),
|
||||||
fLeftTime(0),
|
fLeftTime(0),
|
||||||
fTotalTime(1000000)
|
fTotalTime(1000000)
|
||||||
{
|
{
|
||||||
fRenderSem = create_sem(0, "scope rendering");
|
|
||||||
fHeight = Bounds().Height();
|
fHeight = Bounds().Height();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ ScopeView::Draw(BRect updateRect)
|
|||||||
|
|
||||||
float x = 2;
|
float x = 2;
|
||||||
if (fTotalTime !=0)
|
if (fTotalTime !=0)
|
||||||
x = 2 + (fMainTime - fLeftTime) * (bounds.right - 2) / (fRightTime - fLeftTime);
|
x += (fMainTime - fLeftTime) * (bounds.right - 2)
|
||||||
|
/ (fRightTime - fLeftTime);
|
||||||
SetHighColor(60,255,40);
|
SetHighColor(60,255,40);
|
||||||
StrokeLine(BPoint(x, bounds.top), BPoint(x, bounds.bottom));
|
StrokeLine(BPoint(x, bounds.top), BPoint(x, bounds.bottom));
|
||||||
|
|
||||||
@@ -86,7 +88,9 @@ ScopeView::Draw(BRect updateRect)
|
|||||||
void
|
void
|
||||||
ScopeView::Run()
|
ScopeView::Run()
|
||||||
{
|
{
|
||||||
fThreadId = spawn_thread(&RenderLaunch, "Scope view", B_NORMAL_PRIORITY, this);
|
fRenderSem = create_sem(0, "scope rendering");
|
||||||
|
fThreadId = spawn_thread(&RenderLaunch, "Scope view", B_NORMAL_PRIORITY,
|
||||||
|
this);
|
||||||
if (fThreadId < 0)
|
if (fThreadId < 0)
|
||||||
return;
|
return;
|
||||||
resume_thread(fThreadId);
|
resume_thread(fThreadId);
|
||||||
@@ -96,7 +100,6 @@ void
|
|||||||
ScopeView::Quit()
|
ScopeView::Quit()
|
||||||
{
|
{
|
||||||
delete_sem(fRenderSem);
|
delete_sem(fRenderSem);
|
||||||
fQuitting = true;
|
|
||||||
snooze(10000);
|
snooze(10000);
|
||||||
kill_thread(fThreadId);
|
kill_thread(fThreadId);
|
||||||
}
|
}
|
||||||
@@ -112,51 +115,80 @@ ScopeView::RenderLaunch(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
void
|
||||||
|
ScopeView::ComputeRendering()
|
||||||
|
{
|
||||||
|
int64 framesCount = fMediaTrack->CountFrames() / SAMPLES_COUNT;
|
||||||
|
T samples[fPlayFormat.u.raw_audio.buffer_size / (fPlayFormat.u.raw_audio.format
|
||||||
|
& media_raw_audio_format::B_AUDIO_SIZE_MASK)];
|
||||||
|
int64 frames = 0;
|
||||||
|
U sum = 0;
|
||||||
|
int64 sumCount = 0;
|
||||||
|
float middle = fHeight / 2;
|
||||||
|
int32 previewMax = 0;
|
||||||
|
//fMediaTrack->SeekToFrame(&frames);
|
||||||
|
|
||||||
|
TRACE("begin computing\n");
|
||||||
|
|
||||||
|
int32 previewIndex = 0;
|
||||||
|
|
||||||
|
while (fIsRendering && fMediaTrack->ReadFrames(samples, &frames) == B_OK) {
|
||||||
|
//TRACE("reading block\n");
|
||||||
|
int64 framesIndex = 0;
|
||||||
|
|
||||||
|
while (framesIndex < frames) {
|
||||||
|
for (; framesIndex < frames && sumCount < framesCount;
|
||||||
|
framesIndex++, sumCount++) {
|
||||||
|
sum += samples[2 * framesIndex];
|
||||||
|
sum += samples[2 * framesIndex + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previewIndex >= SAMPLES_COUNT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (sumCount >= framesCount) {
|
||||||
|
//TRACE("computing block %ld, sumCount %ld\n", previewIndex, sumCount);
|
||||||
|
fPreview[previewIndex] = (int32)(sum
|
||||||
|
/ fPlayFormat.u.raw_audio.channel_count / framesCount);
|
||||||
|
if (previewMax < fPreview[previewIndex])
|
||||||
|
previewMax = fPreview[previewIndex];
|
||||||
|
sumCount = 0;
|
||||||
|
sum = 0;
|
||||||
|
previewIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SAMPLES_COUNT; i++)
|
||||||
|
fPreview[i] = (int32)(fPreview[i] * 1.0 / previewMax * middle + middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ScopeView::RenderLoop()
|
ScopeView::RenderLoop()
|
||||||
{
|
{
|
||||||
while (!fQuitting) {
|
while (acquire_sem(fRenderSem) == B_OK) {
|
||||||
if (acquire_sem(fRenderSem)!=B_OK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fIsRendering = true;
|
fIsRendering = true;
|
||||||
|
|
||||||
//int32 frameSize = (fPlayFormat.u.raw_audio.format & 0xf) * fPlayFormat.u.raw_audio.channel_count;
|
|
||||||
int64 totalFrames = fMediaTrack->CountFrames();
|
|
||||||
int16 samples[fPlayFormat.u.raw_audio.buffer_size / (fPlayFormat.u.raw_audio.format & 0xf)];
|
|
||||||
int64 frames = 0;
|
|
||||||
int64 sum = 0;
|
|
||||||
int64 framesIndex = 0;
|
|
||||||
int32 sumCount = 0;
|
|
||||||
fMediaTrack->SeekToFrame(&frames);
|
|
||||||
|
|
||||||
TRACE("begin computing\n");
|
|
||||||
|
|
||||||
int32 previewIndex = 0;
|
|
||||||
|
|
||||||
while (fIsRendering && fMediaTrack->ReadFrames(samples, &frames) == B_OK) {
|
|
||||||
//TRACE("reading block\n");
|
|
||||||
framesIndex = 0;
|
|
||||||
|
|
||||||
while (framesIndex < frames) {
|
|
||||||
for (; framesIndex < frames && sumCount < totalFrames/20000; framesIndex++, sumCount++) {
|
|
||||||
sum += samples[2*framesIndex];
|
|
||||||
sum += samples[2*framesIndex+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previewIndex >= 20000) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sumCount >= totalFrames/20000) {
|
|
||||||
//TRACE("computing block %ld, sumCount %ld\n", previewIndex, sumCount);
|
|
||||||
fPreview[previewIndex++] = (int32)(sum / 2 /(totalFrames/20000) / 32767.0 * fHeight / 2 + fHeight / 2);
|
|
||||||
sumCount = 0;
|
|
||||||
sum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (fPlayFormat.u.raw_audio.format) {
|
||||||
|
case media_raw_audio_format::B_AUDIO_FLOAT:
|
||||||
|
ComputeRendering<float, float>();
|
||||||
|
break;
|
||||||
|
case media_raw_audio_format::B_AUDIO_INT:
|
||||||
|
ComputeRendering<int32, int64>();
|
||||||
|
break;
|
||||||
|
case media_raw_audio_format::B_AUDIO_SHORT:
|
||||||
|
ComputeRendering<int16, int64>();
|
||||||
|
break;
|
||||||
|
case media_raw_audio_format::B_AUDIO_UCHAR:
|
||||||
|
ComputeRendering<uchar, uint32>();
|
||||||
|
break;
|
||||||
|
case media_raw_audio_format::B_AUDIO_CHAR:
|
||||||
|
ComputeRendering<char, int32>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("finished computing, rendering\n");
|
TRACE("finished computing, rendering\n");
|
||||||
|
|
||||||
/* rendering */
|
/* rendering */
|
||||||
@@ -223,7 +255,7 @@ ScopeView::RenderTrack(BMediaTrack *track, media_format format)
|
|||||||
{
|
{
|
||||||
fMediaTrack = track;
|
fMediaTrack = track;
|
||||||
fPlayFormat = format;
|
fPlayFormat = format;
|
||||||
release_sem(fRenderSem);
|
release_sem(fRenderSem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -304,7 +336,8 @@ ScopeView::InitBitmap()
|
|||||||
|
|
||||||
rect.OffsetToSelf(B_ORIGIN);
|
rect.OffsetToSelf(B_ORIGIN);
|
||||||
rect.right -= 2;
|
rect.right -= 2;
|
||||||
fBitmapView = new BView(rect.OffsetToSelf(B_ORIGIN), "bitmapView", B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW);
|
fBitmapView = new BView(rect.OffsetToSelf(B_ORIGIN), "bitmapView",
|
||||||
|
B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW);
|
||||||
fBitmap->AddChild(fBitmapView);
|
fBitmap->AddChild(fBitmapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,11 +355,14 @@ ScopeView::RenderBitmap()
|
|||||||
|
|
||||||
fBitmapView->SetDrawingMode(B_OP_ADD);
|
fBitmapView->SetDrawingMode(B_OP_ADD);
|
||||||
fBitmapView->SetHighColor(15,60,15);
|
fBitmapView->SetHighColor(15,60,15);
|
||||||
int32 leftIndex = (fTotalTime != 0) ? fLeftTime * 20000 / fTotalTime : 0;
|
int32 leftIndex =
|
||||||
int32 rightIndex = (fTotalTime != 0) ? fRightTime * 20000 / fTotalTime : 20000;
|
(fTotalTime != 0) ? fLeftTime * 20000 / fTotalTime : 0;
|
||||||
|
int32 rightIndex =
|
||||||
|
(fTotalTime != 0) ? fRightTime * 20000 / fTotalTime : 20000;
|
||||||
|
|
||||||
for (int32 i = leftIndex; i<rightIndex; i++) {
|
for (int32 i = leftIndex; i<rightIndex; i++) {
|
||||||
BPoint point((i - leftIndex) * width / (rightIndex - leftIndex), fPreview[i]);
|
BPoint point((i - leftIndex) * width / (rightIndex - leftIndex),
|
||||||
|
fPreview[i]);
|
||||||
//TRACE("point x %f y %f\n", point.x, point.y);
|
//TRACE("point x %f y %f\n", point.x, point.y);
|
||||||
fBitmapView->StrokeLine(point, point);
|
fBitmapView->StrokeLine(point, point);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ private:
|
|||||||
void Quit();
|
void Quit();
|
||||||
static int32 RenderLaunch(void *data);
|
static int32 RenderLaunch(void *data);
|
||||||
void RenderLoop();
|
void RenderLoop();
|
||||||
|
template<typename T, typename U> void ComputeRendering();
|
||||||
void RenderBitmap();
|
void RenderBitmap();
|
||||||
void InitBitmap();
|
void InitBitmap();
|
||||||
|
|
||||||
@@ -45,7 +46,6 @@ private:
|
|||||||
BMediaTrack *fMediaTrack;
|
BMediaTrack *fMediaTrack;
|
||||||
media_format fPlayFormat;
|
media_format fPlayFormat;
|
||||||
|
|
||||||
bool fQuitting;
|
|
||||||
bigtime_t fMainTime;
|
bigtime_t fMainTime;
|
||||||
bigtime_t fRightTime;
|
bigtime_t fRightTime;
|
||||||
bigtime_t fLeftTime;
|
bigtime_t fLeftTime;
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ TrackSlider::AttachedToWindow()
|
|||||||
{
|
{
|
||||||
BControl::AttachedToWindow();
|
BControl::AttachedToWindow();
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
InitBitmap();
|
_InitBitmap();
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::InitBitmap()
|
TrackSlider::_InitBitmap()
|
||||||
{
|
{
|
||||||
if (fBitmapView) {
|
if (fBitmapView) {
|
||||||
fBitmap->RemoveChild(fBitmapView);
|
fBitmap->RemoveChild(fBitmapView);
|
||||||
@@ -83,7 +83,7 @@ TrackSlider::InitBitmap()
|
|||||||
#define SLIDER_BASE 10
|
#define SLIDER_BASE 10
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::RenderBitmap()
|
TrackSlider::_RenderBitmap()
|
||||||
{
|
{
|
||||||
/* rendering */
|
/* rendering */
|
||||||
if (fBitmap->Lock()) {
|
if (fBitmap->Lock()) {
|
||||||
@@ -98,20 +98,20 @@ TrackSlider::Draw(BRect updateRect)
|
|||||||
{
|
{
|
||||||
DrawBitmapAsync(fBitmap, BPoint(0,0));
|
DrawBitmapAsync(fBitmap, BPoint(0,0));
|
||||||
|
|
||||||
DrawCounter(fMainTime, fBitmapView->fPositionX, fMainTracking);
|
_DrawCounter(fMainTime, fBitmapView->fPositionX, fMainTracking);
|
||||||
if (fLeftTracking)
|
if (fLeftTracking)
|
||||||
DrawCounter(fLeftTime, fBitmapView->fLeftX, fLeftTracking);
|
_DrawCounter(fLeftTime, fBitmapView->fLeftX, fLeftTracking);
|
||||||
else if (fRightTracking)
|
else if (fRightTracking)
|
||||||
DrawCounter(fRightTime, fBitmapView->fRightX, fRightTracking);
|
_DrawCounter(fRightTime, fBitmapView->fRightX, fRightTracking);
|
||||||
|
|
||||||
DrawMarker(fBitmapView->fPositionX);
|
_DrawMarker(fBitmapView->fPositionX);
|
||||||
|
|
||||||
Sync();
|
Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking)
|
TrackSlider::_DrawCounter(bigtime_t timestamp, float position, bool isTracking)
|
||||||
{
|
{
|
||||||
// timecounter
|
// timecounter
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking)
|
|||||||
rgb_color white = {255,255,255};
|
rgb_color white = {255,255,255};
|
||||||
|
|
||||||
char string[12];
|
char string[12];
|
||||||
TimeToString(timestamp, string);
|
_TimeToString(timestamp, string);
|
||||||
int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2;
|
int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2;
|
||||||
|
|
||||||
float counterX = position;
|
float counterX = position;
|
||||||
@@ -161,7 +161,7 @@ TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::DrawMarker(float position)
|
TrackSlider::_DrawMarker(float position)
|
||||||
{
|
{
|
||||||
rgb_color black = {0,0,0};
|
rgb_color black = {0,0,0};
|
||||||
rgb_color rose = {255,152,152};
|
rgb_color rose = {255,152,152};
|
||||||
@@ -221,7 +221,7 @@ TrackSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
|||||||
SetTracking(false);
|
SetTracking(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePosition(point);
|
_UpdatePosition(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ TrackSlider::MouseDown(BPoint point)
|
|||||||
if (!Bounds().InsetBySelf(2,2).Contains(point))
|
if (!Bounds().InsetBySelf(2,2).Contains(point))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdatePosition(point);
|
_UpdatePosition(point);
|
||||||
SetTracking(true);
|
SetTracking(true);
|
||||||
SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
|
SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ TrackSlider::MouseUp(BPoint point)
|
|||||||
if (!IsTracking())
|
if (!IsTracking())
|
||||||
return;
|
return;
|
||||||
if (Bounds().InsetBySelf(2,2).Contains(point)) {
|
if (Bounds().InsetBySelf(2,2).Contains(point)) {
|
||||||
UpdatePosition(point);
|
_UpdatePosition(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
fLeftTracking = fRightTracking = fMainTracking = false;
|
fLeftTracking = fRightTracking = fMainTracking = false;
|
||||||
@@ -256,7 +256,7 @@ TrackSlider::MouseUp(BPoint point)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::UpdatePosition(BPoint point)
|
TrackSlider::_UpdatePosition(BPoint point)
|
||||||
{
|
{
|
||||||
BRect leftRect(fBitmapView->fLeftX-9, SLIDER_BASE+3, fBitmapView->fLeftX, SLIDER_BASE+16);
|
BRect leftRect(fBitmapView->fLeftX-9, SLIDER_BASE+3, fBitmapView->fLeftX, SLIDER_BASE+16);
|
||||||
BRect rightRect(fBitmapView->fRightX, SLIDER_BASE+3, fBitmapView->fRightX+9, SLIDER_BASE+16);
|
BRect rightRect(fBitmapView->fRightX, SLIDER_BASE+3, fBitmapView->fRightX+9, SLIDER_BASE+16);
|
||||||
@@ -283,7 +283,7 @@ TrackSlider::UpdatePosition(BPoint point)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Invoke(&msg);
|
Invoke(&msg);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
|
|
||||||
//printf("fLeftPos : %Ld\n", fLeftTime);
|
//printf("fLeftPos : %Ld\n", fLeftTime);
|
||||||
} else if (!fMainTracking && (fRightTracking || ((point.x > fBitmapView->fPositionX+4) && rightRect.Contains(point)))) {
|
} else if (!fMainTracking && (fRightTracking || ((point.x > fBitmapView->fPositionX+4) && rightRect.Contains(point)))) {
|
||||||
@@ -308,7 +308,7 @@ TrackSlider::UpdatePosition(BPoint point)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Invoke(&msg);
|
Invoke(&msg);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
|
|
||||||
//printf("fRightPos : %Ld\n", fRightTime);
|
//printf("fRightPos : %Ld\n", fRightTime);
|
||||||
} else {
|
} else {
|
||||||
@@ -323,12 +323,12 @@ TrackSlider::UpdatePosition(BPoint point)
|
|||||||
fBitmapView->fRightX = fBitmapView->fPositionX;
|
fBitmapView->fRightX = fBitmapView->fPositionX;
|
||||||
fRightTime = fMainTime;
|
fRightTime = fMainTime;
|
||||||
msg.AddInt64("right", fRightTime);
|
msg.AddInt64("right", fRightTime);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
} else if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
|
} else if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
|
||||||
fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
|
fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
|
||||||
fLeftTime = fMainTime;
|
fLeftTime = fMainTime;
|
||||||
msg.AddInt64("left", fLeftTime);
|
msg.AddInt64("left", fLeftTime);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke(&msg);
|
Invoke(&msg);
|
||||||
@@ -340,7 +340,7 @@ TrackSlider::UpdatePosition(BPoint point)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackSlider::TimeToString(bigtime_t timestamp, char *string)
|
TrackSlider::_TimeToString(bigtime_t timestamp, char *string)
|
||||||
{
|
{
|
||||||
uint32 hours = timestamp / 3600000000LL;
|
uint32 hours = timestamp / 3600000000LL;
|
||||||
timestamp -= hours * 3600000000LL;
|
timestamp -= hours * 3600000000LL;
|
||||||
@@ -364,7 +364,7 @@ TrackSlider::SetMainTime(bigtime_t timestamp, bool reset)
|
|||||||
fLeftTime = 0;
|
fLeftTime = 0;
|
||||||
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
||||||
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
}
|
}
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ TrackSlider::SetTotalTime(bigtime_t timestamp, bool reset)
|
|||||||
fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
|
fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
|
||||||
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
||||||
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,10 +400,10 @@ TrackSlider::FrameResized(float width, float height)
|
|||||||
{
|
{
|
||||||
fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
|
fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
|
||||||
fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
|
fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
|
||||||
InitBitmap();
|
_InitBitmap();
|
||||||
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
|
||||||
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
|
||||||
RenderBitmap();
|
_RenderBitmap();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,12 +46,12 @@ public:
|
|||||||
void ResetMainTime();
|
void ResetMainTime();
|
||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
private:
|
private:
|
||||||
void DrawCounter(bigtime_t timestamp, float position, bool isTracking);
|
void _DrawCounter(bigtime_t timestamp, float position, bool isTracking);
|
||||||
void DrawMarker(float position);
|
void _DrawMarker(float position);
|
||||||
void TimeToString(bigtime_t timestamp, char *string);
|
void _TimeToString(bigtime_t timestamp, char *string);
|
||||||
void UpdatePosition(BPoint point);
|
void _UpdatePosition(BPoint point);
|
||||||
void InitBitmap();
|
void _InitBitmap();
|
||||||
void RenderBitmap();
|
void _RenderBitmap();
|
||||||
|
|
||||||
|
|
||||||
bigtime_t fLeftTime;
|
bigtime_t fLeftTime;
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
* Copyright 2005, Jérôme Duval. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers and Producers)
|
* Inspired by SoundCapture from Be newsletter (Media Kit Basics:
|
||||||
|
* Consumers and Producers)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <MediaDefs.h>
|
||||||
#include <Screen.h>
|
#include <Screen.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include "DrawingTidbits.h"
|
#include "DrawingTidbits.h"
|
||||||
#include "VUView.h"
|
#include "VUView.h"
|
||||||
|
|
||||||
@@ -26,21 +30,22 @@ VUView::VUView(BRect rect, uint32 resizeFlags)
|
|||||||
fLevelCount = int(rect.Height()) / 2;
|
fLevelCount = int(rect.Height()) / 2;
|
||||||
fChannels = 2;
|
fChannels = 2;
|
||||||
fCurrentLevels = new int32[fChannels];
|
fCurrentLevels = new int32[fChannels];
|
||||||
for (int channel=0; channel < fChannels; channel++)
|
for (int channel = 0; channel < fChannels; channel++)
|
||||||
fCurrentLevels[channel] = 0;
|
fCurrentLevels[channel] = 0;
|
||||||
fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true);
|
fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true);
|
||||||
|
|
||||||
|
|
||||||
memset(fBitmap->Bits(), 0, fBitmap->BitsLength());
|
memset(fBitmap->Bits(), 0, fBitmap->BitsLength());
|
||||||
|
|
||||||
fBitmapView = new BView(rect, "bitmapView", B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW);
|
fBitmapView = new BView(rect, "bitmapView", B_FOLLOW_LEFT|B_FOLLOW_TOP,
|
||||||
|
B_WILL_DRAW);
|
||||||
fBitmap->AddChild(fBitmapView);
|
fBitmap->AddChild(fBitmapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VUView::~VUView()
|
VUView::~VUView()
|
||||||
{
|
{
|
||||||
|
delete fBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,14 +53,14 @@ void
|
|||||||
VUView::AttachedToWindow()
|
VUView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
Run();
|
_Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VUView::DetachedFromWindow()
|
VUView::DetachedFromWindow()
|
||||||
{
|
{
|
||||||
Quit();
|
_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -69,16 +74,16 @@ VUView::Draw(BRect updateRect)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VUView::Run()
|
VUView::_Run()
|
||||||
{
|
{
|
||||||
fThreadId = spawn_thread(&RenderLaunch, "VU view", B_NORMAL_PRIORITY, this);
|
fThreadId = spawn_thread(_RenderLaunch, "VU view", B_NORMAL_PRIORITY, this);
|
||||||
if (fThreadId < 0)
|
if (fThreadId < 0)
|
||||||
return;
|
return;
|
||||||
resume_thread(fThreadId);
|
resume_thread(fThreadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VUView::Quit()
|
VUView::_Quit()
|
||||||
{
|
{
|
||||||
fQuitting = true;
|
fQuitting = true;
|
||||||
snooze(10000);
|
snooze(10000);
|
||||||
@@ -88,18 +93,19 @@ VUView::Quit()
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
VUView::RenderLaunch(void *data)
|
VUView::_RenderLaunch(void *data)
|
||||||
{
|
{
|
||||||
VUView *vu = (VUView*) data;
|
VUView *vu = (VUView*) data;
|
||||||
vu->RenderLoop();
|
vu->_RenderLoop();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SHIFT_UNTIL(value,shift,min) value = (value - shift > min) ? (value - shift) : min
|
#define SHIFT_UNTIL(value,shift,min) \
|
||||||
|
value = (value - shift > min) ? (value - shift) : min
|
||||||
|
|
||||||
void
|
void
|
||||||
VUView::RenderLoop()
|
VUView::_RenderLoop()
|
||||||
{
|
{
|
||||||
rgb_color levels[fLevelCount][2];
|
rgb_color levels[fLevelCount][2];
|
||||||
|
|
||||||
@@ -167,29 +173,72 @@ VUView::RenderLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
template<typename T>
|
||||||
VUView::ComputeNextLevel(void *data, size_t size)
|
T
|
||||||
|
VUView::_ComputeNextLevel(void *data, size_t size, uint32 format, int32 channel)
|
||||||
{
|
{
|
||||||
int16* samp = (int16*)data;
|
T* samp = (T*)data;
|
||||||
|
|
||||||
|
// get the min and max values in the nibbling interval
|
||||||
|
// and set max to be the greater of the absolute value
|
||||||
|
// of these.
|
||||||
|
|
||||||
|
T min = 0, max = 0;
|
||||||
|
for (uint32 i = channel; i < size/sizeof(T); i += fChannels) {
|
||||||
|
if (min > samp[i])
|
||||||
|
min = samp[i];
|
||||||
|
else if (max < samp[i])
|
||||||
|
max = samp[i];
|
||||||
|
}
|
||||||
|
if (-max > (min + 1))
|
||||||
|
max = -min;
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VUView::ComputeLevels(void* data, size_t size, uint32 format)
|
||||||
|
{
|
||||||
for (int32 channel = 0; channel < fChannels; channel++) {
|
for (int32 channel = 0; channel < fChannels; channel++) {
|
||||||
|
switch (format) {
|
||||||
// get the min and max values in the nibbling interval
|
case media_raw_audio_format::B_AUDIO_FLOAT:
|
||||||
// and set max to be the greater of the absolute value
|
{
|
||||||
// of these.
|
float max = _ComputeNextLevel<float>(data, size, format,
|
||||||
|
channel);
|
||||||
int mi = 0, ma = 0;
|
fCurrentLevels[channel] = (uint8)(max * 127);
|
||||||
for (uint32 ix=channel; ix<size/sizeof(uint16); ix += fChannels) {
|
break;
|
||||||
if (mi > samp[ix]) mi = samp[ix];
|
}
|
||||||
else if (ma < samp[ix]) ma = samp[ix];
|
case media_raw_audio_format::B_AUDIO_INT:
|
||||||
|
{
|
||||||
|
int32 max = _ComputeNextLevel<int32>(data, size, format,
|
||||||
|
channel);
|
||||||
|
fCurrentLevels[channel] = max / (2 << (32-8));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case media_raw_audio_format::B_AUDIO_SHORT:
|
||||||
|
{
|
||||||
|
int16 max = _ComputeNextLevel<int16>(data, size, format,
|
||||||
|
channel);
|
||||||
|
fCurrentLevels[channel] = max / (2 << (16-7));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case media_raw_audio_format::B_AUDIO_UCHAR:
|
||||||
|
{
|
||||||
|
uchar max = _ComputeNextLevel<uchar>(data, size, format,
|
||||||
|
channel);
|
||||||
|
fCurrentLevels[channel] = max / 2 - 127;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case media_raw_audio_format::B_AUDIO_CHAR:
|
||||||
|
{
|
||||||
|
char max = _ComputeNextLevel<char>(data, size, format,
|
||||||
|
channel);
|
||||||
|
fCurrentLevels[channel] = max / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (-ma > mi) ma = (mi == -32768) ? 32767 : -mi;
|
|
||||||
|
|
||||||
uint8 n = ma / (2 << (16-7));
|
|
||||||
|
|
||||||
fCurrentLevels[channel] = n;
|
|
||||||
if (fCurrentLevels[channel] < 0)
|
if (fCurrentLevels[channel] < 0)
|
||||||
fCurrentLevels[channel] = 0;
|
fCurrentLevels[channel] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
* Copyright 2005, Jérôme Duval. All rights reserved.
|
* Copyright 2005, Jérôme Duval. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers and Producers)
|
* Inspired by SoundCapture from Be newsletter (Media Kit Basics:
|
||||||
|
* Consumers and Producers)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VUVIEW_H
|
#ifndef VUVIEW_H
|
||||||
@@ -20,13 +21,15 @@ public:
|
|||||||
void AttachedToWindow();
|
void AttachedToWindow();
|
||||||
void DetachedFromWindow();
|
void DetachedFromWindow();
|
||||||
void Draw(BRect updateRect);
|
void Draw(BRect updateRect);
|
||||||
void ComputeNextLevel(void *data, size_t size);
|
void ComputeLevels(void* data, size_t size, uint32 format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Run();
|
void _Run();
|
||||||
void Quit();
|
void _Quit();
|
||||||
static int32 RenderLaunch(void *data);
|
static int32 _RenderLaunch(void *data);
|
||||||
void RenderLoop();
|
void _RenderLoop();
|
||||||
|
template<typename T> T _ComputeNextLevel(void *data,
|
||||||
|
size_t size, uint32 format, int32 channel);
|
||||||
|
|
||||||
thread_id fThreadId;
|
thread_id fThreadId;
|
||||||
BBitmap *fBitmap;
|
BBitmap *fBitmap;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ VolumeSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
|||||||
if (!fSoundPlayer || !Bounds().InsetBySelf(2,2).Contains(point))
|
if (!fSoundPlayer || !Bounds().InsetBySelf(2,2).Contains(point))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateVolume(point);
|
_UpdateVolume(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ VolumeSlider::MouseDown(BPoint point)
|
|||||||
if (!fSoundPlayer || !Bounds().InsetBySelf(2,2).Contains(point))
|
if (!fSoundPlayer || !Bounds().InsetBySelf(2,2).Contains(point))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateVolume(point);
|
_UpdateVolume(point);
|
||||||
SetTracking(true);
|
SetTracking(true);
|
||||||
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ VolumeSlider::MouseUp(BPoint point)
|
|||||||
if (!IsTracking())
|
if (!IsTracking())
|
||||||
return;
|
return;
|
||||||
if (fSoundPlayer && Bounds().InsetBySelf(2,2).Contains(point)) {
|
if (fSoundPlayer && Bounds().InsetBySelf(2,2).Contains(point)) {
|
||||||
UpdateVolume(point);
|
_UpdateVolume(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke();
|
Invoke();
|
||||||
@@ -132,7 +132,7 @@ VolumeSlider::MouseUp(BPoint point)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VolumeSlider::UpdateVolume(BPoint point)
|
VolumeSlider::_UpdateVolume(BPoint point)
|
||||||
{
|
{
|
||||||
fVolume = MIN(MAX(point.x, 11), fRight);
|
fVolume = MIN(MAX(point.x, 11), fRight);
|
||||||
fVolume = (fVolume - 11) / (fRight - 11);
|
fVolume = (fVolume - 11) / (fRight - 11);
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ public:
|
|||||||
virtual void MouseDown(BPoint point);
|
virtual void MouseDown(BPoint point);
|
||||||
void SetSoundPlayer(BSoundPlayer *player);
|
void SetSoundPlayer(BSoundPlayer *player);
|
||||||
private:
|
private:
|
||||||
void UpdateVolume(BPoint point);
|
void _UpdateVolume(BPoint point);
|
||||||
|
|
||||||
BBitmap fLeftBitmap, fRightBitmap, fButtonBitmap;
|
BBitmap fLeftBitmap, fRightBitmap, fButtonBitmap;
|
||||||
float fRight;
|
float fRight;
|
||||||
float fVolume;
|
float fVolume;
|
||||||
|
|||||||
Reference in New Issue
Block a user