MidiPlayer: style overhaul

This commit is contained in:
John Scipione
2014-06-27 22:57:02 -04:00
parent e23f93739b
commit 42bcaa84c0
8 changed files with 429 additions and 431 deletions
+16 -8
View File
@@ -20,21 +20,30 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "MidiPlayerApp.h"
#include <AboutWindow.h>
#include <Alert.h>
#include <Catalog.h>
#include <Locale.h>
#include <StorageKit.h>
#include "MidiPlayerApp.h"
#include "MidiPlayerWindow.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Main Application"
// #pragma mark - MidiPlayerApp
MidiPlayerApp::MidiPlayerApp()
: BApplication(MIDI_PLAYER_SIGNATURE)
:
BApplication(MIDI_PLAYER_SIGNATURE)
{
window = new MidiPlayerWindow;
window = new MidiPlayerWindow();
}
@@ -62,10 +71,10 @@ MidiPlayerApp::AboutRequested()
void
MidiPlayerApp::RefsReceived(BMessage* msg)
MidiPlayerApp::RefsReceived(BMessage* message)
{
msg->what = B_SIMPLE_DATA;
window->PostMessage(msg);
message->what = B_SIMPLE_DATA;
window->PostMessage(message);
}
@@ -90,7 +99,7 @@ MidiPlayerApp::ArgvReceived(int32 argc, char** argv)
}
// #pragma mark -
// #pragma mark - main method
int
@@ -100,4 +109,3 @@ main()
app.Run();
return 0;
}
+7 -3
View File
@@ -19,13 +19,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef MIDI_PLAYER_APP_H
#define MIDI_PLAYER_APP_H
#ifndef _MIDI_PLAYER_APP_H
#define _MIDI_PLAYER_APP_H
#include <Application.h>
#define MIDI_PLAYER_SIGNATURE "application/x-vnd.Haiku-MidiPlayer"
class MidiPlayerWindow;
class MidiPlayerApp : public BApplication {
@@ -42,4 +45,5 @@ class MidiPlayerApp : public BApplication {
MidiPlayerWindow* window;
};
#endif // MIDI_PLAYER_APP_H
#endif // _MIDI_PLAYER_APP_H
+166 -162
View File
@@ -20,10 +20,12 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "MidiPlayerWindow.h"
#include <Catalog.h>
#include <GridLayoutBuilder.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <GridLayoutBuilder.h>
#include <Locale.h>
#include <MidiProducer.h>
#include <MidiRoster.h>
@@ -31,7 +33,6 @@
#include <SpaceLayoutItem.h>
#include "MidiPlayerApp.h"
#include "MidiPlayerWindow.h"
#include "ScopeView.h"
#include "SynthBridge.h"
@@ -44,25 +45,28 @@
#define B_TRANSLATION_CONTEXT "Main Window"
// #pragma mark - MidiPlayerWindow
MidiPlayerWindow::MidiPlayerWindow()
:
BWindow(BRect(0, 0, 1, 1), B_TRANSLATE_SYSTEM_NAME("MidiPlayer"),
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
{
playing = false;
scopeEnabled = true;
reverb = B_REVERB_BALLROOM;
volume = 75;
windowX = -1;
windowY = -1;
inputId = -1;
instrLoaded = false;
fIsPlaying = false;
fScopeEnabled = true;
fReverbMode = B_REVERB_BALLROOM;
fVolume = 75;
fWindowX = -1;
fWindowY = -1;
fInputId = -1;
fInstrumentLoaded = false;
be_synth->SetSamplingRate(44100);
bridge = new SynthBridge;
//bridge->Register();
fSynthBridge = new SynthBridge;
//fSynthBridge->Register();
CreateViews();
LoadSettings();
@@ -74,8 +78,8 @@ MidiPlayerWindow::~MidiPlayerWindow()
{
StopSynth();
//bridge->Unregister();
bridge->Release();
//fSynthBridge->Unregister();
fSynthBridge->Release();
}
@@ -88,9 +92,9 @@ MidiPlayerWindow::QuitRequested()
void
MidiPlayerWindow::MessageReceived(BMessage* msg)
MidiPlayerWindow::MessageReceived(BMessage* message)
{
switch (msg->what) {
switch (message->what) {
case MSG_PLAY_STOP:
OnPlayStop();
break;
@@ -100,7 +104,7 @@ MidiPlayerWindow::MessageReceived(BMessage* msg)
break;
case MSG_INPUT_CHANGED:
OnInputChanged(msg);
OnInputChanged(message);
break;
case MSG_REVERB_NONE:
@@ -132,11 +136,11 @@ MidiPlayerWindow::MessageReceived(BMessage* msg)
break;
case B_SIMPLE_DATA:
OnDrop(msg);
OnDrop(message);
break;
default:
super::MessageReceived(msg);
super::MessageReceived(message);
break;
}
}
@@ -146,8 +150,8 @@ void
MidiPlayerWindow::FrameMoved(BPoint origin)
{
super::FrameMoved(origin);
windowX = Frame().left;
windowY = Frame().top;
fWindowX = Frame().left;
fWindowY = Frame().top;
SaveSettings();
}
@@ -155,23 +159,23 @@ MidiPlayerWindow::FrameMoved(BPoint origin)
void
MidiPlayerWindow::MenusBeginning()
{
for (int32 t = inputPopUp->CountItems() - 1; t > 0; --t)
delete inputPopUp->RemoveItem(t);
for (int32 t = fInputPopUpMenu->CountItems() - 1; t > 0; --t)
delete fInputPopUpMenu->RemoveItem(t);
// Note: if the selected endpoint no longer exists, then no endpoint is
// marked. However, we won't disconnect it until you choose another one.
inputOff->SetMarked(inputId == -1);
fInputOffMenuItem->SetMarked(fInputId == -1);
int32 id = 0;
while (BMidiEndpoint* endpoint = BMidiRoster::NextEndpoint(&id)) {
if (endpoint->IsProducer()) {
BMessage* msg = new BMessage(MSG_INPUT_CHANGED);
msg->AddInt32("id", id);
BMessage* message = new BMessage(MSG_INPUT_CHANGED);
message->AddInt32("id", id);
BMenuItem* item = new BMenuItem(endpoint->Name(), msg);
inputPopUp->AddItem(item);
item->SetMarked(inputId == id);
BMenuItem* item = new BMenuItem(endpoint->Name(), message);
fInputPopUpMenu->AddItem(item);
item->SetMarked(fInputId == id);
}
endpoint->Release();
@@ -182,45 +186,44 @@ MidiPlayerWindow::MenusBeginning()
void
MidiPlayerWindow::CreateInputMenu()
{
inputPopUp = new BPopUpMenu("inputPopUp");
fInputPopUpMenu = new BPopUpMenu("inputPopUp");
BMessage* msg = new BMessage;
msg->what = MSG_INPUT_CHANGED;
msg->AddInt32("id", -1);
BMessage* message = new BMessage(MSG_INPUT_CHANGED);
message->AddInt32("id", -1);
inputOff = new BMenuItem(B_TRANSLATE("Off"), msg);
fInputOffMenuItem = new BMenuItem(B_TRANSLATE("Off"), message);
fInputPopUpMenu->AddItem(fInputOffMenuItem);
inputPopUp->AddItem(inputOff);
inputMenu = new BMenuField(B_TRANSLATE("Live input:"), inputPopUp);
fInputMenuField = new BMenuField(B_TRANSLATE("Live input:"),
fInputPopUpMenu);
}
void
MidiPlayerWindow::CreateReverbMenu()
{
BPopUpMenu* reverbPopUp = new BPopUpMenu("reverbPopUp");
reverbNone = new BMenuItem(
B_TRANSLATE("None"), new BMessage(MSG_REVERB_NONE));
reverbCloset = new BMenuItem(
B_TRANSLATE("Closet"), new BMessage(MSG_REVERB_CLOSET));
reverbGarage = new BMenuItem(
B_TRANSLATE("Garage"), new BMessage(MSG_REVERB_GARAGE));
reverbIgor = new BMenuItem(
B_TRANSLATE("Igor's lab"), new BMessage(MSG_REVERB_IGOR));
reverbCavern = new BMenuItem(
B_TRANSLATE("Cavern"), new BMessage(MSG_REVERB_CAVERN));
reverbDungeon = new BMenuItem(
B_TRANSLATE("Dungeon"), new BMessage(MSG_REVERB_DUNGEON));
BPopUpMenu* reverbPopUpMenu = new BPopUpMenu("reverbPopUp");
fReverbNoneMenuItem = new BMenuItem(B_TRANSLATE("None"),
new BMessage(MSG_REVERB_NONE));
fReverbClosetMenuItem = new BMenuItem(B_TRANSLATE("Closet"),
new BMessage(MSG_REVERB_CLOSET));
fReverbGarageMenuItem = new BMenuItem(B_TRANSLATE("Garage"),
new BMessage(MSG_REVERB_GARAGE));
fReverbIgorMenuItem = new BMenuItem(B_TRANSLATE("Igor's lab"),
new BMessage(MSG_REVERB_IGOR));
fReverbCavern = new BMenuItem(B_TRANSLATE("Cavern"),
new BMessage(MSG_REVERB_CAVERN));
fReverbDungeon = new BMenuItem(B_TRANSLATE("Dungeon"),
new BMessage(MSG_REVERB_DUNGEON));
reverbPopUp->AddItem(reverbNone);
reverbPopUp->AddItem(reverbCloset);
reverbPopUp->AddItem(reverbGarage);
reverbPopUp->AddItem(reverbIgor);
reverbPopUp->AddItem(reverbCavern);
reverbPopUp->AddItem(reverbDungeon);
reverbPopUpMenu->AddItem(fReverbNoneMenuItem);
reverbPopUpMenu->AddItem(fReverbClosetMenuItem);
reverbPopUpMenu->AddItem(fReverbGarageMenuItem);
reverbPopUpMenu->AddItem(fReverbIgorMenuItem);
reverbPopUpMenu->AddItem(fReverbCavern);
reverbPopUpMenu->AddItem(fReverbDungeon);
reverbMenu = new BMenuField(B_TRANSLATE("Reverb:"), reverbPopUp);
fReverbMenuField = new BMenuField(B_TRANSLATE("Reverb:"), reverbPopUpMenu);
}
@@ -228,29 +231,30 @@ void
MidiPlayerWindow::CreateViews()
{
// Set up needed views
scopeView = new ScopeView;
fScopeView = new ScopeView();
showScope = new BCheckBox("showScope", B_TRANSLATE("Scope"),
fShowScopeCheckBox = new BCheckBox("showScope", B_TRANSLATE("Scope"),
new BMessage(MSG_SHOW_SCOPE));
showScope->SetValue(B_CONTROL_ON);
fShowScopeCheckBox->SetValue(B_CONTROL_ON);
CreateInputMenu();
CreateReverbMenu();
volumeSlider = new BSlider("volumeSlider", NULL, NULL, 0, 100,
fVolumeSlider = new BSlider("volumeSlider", NULL, NULL, 0, 100,
B_HORIZONTAL);
rgb_color col = { 152, 152, 255 };
volumeSlider->UseFillColor(true, &col);
volumeSlider->SetModificationMessage(new BMessage(MSG_VOLUME));
rgb_color color = (rgb_color){ 152, 152, 255 };
fVolumeSlider->UseFillColor(true, &color);
fVolumeSlider->SetModificationMessage(new BMessage(MSG_VOLUME));
fVolumeSlider->SetExplicitMinSize(
BSize(fScopeView->Frame().Width(), B_SIZE_UNSET));
playButton = new BButton("playButton", B_TRANSLATE("Play"),
fPlayButton = new BButton("playButton", B_TRANSLATE("Play"),
new BMessage(MSG_PLAY_STOP));
playButton->SetEnabled(false);
fPlayButton->SetEnabled(false);
BBox* divider = new BBox(B_EMPTY_STRING, B_WILL_DRAW | B_FRAME_EVENTS,
B_FANCY_BORDER);
divider->SetExplicitMaxSize(
BSize(B_SIZE_UNLIMITED, 1));
divider->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
BStringView* volumeLabel = new BStringView(NULL, B_TRANSLATE("Volume:"));
volumeLabel->SetAlignment(B_ALIGN_LEFT);
@@ -260,24 +264,24 @@ MidiPlayerWindow::CreateViews()
SetLayout(new BGroupLayout(B_HORIZONTAL));
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
.Add(scopeView)
.Add(fScopeView)
.Add(BGridLayoutBuilder(10, 10)
.Add(BSpaceLayoutItem::CreateGlue(), 0, 0)
.Add(showScope, 1, 0)
.Add(fShowScopeCheckBox, 1, 0)
.Add(reverbMenu->CreateLabelLayoutItem(), 0, 1)
.Add(reverbMenu->CreateMenuBarLayoutItem(), 1, 1)
.Add(fReverbMenuField->CreateLabelLayoutItem(), 0, 1)
.Add(fReverbMenuField->CreateMenuBarLayoutItem(), 1, 1)
.Add(inputMenu->CreateLabelLayoutItem(), 0, 2)
.Add(inputMenu->CreateMenuBarLayoutItem(), 1, 2)
.Add(fInputMenuField->CreateLabelLayoutItem(), 0, 2)
.Add(fInputMenuField->CreateMenuBarLayoutItem(), 1, 2)
.Add(volumeLabel, 0, 3)
.Add(volumeSlider, 1, 3)
.Add(fVolumeSlider, 1, 3)
)
.AddGlue()
.Add(divider)
.AddGlue()
.Add(playButton)
.Add(fPlayButton)
.AddGlue()
.SetInsets(5, 5, 5, 5)
);
@@ -289,23 +293,23 @@ MidiPlayerWindow::InitControls()
{
Lock();
showScope->SetValue(scopeEnabled ? B_CONTROL_ON : B_CONTROL_OFF);
scopeView->SetEnabled(scopeEnabled);
fShowScopeCheckBox->SetValue(fScopeEnabled ? B_CONTROL_ON : B_CONTROL_OFF);
fScopeView->SetEnabled(fScopeEnabled);
inputOff->SetMarked(true);
fInputOffMenuItem->SetMarked(true);
reverbNone->SetMarked(reverb == B_REVERB_NONE);
reverbCloset->SetMarked(reverb == B_REVERB_CLOSET);
reverbGarage->SetMarked(reverb == B_REVERB_GARAGE);
reverbIgor->SetMarked(reverb == B_REVERB_BALLROOM);
reverbCavern->SetMarked(reverb == B_REVERB_CAVERN);
reverbDungeon->SetMarked(reverb == B_REVERB_DUNGEON);
be_synth->SetReverb(reverb);
fReverbNoneMenuItem->SetMarked(fReverbMode == B_REVERB_NONE);
fReverbClosetMenuItem->SetMarked(fReverbMode == B_REVERB_CLOSET);
fReverbGarageMenuItem->SetMarked(fReverbMode == B_REVERB_GARAGE);
fReverbIgorMenuItem->SetMarked(fReverbMode == B_REVERB_BALLROOM);
fReverbCavern->SetMarked(fReverbMode == B_REVERB_CAVERN);
fReverbDungeon->SetMarked(fReverbMode == B_REVERB_DUNGEON);
be_synth->SetReverb(fReverbMode);
volumeSlider->SetValue(volume);
fVolumeSlider->SetValue(fVolume);
if (windowX != -1 && windowY != -1)
MoveTo(windowX, windowY);
if (fWindowX != -1 && fWindowY != -1)
MoveTo(fWindowX, fWindowY);
else
CenterOnScreen();
@@ -320,11 +324,11 @@ MidiPlayerWindow::LoadSettings()
if (file.InitCheck() != B_OK || file.Lock() != B_OK)
return;
file.ReadAttr("Scope", B_BOOL_TYPE, 0, &scopeEnabled, sizeof(bool));
file.ReadAttr("Reverb", B_INT32_TYPE, 0, &reverb, sizeof(int32));
file.ReadAttr("Volume", B_INT32_TYPE, 0, &volume, sizeof(int32));
file.ReadAttr("WindowX", B_FLOAT_TYPE, 0, &windowX, sizeof(float));
file.ReadAttr("WindowY", B_FLOAT_TYPE, 0, &windowY, sizeof(float));
file.ReadAttr("Scope", B_BOOL_TYPE, 0, &fScopeEnabled, sizeof(bool));
file.ReadAttr("Reverb", B_INT32_TYPE, 0, &fReverbMode, sizeof(int32));
file.ReadAttr("Volume", B_INT32_TYPE, 0, &fWindowX, sizeof(int32));
file.ReadAttr("WindowX", B_FLOAT_TYPE, 0, &fWindowX, sizeof(float));
file.ReadAttr("WindowY", B_FLOAT_TYPE, 0, &fWindowY, sizeof(float));
file.Unlock();
}
@@ -337,11 +341,11 @@ MidiPlayerWindow::SaveSettings()
if (file.InitCheck() != B_OK || file.Lock() != B_OK)
return;
file.WriteAttr("Scope", B_BOOL_TYPE, 0, &scopeEnabled, sizeof(bool));
file.WriteAttr("Reverb", B_INT32_TYPE, 0, &reverb, sizeof(int32));
file.WriteAttr("Volume", B_INT32_TYPE, 0, &volume, sizeof(int32));
file.WriteAttr("WindowX", B_FLOAT_TYPE, 0, &windowX, sizeof(float));
file.WriteAttr("WindowY", B_FLOAT_TYPE, 0, &windowY, sizeof(float));
file.WriteAttr("Scope", B_BOOL_TYPE, 0, &fScopeEnabled, sizeof(bool));
file.WriteAttr("Reverb", B_INT32_TYPE, 0, &fReverbMode, sizeof(int32));
file.WriteAttr("Volume", B_INT32_TYPE, 0, &fVolume, sizeof(int32));
file.WriteAttr("WindowX", B_FLOAT_TYPE, 0, &fWindowX, sizeof(float));
file.WriteAttr("WindowY", B_FLOAT_TYPE, 0, &fWindowY, sizeof(float));
file.Sync();
file.Unlock();
@@ -351,35 +355,35 @@ MidiPlayerWindow::SaveSettings()
void
MidiPlayerWindow::LoadFile(entry_ref* ref)
{
if (playing) {
scopeView->SetPlaying(false);
scopeView->Invalidate();
if (fIsPlaying) {
fScopeView->SetPlaying(false);
fScopeView->Invalidate();
UpdateIfNeeded();
StopSynth();
}
synth.UnloadFile();
fMidiSynthFile.UnloadFile();
if (synth.LoadFile(ref) == B_OK) {
if (fMidiSynthFile.LoadFile(ref) == B_OK) {
// Ideally, we would call SetVolume() in InitControls(),
// but for some reason that doesn't work: BMidiSynthFile
// will use the default volume instead. So we do it here.
synth.SetVolume(volume / 100.0f);
fMidiSynthFile.SetVolume(fVolume / 100.0f);
playButton->SetEnabled(true);
playButton->SetLabel(B_TRANSLATE("Stop"));
scopeView->SetHaveFile(true);
scopeView->SetPlaying(true);
scopeView->Invalidate();
fPlayButton->SetEnabled(true);
fPlayButton->SetLabel(B_TRANSLATE("Stop"));
fScopeView->SetHaveFile(true);
fScopeView->SetPlaying(true);
fScopeView->Invalidate();
StartSynth();
} else {
playButton->SetEnabled(false);
playButton->SetLabel(B_TRANSLATE("Play"));
scopeView->SetHaveFile(false);
scopeView->SetPlaying(false);
scopeView->Invalidate();
fPlayButton->SetEnabled(false);
fPlayButton->SetLabel(B_TRANSLATE("Play"));
fScopeView->SetHaveFile(false);
fScopeView->SetPlaying(false);
fScopeView->Invalidate();
BAlert* alert = new BAlert(NULL, B_TRANSLATE("Could not load song"),
B_TRANSLATE("OK"), NULL, NULL,
@@ -393,19 +397,19 @@ MidiPlayerWindow::LoadFile(entry_ref* ref)
void
MidiPlayerWindow::StartSynth()
{
synth.Start();
synth.SetFileHook(_StopHook, (int32)(addr_t)this);
playing = true;
fMidiSynthFile.Start();
fMidiSynthFile.SetFileHook(_StopHook, (int32)(addr_t)this);
fIsPlaying = true;
}
void
MidiPlayerWindow::StopSynth()
{
if (!synth.IsFinished())
synth.Fade();
if (!fMidiSynthFile.IsFinished())
fMidiSynthFile.Fade();
playing = false;
fIsPlaying = false;
}
@@ -422,12 +426,12 @@ MidiPlayerWindow::StopHook()
Lock();
// we may be called from the synth's thread
playing = false;
fIsPlaying = false;
scopeView->SetPlaying(false);
scopeView->Invalidate();
playButton->SetEnabled(true);
playButton->SetLabel(B_TRANSLATE("Play"));
fScopeView->SetPlaying(false);
fScopeView->Invalidate();
fPlayButton->SetEnabled(true);
fPlayButton->SetLabel(B_TRANSLATE("Play"));
Unlock();
}
@@ -436,17 +440,17 @@ MidiPlayerWindow::StopHook()
void
MidiPlayerWindow::OnPlayStop()
{
if (playing) {
playButton->SetEnabled(false);
scopeView->SetPlaying(false);
scopeView->Invalidate();
if (fIsPlaying) {
fPlayButton->SetEnabled(false);
fScopeView->SetPlaying(false);
fScopeView->Invalidate();
UpdateIfNeeded();
StopSynth();
} else {
playButton->SetLabel(B_TRANSLATE("Stop"));
scopeView->SetPlaying(true);
scopeView->Invalidate();
fPlayButton->SetLabel(B_TRANSLATE("Stop"));
fScopeView->SetPlaying(true);
fScopeView->Invalidate();
StartSynth();
}
@@ -456,48 +460,48 @@ MidiPlayerWindow::OnPlayStop()
void
MidiPlayerWindow::OnShowScope()
{
scopeEnabled = !scopeEnabled;
scopeView->SetEnabled(scopeEnabled);
scopeView->Invalidate();
fScopeEnabled = !fScopeEnabled;
fScopeView->SetEnabled(fScopeEnabled);
fScopeView->Invalidate();
SaveSettings();
}
void
MidiPlayerWindow::OnInputChanged(BMessage* msg)
MidiPlayerWindow::OnInputChanged(BMessage* message)
{
int32 newId;
if (msg->FindInt32("id", &newId) == B_OK) {
BMidiProducer* endpoint = BMidiRoster::FindProducer(inputId);
if (message->FindInt32("id", &newId) == B_OK) {
BMidiProducer* endpoint = BMidiRoster::FindProducer(fInputId);
if (endpoint != NULL) {
endpoint->Disconnect(bridge);
endpoint->Disconnect(fSynthBridge);
endpoint->Release();
}
inputId = newId;
fInputId = newId;
endpoint = BMidiRoster::FindProducer(inputId);
endpoint = BMidiRoster::FindProducer(fInputId);
if (endpoint != NULL) {
if (!instrLoaded) {
scopeView->SetLoading(true);
scopeView->Invalidate();
if (!fInstrumentLoaded) {
fScopeView->SetLoading(true);
fScopeView->Invalidate();
UpdateIfNeeded();
bridge->Init(B_BIG_SYNTH);
instrLoaded = true;
fSynthBridge->Init(B_BIG_SYNTH);
fInstrumentLoaded = true;
scopeView->SetLoading(false);
scopeView->Invalidate();
fScopeView->SetLoading(false);
fScopeView->Invalidate();
}
endpoint->Connect(bridge);
endpoint->Connect(fSynthBridge);
endpoint->Release();
scopeView->SetLiveInput(true);
scopeView->Invalidate();
fScopeView->SetLiveInput(true);
fScopeView->Invalidate();
} else {
scopeView->SetLiveInput(false);
scopeView->Invalidate();
fScopeView->SetLiveInput(false);
fScopeView->Invalidate();
}
}
}
@@ -506,8 +510,8 @@ MidiPlayerWindow::OnInputChanged(BMessage* msg)
void
MidiPlayerWindow::OnReverb(reverb_mode mode)
{
reverb = mode;
be_synth->SetReverb(reverb);
fReverbMode = mode;
be_synth->SetReverb(fReverbMode);
SaveSettings();
}
@@ -515,16 +519,16 @@ MidiPlayerWindow::OnReverb(reverb_mode mode)
void
MidiPlayerWindow::OnVolume()
{
volume = volumeSlider->Value();
synth.SetVolume(volume / 100.0f);
fVolume = fVolumeSlider->Value();
fMidiSynthFile.SetVolume(fVolume / 100.0f);
SaveSettings();
}
void
MidiPlayerWindow::OnDrop(BMessage* msg)
MidiPlayerWindow::OnDrop(BMessage* message)
{
entry_ref ref;
if (msg->FindRef("refs", &ref) == B_OK)
if (message->FindRef("refs", &ref) == B_OK)
LoadFile(&ref);
}
+38 -37
View File
@@ -7,10 +7,10 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -19,15 +19,17 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _MIDI_PLAYER_WINDOW_H
#define _MIDI_PLAYER_WINDOW_H
#ifndef MIDI_PLAYER_WINDOW_H
#define MIDI_PLAYER_WINDOW_H
#include <InterfaceKit.h>
#include <MidiSynthFile.h>
#define SETTINGS_FILE "/boot/home/config/settings/MidiPlayerSettings"
enum
{
MSG_PLAY_STOP = 1000,
@@ -42,25 +44,23 @@ enum
MSG_VOLUME,
};
class ScopeView;
class SynthBridge;
class MidiPlayerWindow : public BWindow
{
class MidiPlayerWindow : public BWindow {
public:
MidiPlayerWindow();
virtual ~MidiPlayerWindow();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage* msg);
virtual void MessageReceived(BMessage* message);
virtual void FrameMoved(BPoint origin);
virtual void MenusBeginning();
private:
typedef BWindow super;
void CreateInputMenu();
void CreateReverbMenu();
void CreateViews();
@@ -77,36 +77,37 @@ private:
void OnPlayStop();
void OnShowScope();
void OnInputChanged(BMessage* msg);
void OnInputChanged(BMessage* message);
void OnReverb(reverb_mode mode);
void OnVolume();
void OnDrop(BMessage* msg);
void OnDrop(BMessage* message);
ScopeView* scopeView;
BCheckBox* showScope;
BMenuField* inputMenu;
BPopUpMenu* inputPopUp;
BMenuItem* inputOff;
BMenuField* reverbMenu;
BMenuItem* reverbNone;
BMenuItem* reverbCloset;
BMenuItem* reverbGarage;
BMenuItem* reverbIgor;
BMenuItem* reverbCavern;
BMenuItem* reverbDungeon;
BSlider* volumeSlider;
BButton* playButton;
ScopeView* fScopeView;
BCheckBox* fShowScopeCheckBox;
BMenuField* fInputMenuField;
BPopUpMenu* fInputPopUpMenu;
BMenuItem* fInputOffMenuItem;
BMenuField* fReverbMenuField;
BMenuItem* fReverbNoneMenuItem;
BMenuItem* fReverbClosetMenuItem;
BMenuItem* fReverbGarageMenuItem;
BMenuItem* fReverbIgorMenuItem;
BMenuItem* fReverbCavern;
BMenuItem* fReverbDungeon;
BSlider* fVolumeSlider;
BButton* fPlayButton;
bool playing;
bool scopeEnabled;
int32 inputId;
reverb_mode reverb;
int32 volume;
float windowX;
float windowY;
BMidiSynthFile synth;
SynthBridge* bridge;
bool instrLoaded;
bool fIsPlaying;
bool fScopeEnabled;
int32 fInputId;
reverb_mode fReverbMode;
int32 fVolume;
float fWindowX;
float fWindowY;
BMidiSynthFile fMidiSynthFile;
SynthBridge* fSynthBridge;
bool fInstrumentLoaded;
};
#endif // MIDI_PLAYER_WINDOW_H
#endif // _MIDI_PLAYER_WINDOW_H
+77 -124
View File
@@ -20,237 +20,192 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "ScopeView.h"
#include <Catalog.h>
#include <Locale.h>
#include <Synth.h>
#include <Window.h>
#include "ScopeView.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Scope View"
//------------------------------------------------------------------------------
// #pragma mark - ScopeView
ScopeView::ScopeView()
: BView(BRect(0, 0, 180, 63), NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_WILL_DRAW)
:
BView(BRect(0, 0, 180, 63), NULL, B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_WILL_DRAW),
fIsPlaying(false),
fIsEnabled(true),
fHaveFile(false),
fIsLoading(false),
fIsLiveInput(false),
fSampleCount(Bounds().IntegerWidth()),
fLeftSamples(new int16[fSampleCount]),
fRightSamples(new int16[fSampleCount]),
fScopeThreadID(-1)
{
SetViewColor(0, 0, 0);
playing = false;
enabled = true;
haveFile = false;
loading = false;
liveInput = false;
sampleCount = (int32) Bounds().Width();
leftSamples = new int16[sampleCount];
rightSamples = new int16[sampleCount];
}
//------------------------------------------------------------------------------
ScopeView::~ScopeView()
{
delete[] leftSamples;
delete[] rightSamples;
delete[] fLeftSamples;
delete[] fRightSamples;
}
//------------------------------------------------------------------------------
void ScopeView::AttachedToWindow()
{
finished = false;
threadId = spawn_thread(_Thread, "ScopeThread", B_NORMAL_PRIORITY, this);
if (threadId >= B_OK)
{
resume_thread(threadId);
}
SetViewColor(0, 0, 0);
fIsFinished = false;
fScopeThreadID = spawn_thread(_Thread, "ScopeThread",
B_NORMAL_PRIORITY, this);
if (fScopeThreadID > 0)
resume_thread(fScopeThreadID);
}
//------------------------------------------------------------------------------
void ScopeView::DetachedFromWindow()
void
ScopeView::DetachedFromWindow()
{
if (threadId >= B_OK)
{
finished = true;
if (fScopeThreadID > 0) {
fIsFinished = true;
status_t exitValue;
wait_for_thread(threadId, &exitValue);
wait_for_thread(fScopeThreadID, &exitValue);
}
}
//------------------------------------------------------------------------------
void ScopeView::Draw(BRect updateRect)
void
ScopeView::Draw(BRect updateRect)
{
super::Draw(updateRect);
if (loading)
{
if (fIsLoading)
DrawLoading();
}
else if (!haveFile && !liveInput)
{
else if (!fHaveFile && !fIsLiveInput)
DrawNoFile();
}
else if (!enabled)
{
else if (!fIsEnabled)
DrawDisabled();
}
else if (playing || liveInput)
{
else if (fIsPlaying || fIsLiveInput)
DrawPlaying();
}
else
{
DrawStopped();
}
}
//------------------------------------------------------------------------------
void ScopeView::SetPlaying(bool flag)
{
playing = flag;
}
//------------------------------------------------------------------------------
void ScopeView::SetEnabled(bool flag)
{
enabled = flag;
}
//------------------------------------------------------------------------------
void ScopeView::SetHaveFile(bool flag)
{
haveFile = flag;
}
//------------------------------------------------------------------------------
void ScopeView::SetLoading(bool flag)
{
loading = flag;
}
//------------------------------------------------------------------------------
void ScopeView::SetLiveInput(bool flag)
{
liveInput = flag;
}
//------------------------------------------------------------------------------
int32 ScopeView::_Thread(void* data)
int32
ScopeView::_Thread(void* data)
{
return ((ScopeView*) data)->Thread();
}
//------------------------------------------------------------------------------
int32 ScopeView::Thread()
int32
ScopeView::Thread()
{
// Because Pulse() was too slow, I created a thread that tells the
// ScopeView to repaint itself. Note that we need to call LockLooper
// with a timeout, otherwise we'll deadlock in DetachedFromWindow().
while (!finished)
{
if (enabled && (playing || liveInput))
{
if (LockLooperWithTimeout(50000) == B_OK)
{
while (!fIsFinished) {
if (fIsEnabled && (fIsPlaying || fIsLiveInput)) {
if (LockLooperWithTimeout(50000) == B_OK) {
Invalidate();
UnlockLooper();
}
}
snooze(50000);
}
return 0;
}
//------------------------------------------------------------------------------
void ScopeView::DrawLoading()
void
ScopeView::DrawLoading()
{
DrawText("Loading instruments" B_UTF8_ELLIPSIS);
DrawText(B_TRANSLATE("Loading instruments" B_UTF8_ELLIPSIS));
}
//------------------------------------------------------------------------------
void ScopeView::DrawNoFile()
void
ScopeView::DrawNoFile()
{
DrawText(B_TRANSLATE("Drop MIDI file here"));
}
//------------------------------------------------------------------------------
void ScopeView::DrawDisabled()
void
ScopeView::DrawDisabled()
{
SetHighColor(64, 64, 64);
StrokeLine(
BPoint(0, Bounds().Height() / 2),
StrokeLine(BPoint(0, Bounds().Height() / 2),
BPoint(Bounds().Width(), Bounds().Height() / 2));
}
//------------------------------------------------------------------------------
void ScopeView::DrawStopped()
void
ScopeView::DrawStopped()
{
SetHighColor(0, 130, 0);
StrokeLine(
BPoint(0, Bounds().Height() / 2),
StrokeLine(BPoint(0, Bounds().Height() / 2),
BPoint(Bounds().Width(), Bounds().Height() / 2));
}
//------------------------------------------------------------------------------
void ScopeView::DrawPlaying()
void
ScopeView::DrawPlaying()
{
int32 width = (int32) Bounds().Width();
int32 height = (int32) Bounds().Height();
// Scope drawing magic based on code by Michael Pfeiffer.
int32 size = be_synth->GetAudio(leftSamples, rightSamples, sampleCount);
if (size > 0)
{
int32 size = be_synth->GetAudio(fLeftSamples, fRightSamples, fSampleCount);
if (size > 0) {
SetHighColor(255, 0, 130);
SetLowColor(0, 130, 0);
#define N 16
int32 x, y, sx = 0, f = (height << N) / 65535, dy = height / 2 + 1;
for (int32 i = 0; i < width; i++)
{
int32 x;
int32 y;
int32 sx = 0;
int32 f = (height << 16) / 65535;
int32 dy = height / 2 + 1;
for (int32 i = 0; i < width; i++) {
x = sx / width;
y = ((leftSamples[x] * f) >> N) + dy;
y = ((fLeftSamples[x] * f) >> 16) + dy;
FillRect(BRect(i, y, i, y));
y = ((rightSamples[x] * f) >> N) + dy;
y = ((fRightSamples[x] * f) >> 16) + dy;
FillRect(BRect(i, y, i, y), B_SOLID_LOW);
sx += size;
}
}
}
//------------------------------------------------------------------------------
void ScopeView::DrawText(const char* text)
void
ScopeView::DrawText(const char* text)
{
font_height height;
GetFontHeight(&height);
float strWidth = StringWidth(text);
float strHeight = height.ascent + height.descent;
float stringWidth = StringWidth(text);
float stringHeight = height.ascent + height.descent;
float x = (Bounds().Width() - strWidth)/2;
float y = height.ascent + (Bounds().Height() - strHeight)/2;
float x = (Bounds().Width() - stringWidth) / 2;
float y = height.ascent + (Bounds().Height() - stringHeight) / 2;
SetHighColor(255, 255, 255);
SetLowColor(ViewColor());
@@ -258,5 +213,3 @@ void ScopeView::DrawText(const char* text)
DrawString(text, BPoint(x, y));
}
//------------------------------------------------------------------------------
+59 -23
View File
@@ -19,16 +19,15 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SCOPE_VIEW_H
#define _SCOPE_VIEW_H
#ifndef SCOPE_VIEW_H
#define SCOPE_VIEW_H
#include <View.h>
class ScopeView : public BView
{
public:
class ScopeView : public BView {
public:
ScopeView();
virtual ~ScopeView();
@@ -36,14 +35,13 @@ public:
virtual void DetachedFromWindow();
virtual void Draw(BRect updateRect);
void SetPlaying(bool flag);
void SetEnabled(bool flag);
void SetHaveFile(bool flag);
void SetLoading(bool flag);
void SetLiveInput(bool flag);
void SetPlaying(bool playing);
void SetEnabled(bool enabled);
void SetHaveFile(bool haveFile);
void SetLoading(bool loading);
void SetLiveInput(bool liveInput);
private:
typedef BView super;
static int32 _Thread(void* data);
@@ -54,19 +52,57 @@ private:
void DrawDisabled();
void DrawStopped();
void DrawPlaying();
void DrawText(const char* text);
bool finished;
bool playing;
bool enabled;
bool haveFile;
bool loading;
bool liveInput;
int32 sampleCount;
int16* leftSamples;
int16* rightSamples;
thread_id threadId;
bool fIsFinished;
bool fIsPlaying;
bool fIsEnabled;
bool fHaveFile;
bool fIsLoading;
bool fIsLiveInput;
int32 fSampleCount;
int16* fLeftSamples;
int16* fRightSamples;
thread_id fScopeThreadID;
};
#endif // SCOPE_VIEW_H
inline void
ScopeView::SetPlaying(bool playing)
{
fIsPlaying = playing;
}
inline void
ScopeView::SetEnabled(bool enabled)
{
fIsEnabled = enabled;
}
inline void
ScopeView::SetHaveFile(bool haveFile)
{
fHaveFile = haveFile;
}
inline void
ScopeView::SetLoading(bool loading)
{
fIsLoading = loading;
}
inline void
ScopeView::SetLiveInput(bool liveInput)
{
fIsLiveInput = liveInput;
}
#endif // _SCOPE_VIEW_H
+41 -45
View File
@@ -20,97 +20,93 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "SynthBridge.h"
//------------------------------------------------------------------------------
// #pragma mark - SynthBridge
SynthBridge::SynthBridge()
: BMidiLocalConsumer("Internal Synthesizer")
:
BMidiLocalConsumer("Internal Synthesizer")
{
// do nothing
}
//------------------------------------------------------------------------------
bool SynthBridge::Init(synth_mode mode)
bool
SynthBridge::Init(synth_mode mode)
{
if (be_synth->LoadSynthData(mode) == B_OK)
{
midiSynth.EnableInput(true, true);
if (be_synth->LoadSynthData(mode) == B_OK) {
fMidiSynth.EnableInput(true, true);
return true;
}
return false;
}
//------------------------------------------------------------------------------
BMidiSynth* SynthBridge::MidiSynth()
BMidiSynth*
SynthBridge::MidiSynth()
{
return &midiSynth;
return &fMidiSynth;
}
//------------------------------------------------------------------------------
void SynthBridge::NoteOff(
uchar channel, uchar note, uchar velocity, bigtime_t time)
void
SynthBridge::NoteOff(uchar channel, uchar note, uchar velocity, bigtime_t time)
{
midiSynth.NoteOff(channel + 1, note, velocity, time / 1000);
fMidiSynth.NoteOff(channel + 1, note, velocity, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::NoteOn(
uchar channel, uchar note, uchar velocity, bigtime_t time)
void
SynthBridge::NoteOn(uchar channel, uchar note, uchar velocity, bigtime_t time)
{
midiSynth.NoteOn(channel + 1, note, velocity, time / 1000);
fMidiSynth.NoteOn(channel + 1, note, velocity, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::KeyPressure(
uchar channel, uchar note, uchar pressure, bigtime_t time)
void
SynthBridge::KeyPressure(uchar channel, uchar note, uchar pressure,
bigtime_t time)
{
midiSynth.KeyPressure(channel + 1, note, pressure, time / 1000);
fMidiSynth.KeyPressure(channel + 1, note, pressure, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::ControlChange(
uchar channel, uchar controlNumber, uchar controlValue, bigtime_t time)
void
SynthBridge::ControlChange(uchar channel, uchar controlNumber,
uchar controlValue, bigtime_t time)
{
midiSynth.ControlChange(
channel + 1, controlNumber, controlValue, time / 1000);
fMidiSynth.ControlChange(channel + 1, controlNumber, controlValue,
time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::ProgramChange(
uchar channel, uchar programNumber, bigtime_t time)
void
SynthBridge::ProgramChange(uchar channel, uchar programNumber, bigtime_t time)
{
midiSynth.ProgramChange(channel + 1, programNumber, time / 1000);
fMidiSynth.ProgramChange(channel + 1, programNumber, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::ChannelPressure(
uchar channel, uchar pressure, bigtime_t time)
void
SynthBridge::ChannelPressure(uchar channel, uchar pressure, bigtime_t time)
{
midiSynth.ChannelPressure(channel + 1, pressure, time / 1000);
fMidiSynth.ChannelPressure(channel + 1, pressure, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::PitchBend(
uchar channel, uchar lsb, uchar msb, bigtime_t time)
void
SynthBridge::PitchBend(uchar channel, uchar lsb, uchar msb, bigtime_t time)
{
midiSynth.PitchBend(channel + 1, lsb, msb, time / 1000);
fMidiSynth.PitchBend(channel + 1, lsb, msb, time / 1000);
}
//------------------------------------------------------------------------------
void SynthBridge::AllNotesOff(bool justChannel, bigtime_t time)
void
SynthBridge::AllNotesOff(bool justChannel, bigtime_t time)
{
midiSynth.AllNotesOff(justChannel, time / 1000);
fMidiSynth.AllNotesOff(justChannel, time / 1000);
}
//------------------------------------------------------------------------------
+25 -29
View File
@@ -19,55 +19,51 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SYNTH_BRIDGE_H
#define _SYNTH_BRIDGE_H
#ifndef SYNTH_BRIDGE_H
#define SYNTH_BRIDGE_H
#include <MidiConsumer.h>
#include <MidiSynth.h>
class SynthBridge : public BMidiLocalConsumer
{
public:
class SynthBridge : public BMidiLocalConsumer {
public:
SynthBridge();
bool Init(synth_mode mode);
BMidiSynth* MidiSynth();
virtual void NoteOff(
uchar channel, uchar note, uchar velocity, bigtime_t time);
virtual void NoteOn(
uchar channel, uchar note, uchar velocity, bigtime_t time);
virtual void KeyPressure(
uchar channel, uchar note, uchar pressure, bigtime_t time);
virtual void ControlChange(
uchar channel, uchar controlNumber, uchar controlValue,
virtual void NoteOff(uchar channel, uchar note, uchar velocity,
bigtime_t time);
virtual void ProgramChange(
uchar channel, uchar programNumber, bigtime_t time);
virtual void NoteOn(uchar channel, uchar note, uchar velocity,
bigtime_t time);
virtual void ChannelPressure(
uchar channel, uchar pressure, bigtime_t time);
virtual void KeyPressure(uchar channel, uchar note, uchar pressure,
bigtime_t time);
virtual void PitchBend(
uchar channel, uchar lsb, uchar msb, bigtime_t time);
virtual void ControlChange(uchar channel, uchar controlNumber,
uchar controlValue, bigtime_t time);
virtual void AllNotesOff(
bool justChannel, bigtime_t time);
virtual void ProgramChange(uchar channel, uchar programNumber,
bigtime_t time);
virtual void ChannelPressure( uchar channel, uchar pressure,
bigtime_t time);
virtual void PitchBend(uchar channel, uchar lsb, uchar msb,
bigtime_t time);
virtual void AllNotesOff(bool justChannel, bigtime_t time);
protected:
virtual ~SynthBridge() { }
virtual ~SynthBridge() {}
private:
BMidiSynth midiSynth;
BMidiSynth fMidiSynth;
};
#endif // SYNTH_BRIDGE_H
#endif // _SYNTH_BRIDGE_H