Jump to content
Why become a member? ×
  • advertisement_alt
  • advertisement_alt
  • advertisement_alt

DIY Looper Project


Annoying Twit
 Share

Recommended Posts

Hi all.

I'm starting a DIY looper. I plan to build it using a USB audio interface connected to a Raspberry PI computer (to provide the computing power).



In theory, that should allow enough memory and processing power for a decent looper, but also allow things such as network connectivity (ethernet) and the ability to connect a keyboard/mouse and monitor (if HDMI). Though, I hope to use footswitches and LEDs to make a 'stompbox' style looper out of it.

The first stage is going to be writing code that actually does the looper. I've started on this, except that I'm programming it on a Mac. I'm being careful to use programming libraries that are available on the Pi, and hence my code should transfer over no problem at all. I'm not creating the interface yet, but have to type in text commands to make it do stuff. I'll later on have to work out how to use footswitches to make it do equivalent things.

Here's what a current session looks like.

[quote]
./rplooper
I am initialising
Cannot connect to server socket err = Connection refused
Cannot connect to server request channel
jack server is not running or cannot be started
RPLooper is running
metro volume 0.7
metro on
timesig 4/4
timesig 1 and a 2 and a 3 and a
beat
division
division
beat
division
division
beat
division
division
recording
Recording is 1
play
store 1
export junk.wav
Now in true exporting mode
No going out of export mode
I am now saving to junk.wav
quit
[/quote]

Tonight I hope to fix up the issue of compensating for audio delay when recording, and also be able to import loops into one of the (currently 16) tracks on the looper. That'll make it a lot more useful than it is now.

My big problem, and the reason I'm starting this thread, is that I don't have a looper myself and haven't used one. Hence I don't know exactly how the 'workflow' works. At present my looper, when recording live, puts it into a buffer. At the end of the loop, it keeps on recording. But, if you leave record mode during that time, it's the previous loop that gets saved to a track. That allows me to play for an entire loop, then have a reasonable amount of time to store the last complete loop.

If I watch Ed Friedland looping as in here, he starts a loop looping back and progresses to the next loop instantly the first is recorded. My method also won't work for long loops as the player will have to wait too long. So, how does that work?

Edit: I thought about how it might work. If I'm recording a loop, I buffer the previous loop (which I'm doing now). I could have it that a single foot button stores the previous loop. Hence if I'm playing and want to change the layer I'm playing, then all I have to do is start playing the next layer when the loop ends, and hit the foot switch while playing so that the previous loop gets stored, and continues playing. If I want to do a retake, then all I do is continue playing while not pressing the button. Is that how they work?

Edited by Annoying Twit
Link to comment
Share on other sites

Interesting project, Ive been thinking of doing something pedal related with my RPI for a while, but have been mainly held off by my lack of programming skills.

So how your working so far is that if you keep on playing after you record a loop your overwrite the loop? Would there be a way to overdub the phrase instead, as this might be more useful.
Also, might be interesting to add a USB midi interface if possible to add either tempo-sync with another pedal, or to add a midi controller to control the looper.

Link to comment
Share on other sites

At the moment haven't decided how it is going to work. I was thinking that it would keep on recording a loop (but not playing it back) until the user presses a button to lock a loop. It will then save the last loop to one track, and then automatically move onto the next track.

E.g. (in case this is not clear), the user might start playing with track 1 selected. If they play through a loop that they like and want to keep, then the press 'the button'. This saves the last (not the currently being played) buffer into track 1, starts playing track 1, and then moves to track 2. The next time the user has something that they want to store, they hit 'the button', and the last loops is stored into track 2, which starts playing. So, at this time you have track 1 playing, track 2 playing, and also whatever live audio is playing. With this, a sufficiently good player would be able to seamless play one track, and start playing the next, while still allowing retakes if they want to. (Which will be what happens if they don't press 'the button' after a loop finishes).

An alternative method would be to have the new loop be automatically recorded when the loop finishes, unless the player hits 'the button' as an 'undo' function. But I think I prefer the 'hit button to lock loop' way of doing things.

Therefore the loops will not wipe each other, but as they're stored separately, it will be possible to mix and modify them separately. With the simplest method of doing this being muting and un-muting of tracks, which I've seen people using quite effectively on Youtube videos.

I've used the PortMIDI library before, and that will make it easy to add MIDI control to it. I want to have a built-in drum machine, at least a very primitive one, and some sort of after the fact mixing ability. Using a MIDI keyboard with knobs that send control codes will be the easiest way of doing that. I own a Korg Nanopad, and thought that I'd maybe use that as the 'buttons' to control the system. But, it's tempting to use a better interface and allow the looper to have MIDI tracks that control outboard gear. Not for version 1.0, but it's very likely that 'the button' being MIDI will happen.

It's still only on my Mac at the moment, but when it's a bit more progressed (no chance this coming week - first week of teaching for me), do you think you'd be able to give it a try?

Edited by Annoying Twit
Link to comment
Share on other sites

This isn't exactly the most active thread around :)

However, I'll just mention that I got a chance to work on this again after a panic week at work. I can now change the tempo and number of bars in the loop. However, currently if I change the length of a loop, it doesn't handle existing audio well. I don't know what to do with it. At present, if the loop becomes longer than it has been before, the audio disappears. Or, if the loop shortens or is lengthened to a length less than the maximum it's been before, it just leaves whatever audio is/was there. I'm thinking that eventually I want to include use of the rubberband time-stretching library to handle tempo changes (in particular) better.

For a while I was wondering how you count BPM if you have an odd time signature, but changed the code so that it actually counts the beats in a bar and then calculates tempo. Importantly, I can now import samples from disk, which gives me the ability to import drum and other loops to play over.

Currently the programme is aggressively mono. If I tried to import a stereo loop, it would do very odd things. And recording is mono only. This has to change. But my main playback/recording function is a bit inefficient, as it does things sample by sample. I need to rewrite that to be more efficient, and it's not sensible to do anything about stereo until that's done.

I must admit that I haven't plugged in a bass yet. As I'm still working on quite basic code, the only loops I've recorded are me clapping in front of the computer's microphone. This will change soon :)

Edit: When I said that the looper is mono only, I meant that it can only record live audio in mono, and import mono loops. However, it's possible to set (and reset) the volume and pan positions of audio after it's been recorded, and output is in stereo.

Edited by Annoying Twit
Link to comment
Share on other sites

  • 1 month later...

Not sure there's much interest in this thread. I had a chance to add some more features to this. It now has advanced, and can actually work as a looper, and has been crudely tested as such.

There is a feature called 'latency' where the player can play ten notes along with the metronome, and it prints out the delay of the played note compared to the metronome. But, I seem to have found that my timing is not as precise as I imagined. At least I can wildly estimate how much the input sound should be shifted forward to compensate for input latency.

I've added features such as storing settings across runs so that when testing (or in the future using it) I don't have to always re-enter parameter values such as metronome and time signature every time I run it. I can also select the sound input/output hardware I want, rather than just always using the default

This software is intended for the Raspberry Pi. But so far I haven't used that, I've been developing and testing it on my mac. In the future I'm going to have to add some sort of interface for the R-Pi 's GPIO pins to connect to buttons and LEDs to make it a 'pedal'. Albeit a pedal that will be ethernet connected and which will have some sort of web-based interface for additional configuration.

The next big step forward will be to handle either mono or stereo input. That would allow me to put effects pedals before the looper. I don't think I can build too many effects into the looper itself. Partially because it will take too long to implement some effects, and partially because the Raspberry Pi won't have too much in the way of processor power to perform the effects. And also I'd like to eventually say the looper is 'usable', so that I can get started on my intended Raspberry Pi bass synth.

Link to comment
Share on other sites

The current interface is me typing commands from a keyboard. But, the text commands are orientated towards an eventual interface with pushbuttons, LEDs, and a pedal. E.g. there's one called 'button' :) which saves the current loop in the current track, and moves onto the next track, so that layers can be built up easily.

Not having used existing pedals, I'm not sure what is and isn't done. But, assuming that I have multiple footswitches (say 4 or 8), then I think I need to introduce a concept of different mixes which can be set up, and accessed at the push of a button. E.g. I'm assuming that the thing will have modes, and in 'play mode', the push buttons will call up different mixes instantly. Assuming that this includes muting of tracks, then it would be possible, in real time, to build up sections of a song (e.g. AABA structure), and then easily and quickly navigate between them when playing.

I've seen that there's a LED display with keypad for the R-Pi. http://proto-pic.co.uk/adafruit-blue-and-white-16x2-lcd-keypad-kit-for-raspberry-pi/?gclid=CJ2E14r91LoCFfHKtAodISgA3A This seems reasonably priced and would give a lot of I/O capability, in [b]theory[/b] rivalling current top-end loopers.

BTW: I'm planning that MIDI control will be possible in the future, such that external MIDI keyboards with knobs can be used to control the looper. I must look into the portmidi library. (I'm using portaudio for audio I/O at the moment). MIDI control would also allow me, e.g. to have inbuilt drum sounds. In the long term, I'd like to have some compatibility with the Hydrogen open source drum machine, being able to read its drumkits, patterns, and songs.

Sorry if I'm waffling on too much.

Link to comment
Share on other sites

  • 2 weeks later...

Time for this is short, but it now handles stereo input or mono input. And, it can import mono or stereo samples into individual tracks. One thing I forgot was to have any way of capturing live performances. So, I've added that. A stream to disk can be opened, and then anything playing (unfortunately including the metronome :( - harder to fix than it sounds) is streamed to a .wav file, for ... whatever purpose.

The main problem is that saving loops doesn't work. There's a really nasty bug in there somewhere that I can't fix, and the file saved which should contain all of the loop is corrupted. I think I'm going to end up writing that function again from scratch. I can see the data being corrupted, but for the life of me can't see what's causing it.

This 'thing' however has been used for a lot of looping today. Problem it, it's exposed how clumsy my timing is when playing. Got to work on that. But I've just had fun building a major key solo around 'twinkle twinkle little star' :)

Edited by Annoying Twit
Link to comment
Share on other sites

Very interesting!

Just on the subject of a controller... I was going to make one for a video project by assigning different keys on a keyboard to different functions, and then dismantling a USB keyboard and replacing the buttons with foot switches in a box. I thought that might be a simple way for you to go

Link to comment
Share on other sites

I've wanted to have a go using the GPIO pins on the Pi for a long while now, so this will be my excuse.

Once I work out which MIDI library to use (portMidi seems to have problems according to some people but alsamidi won't run on my mac forcing all development to be on the Pi), then I hope to use a 'learn' function such that MIDI controls can be used instead of buttons. That would allow me to use my Korg micropad (or whatever it's called - drum pad thing) as a controller.

Link to comment
Share on other sites

  • 2 weeks later...

Major problem with this. Now I find that when I start trying to add some functionality, I end up just making loops and playing with the software rather than hard core coding. I've added a tuner to the looper, though it's a bit flakey at present. I haven't put anything in to reduce octave jump tracking errors, but as a tuner it does work if I ignore them. I'm hoping to create a bass synth in the future, and tracking will be 99% of the work for that, the actual synthesis will be easy. I've also solved, I believe, a nasty bug where the looper would crash when I loaded a saved loop. Turned out that I forgot that the audio processing was in parallel with the loading, and it was trying to play back a partially loaded loop => crashville.

I've started creating a 'button' interface, which is to allow me to experiment with different interfaces before I add the real buttons. I'm aiming at an interface that will allow me to recording different sections of a song in real time. The looper now can store different mix setups, including muting of tracks. The 'button' interface allows quick switching between multiple 'modes'. In 'mixgroup' mode, nine (currently, not sure how many physical buttons the real things will have) mixgroups can be quickly accessed through buttons. A mixgroup is a set of track mutes, volumes, pan settings. This will allow the player to be very flexible in creating parts of songs with different chord progressions and switch between them.

I'm designing an 'autorecord' mode where a player will be able to record different sections of a tune by playing them through, switching sections every time a loop is stored, and going back to the first section again. E.g. say a piece of music has three sections, A, B, C. The user would record one track for part A, and on storing it, will move automatically to part B, playing seamlessly through the change if they can play well enough. Then onto C, then back to the second track for part A, and so on. Once all backing loops are recorded, the user can switch modes to another mode where they can switch back and forth between these sections at will, meaning that there can be extended pieces of music with different chord progressions. It looks complicated when I write this here, but I think this will be simpler to implement and use than it sounds. As it will rely on mixgroups (sets of mutes, volumes, pans for tracks that can be easily switched).

Hence, the way I hope it will work, a user might be able to do this.

LOAD PREPARED LOOP WITH TWO DRUM LOOPS - Play bass line for verse (over verse drums) - STORE - play bass line for chorus (over chorus drums) - STORE - play chords for verse (over verse bass and drums) - STORE - play chords for chorus (over chorus drums and bass) - STORE - MIXGROUP MODE - SELECT VERSE - solo as they please (over verse bass, chords, and drums) - SELECT CHORUS - solo as they please (over chorus bass, drums, and chords) - SELECT VERSE - solo as they please ... (and so on).

Edited by Annoying Twit
Link to comment
Share on other sites

  • 2 weeks later...

Responding to this thread http://basschat.co.uk/topic/223624-raspberry-pi-usb-audio/

TBH, I haven't run my looper on my Pi yet. I must try it out. I'm using a Rocksmith cable as a USB interface, and that should work. I will give it a try when I can. Currently it runs on my mac, but only uses libraries that should work on the Pi.

Progress on the looper slowed down a lot when it go to the stage where it is usable, and I get tempted to play with it rather than work on it. I've added things. E.g. it's supposed to run from 10 footswitches and a LED display, but that doesn't exist yet. I was concerned that it was gaining too many commands, so I added a 'preset mode'. In this mode (modes switched through the footswitches) I can create up to 9 'macros' of commands, assigning one to each of 9 footswitches. Hence it would be possible to come up with command sequences that could be used while playing live.

While I tested that it worked some time ago, I've only just recorded my first loop that includes a reversed recording. IMHO it sounds pretty interesting, though clearly playing backwards bass is going to require some practice. (It's playing in my headphones as I type) I would have thought even a backwards drum pattern would have given more guidance than it did. There might be better ways to create backwards parts than what I did this time, e.g. using the metronome, I'll try again.

Link to comment
Share on other sites

Arrggh!!! I've finally installed the program on the Raspberry Pi, and I can't get it to work. When I try and open audio input and output, portaudio (audio i/o library) fails, and I have no idea why. Posting on forums and doing experiments to try and find out why.

Also, I've discovered that there is a new release of the Raspberry Pi which has double the memory. This would mean probably triple the memory available to my program. It's pretty obvious that for a looper, it will be too much of an advantage to have 3x the memory to not upgrade.

Link to comment
Share on other sites

Interesting project!

Have you posted your code anywhere ([url="http://github.com"]github[/url]?) - I imagine there are a few of us around who are into programming and open source who may be able to contribute help to getting this working, or at least would be interested in taking a look at the code. :)

Link to comment
Share on other sites

I was hoping to get it into better shape before open sourcing it.

Today was a bit of a downer given that I couldn't get it working on the Pi. I strongly suspect that this is because PortAudio is broken on the Pi. jackd is broken too, but there is a known workaround. I wrote a very hacky test program to open and close PortAudio devices, and it won't work on the Pi. I thought it might have been that I was using a Rocksmith game USB cable and the Pi's audio output. But, I went and borrowed an M-Audio Fasttrack Pro audio interface, and that didn't work at all. Using alsa command line tools for the Rocksmith cable and the Pi's audio output worked fine, so I think it's just portaudio that's broken

Hence, the next thing I'm going to try is to extract the PortAudio code from the current application into a separate module. Then, I can replace that module on different operating systems, e.g. use a module written to use ALSA for the Pi. That may be a workaround which would then still allow me to develop on the Mac, generally much quicker than the Pi.

Here's my very horribly formatted and written command line test program which uses PortAudio to copy the input to the output. It first uses the default audio devices, then allows the user to type in some device numbers to try hardware other than the default. If anyone else has a Pi and various audio hardware, it would be useful if they could give this a try. I'm not adverse to sharing the looper code, but just want to get it into better shape first.

This is compiled with the command: gcc -o testpa testpa.c -lportaudio

[quote]
#include <stdio.h>
#include <portaudio.h>
#include <stdlib.h>
#include <strings.h>

#define SAMPLE_RATE 44100

static int rooperCallback(
const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );

typedef struct
{
double value;

} paData;

paData data;

void devices();
void openNamed();

PaStream *stream;

main( int argc, char *argv[] )
{
char temp[1024];
PaError err = Pa_Initialize();

printf( "Initialising portaudio, error %d\n", err );

if ( err != paNoError )
{
fprintf( stderr, "Unable to initialise portaudio\n" );
exit( -1 );
}

data.value = 1;

err = Pa_OpenDefaultStream( &stream, 1, 2, paFloat32, SAMPLE_RATE,
256,
rooperCallback,
&data );

printf( "Opening portaudio, error %d\n", err );

if ( err != paNoError )
{
fprintf( stderr, "Unable to open default stream\n" );
exit( -1 );
}

err = Pa_StartStream( stream );

printf( "starting stream, error %d\n", err );

if ( err != paNoError )
{
fprintf( stderr, "Unable to start default stream\n" );
exit( -1 );
}

printf( "hit <return> to continue\n" );
fgets( temp, 1024, stdin );

Pa_StopStream( stream );

devices();
openNamed();

printf( "Hit <return> to continue\n" );
fgets( temp, 1024, stdin );

Pa_StopStream( stream );
}

static int rooperCallback(
const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
/* Cast data passed through stream to our structure. */
paData *data = (paData*)userData;
float *out = (float*)outputBuffer;
float *in = (float*)inputBuffer;
int i;

for ( i = 0; i < framesPerBuffer; i++ )
{
out[2*i] = in[i];
out[2*i+1] = in[i];
}
}

const PaDeviceInfo *deviceInfo;

void devices()
{
int numDevices = Pa_GetDeviceCount();
int index;

printf( "The number of devices is %d\n", numDevices );

for ( index = 0; index < numDevices; index++ )
{
deviceInfo = Pa_GetDeviceInfo( index );

printf( "[%d] %s #in=%d #out=%d\n",
index, deviceInfo->name,
deviceInfo->maxInputChannels,
deviceInfo->maxOutputChannels );
}
}

void openNamed()
{
int fromD;
int toD = 0;
PaError err;
char temp[1024];

PaStreamParameters inputParameters;
PaStreamParameters outputParameters;

printf( "Type in device numbers for input and output hittng <return> after each one.\n" );

printf( "input: " );
fgets( temp, 1024, stdin );
fromD = atoi( temp );
printf( "output: " );
fgets( temp, 1024, stdin );
toD = atoi( temp );

printf( "input: %d, output: %d\n", fromD, toD );

bzero( &inputParameters, sizeof( inputParameters ) );
inputParameters.channelCount = 1;

inputParameters.device = fromD; // Rocksmith cable
inputParameters.hostApiSpecificStreamInfo = NULL;
inputParameters.sampleFormat = paFloat32;
inputParameters.suggestedLatency = Pa_GetDeviceInfo(fromD)->defaultLowInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;

bzero( &outputParameters, sizeof( outputParameters ) );

outputParameters.channelCount = 2;
outputParameters.device = toD; // hardware output
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = Pa_GetDeviceInfo(toD)->defaultLowOutputLatency ;
outputParameters.hostApiSpecificStreamInfo = NULL;

err = Pa_IsFormatSupported( &inputParameters, &outputParameters, SAMPLE_RATE );

if( err == paFormatIsSupported )
{
printf( "Hooray!\n");
}
else
{
printf("Too Bad.\n");
return;
}

err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
256,
paNoFlag,
rooperCallback,
(void *)&data );

if ( err != paNoError )
{
printf( "Unable to open portAudio stream\n" );
}
else
{
printf( "The stream is now opened\n" );
}

err = Pa_StartStream( stream );

if ( err != paNoError )
{
printf( "Unable to start portAudio stream\n" );
}
else
{
printf( "The stream is now running\n" );
}
}

[/quote]

It works fine on my mac, with all sorts of audio hardware. But, it won't work on the Pi with any audio hardware. I tried opening streams reading data as integers instead of floats - that made no difference. This is such a simple program that I would expect it to work if PortAudio was working. It doesn't :(

Edit: Quoting loses the formatting for this program. Anyone who wants the original code can PM me an email address.

Edit2: It appears that rewriting the application as a jack client is a better solution, as that should work on the Pi, but also work on the Mac, preventing me have to have different audio code for Mac OS and Linux.

Edited by Annoying Twit
Link to comment
Share on other sites

  • 4 weeks later...

Just wanted to mention that this project is still alive. I've had a gap while I think about PortAudio not working on the Pi. I'm going to convert to JACK, but it's waiting until I get enough time.

In the meantime, I've decided that it will not have its 'own' hardware interface, but will be controlled by a (in theory any) external MIDI controller. I've purchased an Arduino MEGA board, ten effect box foot switches, an I2C LCD display, and some other bits and bobs ready to make the MIDI controller. I need some more wires and stuff, which I'm pickng up bit by bit from ebay. I think I've worked out where I'm going to get an aluminium box from, and how I'm going to drill all the necessary holes in it etc. I'm planning to have a low profile aluminium top screwed to a wooden base, with rubber feet. That will then connect through MIDI to the PI. But, I plan that the foot controller will be general enough to do other things as well.

The looper still works on the mac, so I can develop and test MIDI control on that. After I've got some MIDI control, it's time to rewrite the looper to use JACK interface for audio.

Link to comment
Share on other sites

  • 3 weeks later...

Slow progress on this one, but I now have enough bits together to build the MIDI foot controller. I have some 5in x 2in aluminum box section at work which I will mount all of this in to make the physical foot controller.

I seem to be dreadful at taking photos of things inside at night, but I think this blurry photo gives an accurate impression of where I'm up to :)

Those with eagle eyes will notice I'm using an Arduino nano soldered to veroboard instead of the Arduino mega board I bought at first. I figured out that wiring so many things together without using veroboard was going to be a pain in the posterior. I'm not yet decided what the knobs will do, but it cost about two quid or something to buy them, and I thought it would be silly not to add some. I'll work out what they do when I write the code to make it all work. The arduino mega will not go to waste, I've ordered some various sensors such as a gyroscope sensor, waterproof temperature sensor, etc. Using the arduino has been find and I want to try some things like building my own Christmas lights.

The foot switches cost more than all the other electrical components put together. But, they feel good quality, so I suspect that may be money well spent if I'm going to be stomping on them regularly.

It's not visible in the photo, but the LCD in this photo was displaying: "Counter: <some large number>" which was a trial program I wrote just to check that I could communicate with the LCD. The next stage will be to solder the knobs and the switches to the board, and write a sample program to detect movements/presses of these and display on the LCD what is happening. Then to add the MIDI output. After that, code so that this 'thing' can be configured to send any MIDI streams when any switch is pressed or released, which will then actually make it a useful MIDI controller. As well as controlling my looper, I hope to be able to trigger drum sounds from the footswitches, and also use it as a bass pedal (sort of like some of the zoom footpedals) so that I can play notes or chords with my feet, and solo over the top.

Edited by Annoying Twit
Link to comment
Share on other sites

A lot more soldering done. Knobs and two footswitches (ran out of wire) work, and currently as a test I've set it up so that the two footswitches send C major and G major chords over MIDI, note on when pressed, note offs when released. This all works. I need to get some more wire, and connect the other eight footswitches. Next I have to look into connecting and testing (again) the LCD. After that, it'll be software development only, which will be easy.

Link to comment
Share on other sites

  • 3 months later...

Progress on this has been slow recently. I've obtained a square aluminium box which I'm going to use to build the foot interface but it's sitting in the machine shop at work waiting for them to have time to drill holes etc.

However, I brought my mac and enough wires to make it work to the bass bash yesterday, and I was very pleased that a number of people had a go on it. (Thanks!)

Some usability issues were found. So, this morning I addressed these.

I hadn't mentioned it here, but I'd changed the metro to allow flexible time signatures, e.g. specified by text such as "1 and 2 and 3 po let 4 and" for a 4/4 time signature with a triplet division on the three. I recorded spoken word samples for the numbers to get an audible metronome from that, but possibly due to the performance of those not being punchy enough and editing of the samples being harder than I expected, it doesn't really work. I'm going to have to look into what to do about that.

Using it yesterday, it was quite difficult to spot where the loop started, in the slightly noisy environment of a bass bash. This led to me putting my head next to the amp, and then when I worked it out counting off bar numbers (e.g. if the loop is a four bar loop). I've added the ability to specify a sample which is played at the start of each loop. For testing I've been using a crash cymbal. This means that if I import a one bar drum loop, but repeat it four times to get a four bar loop, by adding (e.g.) the crash, it's easy to tell where the loop starts and ends.

Yesterday we were streaming out performances. This feature streams the live audio output from the looper (including live playing - e.g. soloing) to disk. Unfortunately, it was previously quite difficult to set the levels of tracks and live input so that the recording would have a sensible overall level without clipping. I've added a parameter so that the level of the streaming audio can be offset from the live output from the looper. E.g. setting this to 0.5 would mean that the streaming audio is half (in absolute terms, not dB) of the live audio. I've also added the ability to automatically calibrate this to a target amount of headroom. I issue a "calibrate stream" command, play for a bit over the current loop, issue another "calibrate stream" command, and the volume offset for the stream is then calculated based on the audio between the two commands so that it would achieve the target amount of headroom.

Finally a seemingly minor but practically important changed. there is now a "used" command which tells me what tracks currently have audio on. This helps me avoid forgetting which tracks the drum loops are on, and accidentally wiping the drums by storing other audio into the same track.

I feel that after these detail changes, I want to add something to it that really significantly improves what it can do. It might be interesting to upgrade the import of (usually) drum loops. Currently I can import drum loops, multiplying them up. E.g.

"import verse.wav 1 4"

means that verse.wav has one bar (so that the looper can work out the tempo), and is multiplied four times. It would be much more flexible if I could import multiple files, e.g.

"import verse.wav 1 2 chorus.wav 1 2"

to get two bars of one drum pattern, and two bars of another, which then form the basis of the loop.

The other thing I'm thinking of is tempo maps, so that I can have variable tempo. This can be achieved with multiple samples as above, as they may not be at the same tempo. But, this wouldn't then match up with the constant tempo metronome. I'd like to be able to specify a tempo map, for use in loops where there aren't any imported external samples. However, I'm not sure if tempo maps would really be used in looping applications. When Ed Friedman used a looper for his version of Steely Dan's "Do it again" he had a long enough loop to have both verse and chorus, and it would be plausible to speed up the tempo for the chorus. But it wouldn't really happen for short four bar loops.

Link to comment
Share on other sites

Just added functionality to be able to append (usually drum) wav loops read from disk, as well as import them. This is so that I can build up a backing track for a longer loop from smaller (e.g. one bar) drum loops from disk. The import command reset the length (and tempo) of the loop to be based on the wav file read in. The 'append' command adds the new wav file onto the end of the loop. At present, the tempo and number of bars may not quite be in sync with the drums - that's a debugging session in itself. And I can't append a stereo file on the end of a mono file, or vice versa - that requires some more coding. But, if the metro is turned off, the append works. Which is something, and makes the looper more flexible, musically.

Link to comment
Share on other sites

[quote name='Annoying Twit' timestamp='1383901815' post='2270483']
Not sure there's much interest in this thread.
[/quote][i]Au contraire[/i], my friend. It's fascinating, even if my poor analogue brain only understands about one word in three. :lol: 'lack of replies' doesn't mean 'lack of interest'..!

Edited by UglyDog
Link to comment
Share on other sites

Thanks. I was encouraged by actually having other people using it at the bass bass on Saturday.

Just putting in the code so that I can append a stereo sample onto the end of a mono sample and vice versa.

Edit: It now has a server built in so that it can be controlled from a browser. The idea is that eventually it will run on the Raspberry Pi, and any computer/tablet/phone/etc. on the same network can access the looper using a browser. At present, raw commands are entered through the interface, but it's intended that eventually there will be a more fancy browser interface with menus etc.

Edited by Annoying Twit
Link to comment
Share on other sites

As well as making it do the basic looper stuff, I really want to add some fancy stuff to this looper.

I've now seen this demonstration of infinite verb:

https://www.youtube.com/watch?v=Qv9QWoHCFhQ

And oh yes, do I want to add some sort of infinite reverb to my looper. I hope that modifying freeverb or another reverb methodology (I've forgotten the name) to make an infinite 'verb will sound like that. The sounds here sound not just verby, but chorused. That might be a natural result of the delays used to create the reverb. Otherwise, it's easy to write chorus effects in software.

Though, I hope I don't have to write a full real time convolution reverb to make this work, as that's very far from easy.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...