You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
7.1 KiB
164 lines
7.1 KiB
15 years ago
|
amaroK VIS_PLAN - Created: 22-11-2003
|
||
|
|
||
|
|
||
|
Abstract
|
||
|
========
|
||
|
In order to create a visualisation framework that is superior to anything
|
||
|
popular available for Linux today we should plan amaroK's thoroughly
|
||
|
before implementation. This document exists to map out our ideas and is
|
||
|
available for anyone to edit, please, if you have some good suggestion, or
|
||
|
experience with this kind of work, add some comments! Thanks, Max Howell
|
||
|
|
||
|
|
||
|
Formatting
|
||
|
==========
|
||
|
The document has no regimented formatting, but do try to keep the wordwrap set
|
||
|
the same! Feel free to recommend formatting if the document becomes
|
||
|
unmanageable.
|
||
|
|
||
|
|
||
|
Plan
|
||
|
====
|
||
|
My initial thoughts were to make visualisations a separate process rather than
|
||
|
separate thread. The reasoning being, a crash in the vis won't crash amaroK,
|
||
|
threads can be unmanageable, *nix is good for new processes, we can use DCOP to
|
||
|
control the vis and presumable we just need to pass a handle to the relevant
|
||
|
arts server to the vis and leave it. Since the music playing bit is already a
|
||
|
separate process it makes sense to make the visualisation separate too! Also
|
||
|
this may mean that these visuals could be separate from amaroK and just depend
|
||
|
on KDE.
|
||
|
|
||
|
I was also thinking that this means it may be possible to not use Qt to
|
||
|
do rendering. There are probably better libraries for high speed graphics and if
|
||
|
there isn't a way to make DCOP not depend on a QApplication, then maybe we could
|
||
|
write something. It would be sorted if we could make something that can react to
|
||
|
arts sound output in general.
|
||
|
<markey> we could use SDL for 2d and OpenGL for 3d rendering.
|
||
|
|
||
|
I was also thinking it would be neat to embed the visuals somehow into amaroK,
|
||
|
so as the background in the playlist perhaps (I know, this would probably not
|
||
|
work well due to the need to re-render all the AA text all the time, but still
|
||
|
the idea is neat) This is similar to Sonique on Windows if anyone has ever used
|
||
|
it.
|
||
|
|
||
|
If we make the visualisations not amaroK specific it may be possible to embed
|
||
|
visualisations into the Kicker, onto the desktop, etc.
|
||
|
|
||
|
Do we want more than an FFT of the audio data? Would other data
|
||
|
be useful to visuals at all? Beat detection certainly would be a useful thing to
|
||
|
offer the visualisations, and it would certainly stop every visual implementing
|
||
|
its own detection.
|
||
|
|
||
|
|
||
|
Vis Process Architecture
|
||
|
========================
|
||
|
I suggest having a separate process for each visualization. Each vis process would
|
||
|
only load one visualization plugin. This way we have good crash safety and it's also
|
||
|
possible to develop and ship plugins separately from amaroK. So we have one "vis loader
|
||
|
skeleton" in amaroK, which will be instanciated whenever we need a vis. This loader could
|
||
|
get started with the vis plugin as cli argument. It would also contain all the socket and
|
||
|
interface needed to communicate with amaroK.
|
||
|
|
||
|
We should take care to keep the design as simple as possible.
|
||
|
|
||
|
<mxcl> Why make visualisations plugins as well as binaries? It seems sensible to have
|
||
|
visualisations as separate processes and then communicate with amK through the socket.
|
||
|
Why have the extra layer of plugins if you're going to force each process to only load
|
||
|
one plugin anyway?
|
||
|
|
||
|
|
||
|
Merging Analyzer and Vis
|
||
|
========================
|
||
|
If we decide on unifying vis and analyzer, the question arises how to get the rendered
|
||
|
bitmap graphic back into amaroK's playerwidget. It seems we have the following options:
|
||
|
|
||
|
* Writing it into a shared memory buffer. amaroK must then read the buffer and bitBlt()
|
||
|
the pixmap into the framebuffer
|
||
|
* Transferring the pixmap over a Unix socket (or UDP network socket). This can amount to
|
||
|
several megabytes per second. After the transfer amaroK must bitBlt() it to the
|
||
|
framebuffer.
|
||
|
* Writing it directly into the framebuffer at the desired position, like a video overlay.
|
||
|
There might be technical problems doing so, and it will be difficult when the user
|
||
|
moves the window.
|
||
|
|
||
|
|
||
|
|
||
|
[Comment from muesli, to be integrated into the paragraphs above]
|
||
|
|
||
|
imho, it would be cool to offer this service via sockets. udp would fit per-
|
||
|
fectly, since it has to be realtime, anyways (better loose a packet and show
|
||
|
nothing, instead of a out-of-sync beat). e.g., you would be able to have
|
||
|
various of visualizations-clients connected to amarok, showing different
|
||
|
animations, at the same time. this would also remove the DCOP-dependency-chains
|
||
|
for the OpenGL clients.
|
||
|
|
||
|
right now, i can imagine two implementation methods:
|
||
|
|
||
|
A) transmit the frequency vector of the analyzer to the vis-client. beat-detection and
|
||
|
all that stuff gets done by the vis-client.
|
||
|
|
||
|
B) basic beat-detection and music analysis gets done by amarok itself. the
|
||
|
results of that process are sent to the vis-clients.
|
||
|
|
||
|
<mxcl> IMO it would be good to offer services like beat detection. This
|
||
|
way vis-writers have less to do and are more likely to write a vis since
|
||
|
beat-detection is already done, also it means beat-detection is likely to be better
|
||
|
as we will over time offer a really good implementation, and it means that if the user
|
||
|
has many visuals running, the beat-detection is only done once for all visualisations.
|
||
|
|
||
|
[/Comment by muesli]
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//FIXME <markey> beat detection code temporarily moved here
|
||
|
|
||
|
/*
|
||
|
// Muesli's Beat Detection - A Night's Oddysee
|
||
|
// shift old elements
|
||
|
for ( uint x = 0; x < 18; ++x )
|
||
|
for ( uint y = 42; y > 0; --y ) m_beatEnergy[x][y] = m_beatEnergy[x][y - 1];
|
||
|
|
||
|
// get current energy values
|
||
|
for ( uint x = 0; x < pScopeVector->size(); ++x ) m_beatEnergy[x][0] = pScopeVector->at(x);
|
||
|
|
||
|
// compare to old elements and get averages
|
||
|
double beatAvg[18];
|
||
|
// double beatVariance[18];
|
||
|
// double beatMood[18];
|
||
|
|
||
|
for ( uint x = 0; x < 18; ++x )
|
||
|
{
|
||
|
beatAvg[x] = 0;
|
||
|
for ( uint y = 1; y < 44; ++y ) beatAvg[x] += m_beatEnergy[x][y];
|
||
|
|
||
|
beatAvg[x] = beatAvg[x] / 43;
|
||
|
}
|
||
|
*/
|
||
|
/* for ( uint x = 0; x < 18; ++x )
|
||
|
{
|
||
|
beatVariance[x] = 0;
|
||
|
for ( uint y = 0; y < 42; ++y ) beatVariance[x] += (pow((m_beatEnergy[x][y] - beatAvg[x]), 2) / 43);
|
||
|
}
|
||
|
|
||
|
for ( uint x = 0; x < 18; ++x )
|
||
|
beatMood[x] = (-0.0025714 * beatVariance[x]) + 1.5142857;
|
||
|
*/
|
||
|
|
||
|
// do we have a beat? let's dance!
|
||
|
/* int total_hits = 0;
|
||
|
for ( uint x = 0; x < 18; ++x )
|
||
|
{
|
||
|
double factor = cos( x * 4 ) * 18;
|
||
|
factor = beatAvg[x] * factor;
|
||
|
|
||
|
if ( m_beatEnergy[x][0] > factor )
|
||
|
{
|
||
|
total_hits++;
|
||
|
kdDebug() << "*CLAP* factor: " << factor << " - x: " << x << " - average energy: " << beatAvg[x] << " - current peak: " << m_beatEnergy[x][0] << endl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( total_hits > 3 ) kdDebug() << "***CLAPCLAPCLAP***" << endl;
|
||
|
*/
|