The Media Kit provides two audio streams. The ADC stream carries data from the input source (line-in, CD, or microphone), and the DAC stream carries data to line-out and the built-in speaker. If you're experimenting with digital audio effects, then you may wish to connect the input stream to the output stream so that you can hear what your favorite audio CD sounds like when processed by your favorite audio algorithm.
The Nino ("noise in/noise out") class is a simple test bed that connects
the two audio streams. A Nino object contains a pointer to a buffer, two
semaphores for controlling the stream functions, and two BAudioSubscriber
objects, one for the ADC stream and one for the DAC stream:
struct Nino :BObject
{Nino
();~Nino
(); char*buffer
; sem_idbufferReady
; sem_idbufferUsed
;BAudioSubscriber
*adcSubscriber
;BAudioSubscriber
*dacSubscriber
; };
The global "stream functions" are called
adc_reader()
and dac_writer()
.
Each stream function is called once per buffer. When adc_reader()
gets a
buffer, it releases the bufferReady
semaphore and
waits for dac_writer()
to release bufferUsed.
static booladc_reader
(void*arg
, char*adc_buf
, longcount
) {Nino
*my_nino
= (Nino
*)arg
;my_nino
->buffer
=adc_buf
;release_sem
(my_nino
->bufferReady
);acquire_sem
(my_nino
->bufferUsed
); returnTRUE
; } static bool dac_writer (void*arg
, char*dac_buf
, longcount
) {Nino
*my_nino
= (Nino
*)arg
;acquire_sem
(my_nino
->bufferReady
);memcpy
(dac_buf
,my_nino
->buffer
,count
);release_sem
(my_nino
->bufferUsed
); returnTRUE
; }
To simplify the example, these functions assume that both streams have
the same buffer size. Also, to avoid erasing the output of other DAC
stream subscribers, the call to memcpy()
should be replaced by a mixing
function: You should add the contents of my_nino->buffer
into dac_buf
rather than simply clobbering the latter with the former.
The Nino constructor initializes the semaphores and subscribers and enters the subscribers into their respective streams.
Nino
::Nino
() {bufferReady
=create_sem
(0, "buffer ready");bufferUsed
=create_sem
(0, "buffer used");adcSubscriber
= newBAudioSubscriber
("Nino ADC reader");dacSubscriber
= newBAudioSubscriber
("Nino DAC writer");adcSubscriber
->Subscribe
(B_ADC_STREAM
,B_SHARED_SUBSCRIBER_ID
,TRUE
);dacSubscriber
->Subscribe
(B_DAC_STREAM
,B_SHARED_SUBSCRIBER_ID
,TRUE
);adcSubscriber
->EnterStream
(NULL
,FALSE
,this
,adc_reader
,NULL
,TRUE
);dacSubscriber
->EnterStream
(NULL
,TRUE
,this
,dac_writer
,NULL
,TRUE
); }
The Nino destructor must be careful to exit the stream, cleanly. It waits
for dacSubscriber
to exit before it deletes the semaphores, then it waits
for adcSubscriber
to exit before it deletes the subscribers.
Nino
::~Nino
() {dacSubscriber
->ExitStream
(TRUE
);delete_sem
(bufferReady
);delete_sem
(bufferUsed
);adcSubscriber
->ExitStream
(TRUE
); deleteadcSubscriber
; deletedacSubscriber
; }
When testing a Nino, remember to make sure that the B_ADC_IN
and
B_DAC_OUT
devices are enabled, and that B_LOOPBACK
is disabled (See the
documentation for BAudioSubscriber
in "The Be Book").
During the lifetime of a Nino object the ADC input stream will be fed to the DAC output stream. This will make it easy to experiment with digital processing of any audio source.
I completed a Bachelor of Science (Information Systems) at the University of New South Wales in 1994. Since then I've moved into the banking and finance industry, working as an analyst and programmer. (It's not as much fun as software engineering, but the money is better.) Although I like the business environment—there are a number of fringe benefits—I hate the long hours. Mostly because this doesn't give me enough time to develop my BeOS™ applications.
From my brief experience with the BeBox, it seems that the BeOS is significantly different from other operating systems I have used (including AmigaOS and UNIX), in that the OS does a lot more for you. This is something that you actually have to get used to. Normally—on other platforms—you spend half your time setting up your program environment (utility functions, code structures, and so on). With the BeOS, on the other hand, a lot of the setting up is done for you, allowing you to concentrate on what it is that you want your application to do, such as formatting documents, creating sounds, and other functions.
Of course nothing's perfect, and there are, in my opinion, some improvements to be made. For example, the interface is currently kinda ugly (IMHO), and I'd really like more control objects (such as a "BFuelGauge" object). Also, I'm a bit concerned by the fact that the OS is "inspired" by the Mac—I've found that the Mac takes a very simplistic view towards what functionality they need in the OS; I wouldn't want this attitude to influence the design decisions that Be makes.
But I can't argue much with the direction of the BeOS so far: It's new, it's not Wintel, it's fun, and it's targeted at technically minded people. The fact that I can have input into the design of BeOS, and that it is being influenced by people all over the Internet is exciting.
My short term plan is to develop a system monitor program. It looks a bit like a Browser window in "List View" mode, but instead of showing files, it displays teams, threads, semaphores, and other system resources. It's already working in basic form, but it needs some bells and whistles before it's made public—this way I can learn more about the OS in the process. My long term plan is to develop some Internet software, such as an irc, ftp, or news client.
The system monitor should be available within two months, the next "big" project should be in alpha or beta in less than six months.
Our demo port of the BeOS to the PowerMac was very well received at the Macworld show in Boston last week. In our booth, we showed the port running on an entry-level Power Computing PowerCenter 120, a 120 MHz 604 uniprocessor PowerMac clone. In their booth, Power Computing had the BeOS running on a 200 MHz 604e uniprocessor machine. Both machines impressed us—and the many visitors to the booths—with their performance running the BeOS and with the stability and robustness of the port. Thus, the decision to finish the port and commercialize it was an easy one. We've had many questions from developers and users about BeOS on the PowerMac, and I'll try to answer some of them here. In many cases, we really haven't figured out the answers yet, so please bear with us as we explore the possibilities more and gather feedback from our many friends, partners, and customers.
Last week's Macworld Expo in Boston reminded me of the same show in August 1985. At that time, Apple was in trouble: There had been turmoil in the executive suite, the company had announced a big quarterly loss and a layoff. The conventional wisdom was that Apple and the Mac were in big trouble. The show floor didn't reflect any of that insight then. Customers and developers were too busy doing business to inhale the noxious predictions.
History doesn't quite repeat itself, but eleven years later the Boston Macworld visitors and exhibitors were obviously oblivious of oracles of obliteration. One might argue that only the faithful came to the show. But that's always been the case, and they came in large numbers (50,000 we're told) and they were spending money.
One of the key differences this year was the strong presence of clone makers, with Power Computing leading the pack. And not just in hardware performance, but also in marketing presence. I'm not just referring to their highly visible bungee-jumping crane, frequented by various members of our team, or to the video wall in their crowded booth. Power Computing machines were everywhere on the floor. The Apple Developer Greenhouse was populated with Power Computing boxes—but not the Apple pavilion.
Speaking of Power Computing, the port of the BeOS on a Power Computing system was well received, better than we expected. Because we had gone through the BeOS port from the AT&T Hobbit processor to the PowerPC, we had proven our system to be portable. We even knew how portable it is -- very. Meaning its design made the task much easier than, say, porting Windows 95. But that was internal knowledge.
Perhaps we made the classical mistake of assuming others knew what we knew. In our industry, so many lofty claims have been made that skepticism, polite or otherwise, has become the norm. Show me. And show we did. At the last minute, we got one the newest 225 MHz Power Computing machines, Bob Herold was able to make the required processor ID modification and, voila, the BeOS ran on the fastest Mac clone available.
Removing the hardware variable simplifies the evaluation of our OS. Before, one could look at our admittedly nonstandard multiprocessor hardware and wonder if the perceived high performance wasn't due to some undisclosed hardware advantage (other than the number of processors). On the assumption that it's dangerous to develop software on hardware faster than what customers will use, we deliberately picked the slowest member of the PPC family for our first BeBox system, thus forcing us to watch the efficiency of our code. This strategy worked for performance, but it didn't sufficiently clarify its main source. Now you can see the Mac OS and the BeOS on the same system. In one demonstration we prove both portability and performance.
Still, we have a lot to do before the port becomes a commercial product. First, we need to release it to Be developers for testing and comments. Second, some functions remain to be implemented, such as the floppy driver. Third, we need to evaluate which systems we can and should support. In particular, we're getting many requests to support 601- based machines (which is still being evaluated), and 68K Macs (which is extremely unlikely). Once we have a stable product, supporting a reasonable range of hardware, we can turn to the issue of distribution and pricing. Hopefully, we'll be ready for the next Macworld in January 97 in San Francisco.
Many other questions remain, such as various forms of integration with the MacOS and the reintroduction of the hardware variable. I'll deal with them in future columns, starting next week.