Be Newsletter
Issue 91, September 17, 1997
Table of Contents
BE DEMO TOUR: BeOS Demo in Portland, OR and Orange County, CA
- Thursday September 18, 1997
BeOS demo at PDX Be Users Group in Portland, Oregon
When: 6:30pm
Where:
Trinity Place Apartments
117 NW Trinity Place, #48
Portland, OR
For directions, please check: http://www.teleport.com/~pdxbug
- Saturday October 4, 1997
BeOS demo at the Orange Apple Computer Club
When: 9:30am
Where:
Orange Coast College
Chemistry Building, Room 214
Costa Mesa, CA
For directions, please check: http://www.oacc.org/
BE ENGINEERING INSIGHTS: Introducing the BSynth Class
By Marc Ferguson
One of the new features in the Preview Release is the
software MIDI synthesizer. The Midi Kit contains three
classes for controlling the MIDI synthesizer: BSynth ,
BMidiSynth , and BMidiSynthFile . The BSynth object is the
interface to the underlying synthesizer engine. BMidiSynth
is a subclass of BMidi that forwards MIDI events to the
BSynth object. And BMidiSynthFile is a specialization of
BMidiSynth which reads from a standard MIDI file.
An application that uses the MIDI synthesizer starts by
creating a BSynth object. Currently you can only create one
BSynth object per application, but you probably only need
one anyway. After creating the BSynth , call
LoadSynthData(B_BIG_SYNTH) on it. This tells the BSynth to
use the instrument file "/boot/beos/etc/synth/big_synth.sy ".
If the call to LoadSynthData() fails, it probably couldn't
find the instrument file. LoadSynthData() does not load the
instruments into memory yet. Unless you are playing directly
from a MIDI file you will still need to load the
instruments.
The application then creates a BMidiSynth object which you
can send MIDI events to just as you would to any other BMidi
object. After creating the BMidiSynth , call EnableInput()
on it. The first argument to EnableInput() should be true,
and the second argument indicates whether to pre-load all
instruments from the instrument file.
The easiest way to see how this works is to try it. Here is
a program that plays six notes on a piano. Don't forget
to link with libmidi.so .
#include <MidiSynth.h>
main ()
{
BSynth synth;
status_t err = synth.LoadSynthData(B_BIG_SYNTH);
if (err) {
printf ("LoadSynthData: %x\n", err);
return -1;
}
BMidiSynth song;
err = song.EnableInput(true, false);
if (err) {
printf ("EnableInput: %x\n", err);
return -1;
}
int channel = 1; // MIDI channel number
int instrument = B_ACOUSTIC_GRAND; // GM instrument
song.LoadInstrument(instrument);
song.ProgramChange(channel, instrument);
for (int i = 0; i < 6; i++) {
song.NoteOn(channel, 60 + 5 * i, 127);
snooze(250000);
}
snooze(2000000);
song.AllNotesOff(FALSE);
return 0;
}
In this example "channel" is a MIDI channel number (1-16),
and "instrument" is a General MIDI instrument number. The
instrument numbers are represented by the midi_axe constants
defined in MidiDefs.h . The ProgramChange() call associates
an instrument with a channel.
You can also play the synthesizer from an external MIDI
keyboard. If you are on a Mac you will also need a Mac MIDI
interface (I'm using an "Opcode Midi Translator II"). To do
this, you just connect a BMidiPort to the BMidiSynth :
BSynth synth;
synth.LoadSynthData(B_BIG_SYNTH);
BMidiSynth song;
printf("Loading instruments...\n");
song.EnableInput(true, true);
printf("Done.\n");
BMidiPort port;
status_t err = port.Open("midi2"); // printer port on Macs
if (err)
printf ("Open: %x\n", err);
port.Connect(&song);
port.Start();
In this case the second argument to EnableInput() is true.
So all the instruments will be pre-loaded, which may take
a few seconds. Note that on Macs, "midi1" is the
modem port and "midi2" is the printer port.
To play a MIDI file, use a BMidiSynthFile instead of a
BMidiSynth :
#include <MidiSynthFile.h>
main ()
{
BSynth synth;
synth.LoadSynthData(B_BIG_SYNTH);
char* filename = "/boot/optional/midi/BeBoxBeBop.mid";
BMidiSynthFile song;
entry_ref ref;
get_ref_for_path(filename, &ref);
status_t err = song.LoadFile(&ref);
if (err) {
printf ("LoadFile: can't open %s\n", filename);
return -1;
}
song.Start();
while (!song.IsFinished())
snooze(1000000);
song.Fade();
return 0;
}
There are also several other BSynth methods such as
SetReverb() and SetSynthVolume() to experiment with, but
this is enough to get started using the BSynth . So dig out
those old MIDI keyboards and plug them in!
A Problem with Extensions
By Baron Arnold
Inspiration comes wheeling around the corner like a '68
Chevy Camero: screaming rubber, hoodless, with a caved-in
passenger door. Greek blue and pumped to evade, or catch, or
surprise.
Effort squeezes into a tiny hallway, sweaty and breathing
hard. Then comes the split, the lesson, the book, the movie
and you wanna know the rest...
Buy the rights.
How bizarre.
I spent 35 minutes waiting for my friend's 9500/132 to
upgrade itself from 7.5.something to 7.6. Then Corel's word
processor would lock up whenever she tried to save a
document. Neat.
So she called Corel and they told her it was $25 for help.
Neat.
Tonight she told me that it turned out to be a problem with
Extensions. Imagine that. A problem with Extensions. You
could almost write a recent-history book called...
"A Problem with Extensions"
And you could write it with StyledEdit, and you could look
up the words you don't know how to spell with NetPositive
targeted to autoload your favorite online dictionary. You
could even e-mail the final manuscript to your publisher,
click back and check your bank account to make sure they
don't stiff you on the five cents a word you're paid to
describe the very disappointing behaviour of one careless
twit behind that big fruity curtain.
Because baby you had it all along.
BeOS CDs are breeding like AOL floppies.
She asked if the BeOS would save her, and I said, "Yes."
It's simple, really.
She's a student. She wants e-mail, a word processor, and
Internet access.
She doesn't want a million upgrade headaches.
She doesn't need all those fancy legacy applications.
She's got nice hardware.
Calgon, take me away.
PR2 is almost ready.
It fixes most of what you were asking for.
Oh and those of you who have been submitting PPP bugs,
please remember to tell us what kind of modem you have and
if possible, what kind of modem you are connecting to.
So blah blah blah Power Computing and Apple, and blah blah
blah CHRP and BURP (Be United Reference Platform.) Blah blah
blah Moto and does it really matter anyway? Latitude is
coming. Chill out for a couple months. Then it's gonna get
VERY interesting. You saw the demo.
I'll see a thousand BIntel machines clog my cube before
Xmas, and by Spring you'd be a fool not to be running
multi-boot on your 95% of the back seat.
If you kids don't stop fighting I'll turn this IPO around
right now!
And speaking of super-duper, if anyone out there at Radius
is reading this, then we've got a couple of bugs with those
kool expensive cards you sell. Achieve greater market
penetration, contribute to the Be Hardware Fund. Pack up your
dreams of compatibility and ship them to:
Baron Arnold
800 El Camino Real, Suite 300
Menlo Park, CA 94025.
Oh and props out to the people who built the Be Machine.
I use it as my main testing box.
It's fast and blue. =)
I love the overspray on the CD drawer the most.
Very kool.
But seriously, about the Be Hardware Fund, if you are
somehow in charge of something where what you make is
something you'd like to see BeCompatible, send me one please?
And for those of you just tuning in, the Intel world is just
so chock full of hardware options, send me stuff. Really. You
know the song. We'll try support it, but only if we can test
it.
Speaking of testing, I wanna publicly thank Jake Hambey.
He's filed a million good bugs and helped me take a few very
big steps into scripting the testing grunt work by porting
Expect. If you ever wanted to script a telnet session then
get Expect from BeWare.
Wow. Thanks, Jake.
And ya know?
He plays a mean ocarina. =)
Driving up to the Avenues the other night, I was telling
Jake that it's really the people at Be who have allowed us
to develop at such a rapid rate. It has been the
inter-linking of so many different personalities, of so many
different work styles: so many concessions and
acknowledgments made in the name of The Right Way. It's
quite simple, and yet, terrifically effective. We joked with
abstraction about the BeActionPlaySet, plastic StarWars-size
BePlay figures of Dominic, and Benoit, and George. And we
considered, with respect, how many more of each individual
engineer Be would need to cover perfectly the near-future
work to be done. As for testing, I think just one each of
Ming and Mel and Jake and I could handle it. Well, maybe two
Mings. One for each wing. =) We'll definitely need more
space though.
And so the fourth floor acquisition is but one release away
(gotta put those engineers somewhere). MIA and CBS and DVD
and I'm a little worried that we will grow too fast. That
there will be so much to do that we won't have time to find
out who our co-workers are. What they love and dislike. What
they have seen. Where they have been. Hmmm. Perhaps this is
an attempt to jinx us. Keep the lid on our secret a little
longer. Let this GUI simmer in these, the last of our simple
days.
There are so many things we'd like to give you.
We talk about them every day.
At lunch, at dinner, on the weekends.
We want to give you everything.
So blah blah blah MacWorld and Comdex.
Blah blah blah shop talk shop talk shop talk.
Watch for BeShred in a shrink wrap near you.
Get your ticket now for "The Power of the Word NO."
Hang on to your sense of humor and consider please
that 150%, is just a sleepier 110.
Spin a few times, but never forever.
Try to be humble and honest and clever.
Love = work + your life and your friends so Valerie,
here's where my article ends.
News from the Front
By William Adams
Are you AllAttached? When you're using a programming
framework, sometimes it takes a while to figure out all the
ins and outs of what happens when. The BeOS programming
interface is clean and simple to use, but learning a little
bit about proper usage can go a long way. I was recently
playing with a library of code which was largely unknown to
me, when my application kept crashing on initialization. It
turns out that I was trying to set a target handler for a
object that didn't quite exist yet. Specifically it was a
button in one of the views that is not created until the
AttachedToWindow() method is called.
Well, AttachedToWindow() gets called when you actually add a
view to a window's hierarchy. At this point, you can call
the Window() method of a view to get a pointer to the window
you're attached to. Also, at this point none of your child
view's AttachedToWindow() methods will have been called, and
you know nothing about your sibling views. So what's safe to
do here? Things that are directly related to your view that
you didn't already do in your constructor. You might add
child views, set your font and colors and all that.
What about AllAttached() ? You want to use this when it is
absolutely paramount that all of your child views have been
attached. This would be the case if you are going to perform
an action that depends on the existence of your child views
in the hierarchy.
So let's say there should be a button in your view with the
name "OK". And you want to set the target handler of that
button to be yourself. Ideally you want to do the following:
BButton *aButton = (BButton *)FindView("OK");
if (0 != aButton)
aButton->SetTarget(this);
Where is it safe to put this code? Well, if you were the
view writer and you know explicitly when the button was
created, then you can do it anywhere you want. If you are
sub-classing some other view, then it's safest to
stick the code in the AllAttached() method, assuming that
the original view author created the button in their
AttachedToWindow() method.
This is what I did, and my bugs went away. Just goes to show
you...
Then I got to figuring, there's got to be more uses of
BMessageFilter s. So I sought to simplify the HelloWorld
application. Often times when you create a simple little
app, you might create a sub-class of BApplication and
BWindow , simply to implement the BWindow::QuitRequested()
method so when the window closes, the app will quit. Well,
that seems like a bit much just to quit an app, how about a
filter?
#include <MessageFilter.h>
#include <Application.h>
#include <Window.h>
static filter_result
QuitFilter(BMessage *msg, BHandler **target,
BMessageFilter *filter)
{
be_app->PostMessage(B_QUIT_REQUESTED);
return B_SKIP_MESSAGE;
}
In this case, whenever this filter receives a message, it
will post a message to the application object asking it to
quit. You could have actually checked the *msg passed in to
make sure what type of message it is, but in this very
simple case we don't care. As you will see below, the filter
is installed in such a way that only one type of message
will come to this filter in the first place.
So, now my simple application to pop a window up on the
screen and quit when it's closed looks like this:
BRect gWindowSize = BRect(100,80,260,120);
class HelloView : public BView {
public:
HelloView(BRect frame, char *name);
virtual void Draw(BRect updateRect);
};
HelloView::HelloView(BRect rect, char *name)
: BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW)
{
}
void HelloView::Draw(BRect)
{
SetFont(be_bold_font);
SetFontSize(24);
MovePenTo(BPoint(10, 30));
DrawString("Hello, World!");
}
main()
{
// Start off with an instance of an application object
BApplication *myApplication = new BApplication('HLWD');
// Setup our window
BWindow *aWindow = new BWindow(gWindowSize, "Hello",
B_TITLED_WINDOW, B_NOT_RESIZABLE);
// Create a filter that will only look at B_QUIT_REQUESTED
// message. These are sent to the window whenever the
// close box is clicked on, or when you do an Alt-Q.
BMessageFilter *filter =
new BMessageFilter(B_QUIT_REQUESTED, QuitFilter);
aWindow->AddCommonFilter(filter);
// view rect should be same size as window rect but with
// left top at (0, 0)
gWindowSize.OffsetTo(B_ORIGIN);
HelloView *aView =
new HelloView(gWindowSize, "HelloView");
// add view to window
aWindow->AddChild(aView);
// make window visible
aWindow->Show();
// Start the application running
myApplication->Run();
// After it is finished running, delete it
// to be nice and tidy
delete(myApplication);
return(0);
}
This is a very simple app. All it needs is a specialized
view to be added to the window and you're all set. You can
use this as a template for knocking out those quick and
dirty apps where you just want to try something out in a
window real quick.
If all your view does is draw something, you could
conceivably create a simple base class view that you could
install a drawing function into. It would then in turn call
this drawing function whenever the Draw() method was called.
Fun things can be done with this. If you haven't already
started playing with filters, then maybe this gives you some
incentive. They really are flexible and allow you to quickly
and dynamically change the nature of your application simply
by installing and removing filters.
How can filters be used for an interface builder? Maybe
that's what someone can do next?
The Photoshop Machine
By Jean-Louis Gassée
CHRP had the right goal: To create a hardware standard
around the PowerPC similar in intent to what IBM's PC/AT
became for the Intel processor, the core platform around
which a huge industry was built. Almost forgotten is that
while IBM designed the PC/AT, it lost control of the
standard. It was IBM's very loss of control that gave
birth to the clone industry, now driven, if not controlled,
by Intel and Microsoft.
This bit of history isn't lost on Apple's management.
They remember IBM's futile attempt to regain control of
the PC standard with the proprietary PS/2 platform and
have concluded that even with a hypothetical "private"
version of CHRP, they would lose the hardware battle. In many
respects, CHRP would have been a bigger danger to Apple than Power
Computing ever was: Power's engineers were industrious and
talented -- had CHRP lived, industry and talent wouldn't
have been necessary. Lower the bar and increase the competition.
Regardless of what we think of Apple's decision to bring the
Mac cloning experiment to an end, the demise of CHRP is a
logical consequence of the de-cloning move.
Yet, many have stated their opinion that there is life left
in CHRP -- potentially. As a result, we've seen several
suggestions on the 'Net with a view to breathing commercial
life back into an "independent" PowerPC platform.
These observers go on to suggest there must be a
considerable inventory of CHRP systems or, if not systems,
ready-to-assemble components otherwise condemned to the
scrap heap. The performance of CHRP hardware demonstrated by
Motorola and IBM is enticing; why not use cost-competitive,
if not "devalued" CHRP hardware to build a BeOS-based
"Photoshop box"?
This is an engaging suggestion, and the thought experiment
it triggers will allows us to explore issues such as
dedicated systems vs. general purpose ones, the cost and
performance benefits of the BeOS for a given application
space and porting existing applications vs. enabling new
ones.
If I follow the dominoes correctly, Photoshop has a large
user base, these users are hungry for performance, or cost
savings, or both, and many would buy one or more additional
"boxes" just to run Photoshop if they saw enough
productivity gains in a dedicated machine. A dual
processor CHRP system just running a BeOS version of
Photoshop would excite a large enough user population
to incite one or more hardware manufacturers to ship such
a product. In turn, this would constitute a sizeable
enough business to trigger Adobe into making Photoshop
available for this system.
This, needless to say, is purely hypothetical and I don't
want to imply that any of the companies mentioned or alluded to
have expressed the slightest shadow of interest for the
idea. This is purely a thought experiment.
Even with this stipulation, I won't speculate too much as to
why Adobe would or wouldn't consider such an idea.
Performance is always welcome by Photoshop users and we've
demonstrated substantial improvements on existing hardware
as well as on affordable multi-processor systems.
Still, if I dare to imagine Adobe's concerns, there must be
the cost of producing a new version of Photoshop and there
must be the alternative of the Intel space. In the latter,
there is inexpensive dual-processor hardware and interesting
performance improvements in the making. I don't know what
would happen if Adobe would let it be known they'd support
the concept of a dedicated Photoshop system. Where would the
best bids come from?
In the past, dedicated systems haven't fared too well. Take
the word processor. In the early difficult days of the Mac,
many observers remarked on the ease of use and beautiful
printing obtained with MacWrite. They concluded the Mac
should be reconfigured as a dedicated word processor. That
didn't happen. Does this apply to the current idea? On the
one hand customers have shown a liking for a system with a
wide range of actual or potential uses. On the other hand,
word processing applications are not driven by the thirst
for performance Photoshop users experience.
Addressing cost, using the BeOS in a dedicated configuration
might do more than add performance. Using the modularity of
the BeOS and targeting Photoshop users could further reduce
the footprint of the system and thus save hardware dollars.
Still, others will remind us that hardware ought to stay as
close as possible to the mainstream in order to best capture
the benefits of competition between vendors.
Lastly, there is the question of new software versus mature
applications. On this issue, the assumptions of today's
thought experiment matter a great deal. Historically, ports
from one generation of operating systems to a new one don't
do well. The reasons might be that the technical constraints
of the old design don't permit effective use of the new
platform, or it could be that the press of business on
the existing front leaves no financial or psychic energy for
a risky bet on a new vehicle. (DOS to Windows, or Apple II
to Mac are changes of generation; Mac to Windows isn't; Mac
or Windows to the BeOS are.)
What differs in today's thought experiment is the assumption
that a dedicated box would be sold almost exclusively to
existing Photoshop users who want the simplest, least
disruptive, most effective way of improving their existing
work flow. In such a context a port could do very well.
It is too early to tell if the many suggestions we've seen
on the 'Net for a "Photoshop box" will lead to an actual
implementation, but we certainly appreciate the positive
sentiments they convey.
|