summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2004-01-20 15:51:03 (UTC)
committer mickeyl <mickeyl>2004-01-20 15:51:03 (UTC)
commit996826e77a8f96ada424814716178e65caba9287 (patch) (side-by-side diff)
tree09c60dcc4437dba1838c086b7eeb5480800716d5
parent557eb6a25f2cfc6e350c1731ead4df0e07861f25 (diff)
downloadopie-996826e77a8f96ada424814716178e65caba9287.zip
opie-996826e77a8f96ada424814716178e65caba9287.tar.gz
opie-996826e77a8f96ada424814716178e65caba9287.tar.bz2
package the guitar sample
fix reading from share/powerchord/
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/powerchord/gs.cpp17
-rw-r--r--noncore/multimedia/powerchord/gs.h1
-rw-r--r--noncore/multimedia/powerchord/opie-powerchord.control8
-rw-r--r--share/powerchord/acguitar.rawbin0 -> 50000 bytes
4 files changed, 15 insertions, 11 deletions
diff --git a/noncore/multimedia/powerchord/gs.cpp b/noncore/multimedia/powerchord/gs.cpp
index a3e85c9..fdcfb74 100644
--- a/noncore/multimedia/powerchord/gs.cpp
+++ b/noncore/multimedia/powerchord/gs.cpp
@@ -1,460 +1,465 @@
//#include <FL/Fl.H>
//#include <FL/Fl_Widget.H>
//#include <FL/fl_draw.H>
#include <stdio.h>
//#include <qpixmap.h>
#include "gs.h"
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
//#include <qpainter.h>
#include <qmessagebox.h>
+#include <qstring.h>
gs::gs()
{
finger[0] = OPEN;
finger[1] = OPEN;
finger[2] = OPEN;
finger[3] = OPEN;
finger[4] = OPEN;
finger[5] = OPEN;
tuning[0] = 0;
tuning[1] = 0;
tuning[2] = 0;
tuning[3] = 0;
tuning[4] = 0;
tuning[5] = 0;
initial_fret = 0;
audio_fd = -1;
pb_rate0 = 0;
pb_rate1 = 0;
pb_rate2 = 0;
pb_rate3 = 0;
pb_rate4 = 0;
pb_rate5 = 0;
pb_rate6 = 0;
pb_oct0 = 0;
pb_oct1 = 0;
pb_oct2 = 0;
pb_oct3 = 0;
pb_oct4 = 0;
pb_oct5 = 0;
pb_oct6 = 0;
// initialise reverb buffer
reverb = (signed short *)malloc(1024 * sizeof(signed short));
for (reverb_ptr=0;reverb_ptr<1024;reverb_ptr++){
reverb[reverb_ptr] = 0;
}
reverb_ptr = 0;
reverb_max = 1024;
- // load sampled 'E' string
+ // load sampled 'E' string
int samplen = 25000;
signed short *dsp_buf = (signed short *)malloc(samplen * sizeof(signed short));
signed short *dsp_buf_ptr = dsp_buf;
int raw_fd;
- raw_fd = open(ACGUITAR_PATH_S, O_RDONLY);
-
+
+ QString path = getenv( "OPIEDIR" );
+ path.append( "/share/powerchord/acguitar.raw" );
+
+ raw_fd = open( (const char*) path, O_RDONLY);
+
if (raw_fd < 0){
fprintf(stderr, "Failed to open raw file (%s)\n", strerror(errno));
exit(-1);
}
int totread = 0;
int i;
-
+
while (totread < samplen*2){
int want = samplen*2 - totread;
int numread = read(raw_fd, dsp_buf_ptr, want);
fprintf(stderr, "read %d bytes\n", numread);
totread += numread;
dsp_buf_ptr += numread/2;
-
+
if (numread == 0){
fprintf(stderr, "failed to read bytes\n");
- exit(-1);
+ exit(-1);
}
}
close(raw_fd);
// scale down a bit for mixing
for (i=0;i<samplen;i++){
dsp_buf[i] /= 6;
}
set_tonebank(0, dsp_buf, samplen);
set_tonebank(1, dsp_buf, samplen);
set_tonebank(2, dsp_buf, samplen);
set_tonebank(3, dsp_buf, samplen);
set_tonebank(4, dsp_buf, samplen);
set_tonebank(5, dsp_buf, samplen);
set_tonebank(6, dsp_buf, samplen);
}
void gs::set_tonebank(int tb, signed short *buf, int length)
{
switch(tb){
case 0:
tonebank0 = buf;
tonebank_length0 = length;
break;
case 1:
tonebank1 = buf;
tonebank_length1 = length;
break;
case 2:
tonebank2 = buf;
tonebank_length2 = length;
break;
case 3:
tonebank3 = buf;
tonebank_length3 = length;
break;
case 4:
tonebank4 = buf;
tonebank_length4 = length;
break;
case 5:
tonebank5 = buf;
tonebank_length5 = length;
break;
case 6:
tonebank6 = buf;
tonebank_length6 = length;
break;
}
}
void gs::Finger(int f, int position){
if (f < 0 || f > 5){
fprintf(stderr, "Error - finger2 value was %d\n", f);
return;
}
finger[f] = position;
}
void gs::Tuning(int t[6]){
for (int i=0;i<6;i++){
tuning[i] = t[i];
}
}
// length in ps (seconds x 10^-9) of the period of a note.
// we use these as ratios in a breshenham-like algorithm to
// scale a deep note to a higher pitch
// They are derived from f(A) = 440Hz and multiply each successive
// semitone by the 12th root of 2 (such that after 12 multiplications for
// 12 semitones you have a note exactly 2x the frequency of the initial one,
// - an octave higher in other words.)
int gs::note_periods[12] = {
90703,
85612,
80802,
76272,
71991,
67950,
64137,
60537,
57139,
53932,
50905,
48048
};
int gs::octave_step[6] = {
1,
2,
4,
8,
16,
32
};
int gs::Play(){
int format;
int channels;
int speed;
frames = 0;
if (audio_fd == -1){
if ( (audio_fd = open("/dev/dsp", O_WRONLY, 0) ) == -1){
audio_fd = -1;
return 1;
}
format = AFMT_S16_NE;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1){
fprintf(stderr, "Error SNDCTL DSP SETFMT, %s\n", strerror(errno));
exit(0);
}
channels = 1;
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1){
fprintf(stderr, "Error SNDCTL DSP CHANNELS, %s\n", strerror(errno));
exit(0);
}
speed = 11025;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed) == -1){
fprintf(stderr, "Error SNDCTL DSP SPEED, %s\n", strerror(errno));
exit(0);
}
// buffering q's
// audio_buf_info info;
// if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1){
// fprintf(stderr, "Error SNDCTL DSP GETOSPACE, %s\n", strerror(errno));
// exit(0);
// }
// fprintf(stderr, "fragments %d\nfragstotal %d\nfragsize %d\nbytes %d\n", info.fragments, info.fragstotal, info.fragsize, info.bytes);
// audio math.
// A4 = 440Hz
// +1 octave = 2x freq
// -1 octave = /2 freq.
// +1 semitone = *= 12 root 2;
// ie. * 1.059463094
// tones, approx Hz, samples at 11025
// A4 440 25
// A#4 466 24
// B4 494 22
// C4 523 21
// C#4 554 20
// D4 587 19
// D#4 622 18
// E4 659 17
// F4 698 16
// F#4 740 15
// G4 784 14
// G#4 831 13
}
else{
fprintf(stderr, "Already playing\n");
}
return 0;
}
void gs::note_start(int chan, int note, int octave)
{
switch (chan){
case 0:
pb_rate0 = note_periods[note];
pb_oct0 = octave_step[octave];
pb_ratio0 = 0;
pb_rsc0 = 0;
break;
case 1:
pb_rate1 = note_periods[note];
pb_oct1 = octave_step[octave];
pb_ratio1 = 0;
pb_rsc1 = 0;
break;
case 2:
pb_rate2 = note_periods[note];
pb_oct2 = octave_step[octave];
pb_ratio2 = 0;
pb_rsc2 = 0;
break;
case 3:
pb_rate3 = note_periods[note];
pb_oct3 = octave_step[octave];
pb_ratio3 = 0;
pb_rsc3 = 0;
break;
case 4:
pb_rate4 = note_periods[note];
pb_oct4 = octave_step[octave];
pb_ratio4 = 0;
pb_rsc4 = 0;
break;
case 5:
pb_rate5 = note_periods[note];
pb_oct5 = octave_step[octave];
pb_ratio5 = 0;
pb_rsc5 = 0;
break;
case 6:
pb_rate6 = note_periods[note];
pb_oct6 = octave_step[octave];
pb_ratio6 = 0;
pb_rsc6 = 0;
break;
default:
fprintf(stderr, "Bad channel\n");
exit(-1);
}
}
void gs::write_buffer(){
int num_read;
num_read = write(audio_fd, (void *)audio_buf, BUFSIZE*2);
// fprintf(stderr, "Wrote %d bytes\n", num_read);
}
void gs::fill_buffer()
{
frames ++;
int i;
for (i=0;i<BUFSIZE;i++){
audio_buf[i] = 0;
if (pb_rate0){
audio_buf[i] += tonebank0[pb_rsc0];
pb_rsc0 += pb_oct0;
pb_ratio0 += 90703;
pb_ratio0 -= pb_rate0;
if (pb_ratio0 >= pb_rate0){
pb_rsc0 += pb_oct0;
pb_ratio0 -= pb_rate0;
}
if (pb_rsc0 >= tonebank_length0) pb_rate0 = 0;
}
if (pb_rate1){
audio_buf[i] += tonebank1[pb_rsc1];
pb_rsc1 += pb_oct1;
pb_ratio1 += 90703;
pb_ratio1 -= pb_rate1;
if (pb_ratio1 >= pb_rate1){
pb_rsc1 += pb_oct1;
pb_ratio1 -= pb_rate1;
}
if (pb_rsc1 >= tonebank_length1) pb_rate1 = 0;
}
if (pb_rate2){
audio_buf[i] += tonebank2[pb_rsc2];
pb_rsc2 += pb_oct2;
pb_ratio2 += 90703;
pb_ratio2 -= pb_rate2;
if (pb_ratio2 >= pb_rate2){
pb_rsc2 += pb_oct2;
pb_ratio2 -= pb_rate2;
}
if (pb_rsc2 >= tonebank_length2) pb_rate2 = 0;
}
if (pb_rate3){
audio_buf[i] += tonebank3[pb_rsc3];
pb_rsc3 += pb_oct3;
pb_ratio3 += 90703;
pb_ratio3 -= pb_rate3;
if (pb_ratio3 >= pb_rate3){
pb_rsc3 += pb_oct3;
pb_ratio3 -= pb_rate3;
}
if (pb_rsc3 >= tonebank_length3) pb_rate3 = 0;
}
if (pb_rate4){
audio_buf[i] += tonebank4[pb_rsc4];
pb_rsc4 += pb_oct4;
pb_ratio4 += 90703;
pb_ratio4 -= pb_rate4;
if (pb_ratio4 >= pb_rate4){
pb_rsc4 += pb_oct4;
pb_ratio4 -= pb_rate4;
}
if (pb_rsc4 >= tonebank_length4) pb_rate4 = 0;
}
if (pb_rate5){
audio_buf[i] += tonebank5[pb_rsc5];
pb_rsc5 += pb_oct5;
pb_ratio5 += 90703;
pb_ratio5 -= pb_rate5;
if (pb_ratio5 >= pb_rate5){
pb_rsc5 += pb_oct5;
pb_ratio5 -= pb_rate5;
}
if (pb_rsc5 >= tonebank_length5) pb_rate5 = 0;
}
if (pb_rate6){
audio_buf[i] += tonebank6[pb_rsc6];
pb_rsc6 += pb_oct6;
pb_ratio6 += 90703;
pb_ratio6 -= pb_rate6;
if (pb_ratio6 >= pb_rate6){
pb_rsc6 += pb_oct6;
pb_ratio6 -= pb_rate6;
}
if (pb_rsc6 >= tonebank_length6) pb_rate6 = 0;
}
// do reverb
signed short rtmp = reverb[reverb_ptr];
reverb[reverb_ptr] /= 2;
reverb[reverb_ptr] += audio_buf[i]/4;
audio_buf[i] += rtmp;
reverb_ptr++;
if (reverb_ptr >= reverb_max) reverb_ptr = 0;
}
}
void gs::Stop(){
if (audio_fd == -1){
fprintf(stderr, "Already stopped\n");
}
else{
//ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
close(audio_fd);
audio_fd = -1;
}
}
gs::~gs()
{}
diff --git a/noncore/multimedia/powerchord/gs.h b/noncore/multimedia/powerchord/gs.h
index 3e4c04d..f2b309f 100644
--- a/noncore/multimedia/powerchord/gs.h
+++ b/noncore/multimedia/powerchord/gs.h
@@ -1,124 +1,123 @@
#ifndef __GS_H
#define __GS_H
#include <qobject.h>
// sound includes
#include <sys/soundcard.h>
#define BUFSIZE 256
#define NUMCHANS 7
-#define ACGUITAR_PATH_S "/usr/local/projects/opie-head/noncore/multimedia/powerchord/acguitar.raw"
class gs : public QObject {
Q_OBJECT
public:
gs();
~gs();
private:
int initial_fret;
int finger[6];
int tuning[6];
signed short *reverb;
int reverb_ptr;
int reverb_max;
int audio_fd;
signed short audio_buf[BUFSIZE];
static int note_periods[12];
static int octave_step[6];
int frames;
// 7 channel synth
signed short *tonebank0; // source of waveform
signed short *tonebank1;
signed short *tonebank2;
signed short *tonebank3;
signed short *tonebank4;
signed short *tonebank5;
signed short *tonebank6;
int tonebank_length0;
int tonebank_length1;
int tonebank_length2;
int tonebank_length3;
int tonebank_length4;
int tonebank_length5;
int tonebank_length6;
int pb_rate0; // playback rate or 0
int pb_rate1;
int pb_rate2;
int pb_rate3;
int pb_rate4;
int pb_rate5;
int pb_rate6;
int pb_ratio0; // accumulator for ratio
int pb_ratio1;
int pb_ratio2;
int pb_ratio3;
int pb_ratio4;
int pb_ratio5;
int pb_ratio6;
int pb_rsc0; // pointer to current position
int pb_rsc1;
int pb_rsc2;
int pb_rsc3;
int pb_rsc4;
int pb_rsc5;
int pb_rsc6;
int pb_oct0; // octave
int pb_oct1;
int pb_oct2;
int pb_oct3;
int pb_oct4;
int pb_oct5;
int pb_oct6;
void set_tonebank(int bank, signed short *buffer, int length);
protected:
public:
static const int MUTED=7;
static const int OPEN=0;
// accessors
int Frames(){return frames;};
int Finger(int finger);
int Fret(){return initial_fret;};
int Playing(){
if (pb_rate0 == 0 &&
pb_rate1 == 0 &&
pb_rate2 == 0 &&
pb_rate3 == 0 &&
pb_rate4 == 0 &&
pb_rate5 == 0 &&
pb_rate6 == 0) return 0;
return 1;
};
public :
// mutators
void Reverb(int size){reverb_max = 64 * size;};
void Finger(int finger, int position);
void Fret(int position){initial_fret = position;};
void Tuning(int t[6]);
void note_start(int chan, int note, int octave);
// methods
int Play();
void fill_buffer();
void write_buffer();
void Stop();
};
#endif
diff --git a/noncore/multimedia/powerchord/opie-powerchord.control b/noncore/multimedia/powerchord/opie-powerchord.control
index 7f45999..d295031 100644
--- a/noncore/multimedia/powerchord/opie-powerchord.control
+++ b/noncore/multimedia/powerchord/opie-powerchord.control
@@ -1,10 +1,10 @@
-Files: bin/powerchord apps/Applications/powerchord.desktop pics/powerchord sounds/powerchord
+Files: bin/powerchord apps/Applications/powerchord.desktop pics/powerchord share/powerchord
Priority: optional
-Section: qpe/applications
+Section: Applications
Maintainer: Camilo Mesias <camilo@mesias.co.uk>
Architecture: arm
-Version: 0.0.7
-Depends: qpe-base ($QPE_VERSION)
+Version: 0.0.8
+Depends: task-opie-minimal
Description: Guitar Chord generator application
Allows naming of chords using base note and key. Fretboard diagrams are
produced illustrating ways to play the chord.
diff --git a/share/powerchord/acguitar.raw b/share/powerchord/acguitar.raw
new file mode 100644
index 0000000..1452147
--- a/dev/null
+++ b/share/powerchord/acguitar.raw
Binary files differ