Saving and sequencing own synth sounds?

hi everyone I hope your all well thanks for your help so far :slight_smile:

I have a couple of questions about saving and sequencing your own sounds below is some code I made, its a basic riff using the sonic pi internal sounds:

live_loop :fun do
  use_bpm 140
  use_synth :square
  riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)
  play riff.tick
  sleep 0.5
end 

how would I write a riff like this with a sound that I make?

my next question is is it possible to save the sounds I make and recall them for later use not only if sonic pi is open but also if I close and reopen it? 

thanks for all your help everyone :)

Not quite certain of your question, but if you mean how can you play a riff with a sample rather than a synth here is how:

I used the built in sample "ambi_glass_rub, but you could use an external one too.

First find the sample pitch, then sound it using the ;rpitch (reoative ptich) option.

#first find pitch of sampler by trial and error
sample :ambi_glass_rub,sustain: 0.5
sleep 0.5
use_synth :square
play :fs5 # is is sample natural pitch
sleep 1
#you can remove the lines above when you know the pitch

live_loop :fun2 do #playing with a sample
  use_bpm 140
  riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)
  tick
  sample :ambi_glass_rub,rpitch: note(riff.look) - note(:fs5),sustain: 0,release: 0.5 if riff.look !=:r 
#sample only played if riff.look is not a rest 
  sleep 0.5
end

Alternatively, you can play the riff using a midi command and play externally generated sounds using a midi synth.

The simplest way to do that is to save the sounds in a file and open that file when you need it. If you want to get fancy about it, you can define the riff as a function which you call in another buffer. If you want to be able to change the pitch of the riff, you could make a function like this:

# pitch:0  and sleeps:0.5  means we have default values, if none is supplied
define :riff do |pitch: 0, sleeps: 0.5|
  use_bpm 140
  use_synth :square
  riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)
  riff.count.times do
    play riff.tick + pitch
    sleep sleeps
  end
end

live_loop :riffExample do
  # play at default pitch
  riff
  
  # play at one note lower
  # functions work with parentheses too, if you find that more readable
  riff(pitch: -1)
  
  # play at one octave higher, twice as fast
  riff pitch: 12, sleeps: 0.25
end

      
      # play at one octave higher, twice as fast
      riff pitch: 12, sleeps: 0.25
    end

Put all the function definitions (the define blocks) in a separate file, load it, and run it. You can then use the functions from any other buffer in your live_loops or compositions. There might be a way to import them without loading the file into a buffer which I’m not aware of.

Hi,

Well i understand your question as this : how to play my riff with my own synth parameters ? right ?
So you just need to use use_synth_defaults and put your parameters.
or you have to use something like that

define :mySynth do |n|
  
  s=:piano
  use_synth_defaults attack:0, delay: 0.5, amp:1
  use_merged_synth_defaults
  synth s,note: note(n)
end



live_loop :fun do
  use_bpm 140
  riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)
  mySynth(riff.tick)
  sleep 0.5
end

Does it help ?

We can go in many directions with this system

By the way, you 'd better put use_bpm outside live_loop.

define :mySynth_01 do |n|
  s=:sine
  use_synth_defaults attack: 0,
    delay: 0, amp:1
  use_merged_synth_defaults
  use_octave -2
  with_fx :echo, mix: 0.2 do
    synth s,note: note(n)
    synth :piano,note: note(n) + 12, pan: -1, release: 0.5
    synth :pluck, note: note(n) + 24, pan: 1, sustain: 1.2
  end
end

define :myBells do |n|
  
  with_fx :echo, mix: 0.2 do
    synth :pretty_bell,note: note(n), release: 0.8
  end
end

use_bpm 140

live_loop :fun do
  riff = (ring :e, :e, :g, :r, :f, :e, :e, :e, :e, :g, :r)
  mySynth_01(riff.tick)
  sleep 0.5
end

live_loop :fun_02 do
  
  riff_02 = (ring :e, :e, :g, :r)
  myBells(riff_02.tick)
  sleep 2
end

thanks for all your help gang :slight_smile: so how would I make a sound with 2 wave forms using use_synth_defaults?
would I put the 2 wave forms first then put the rest of things like attack release and such? thanks for all your help everyone p.s. when making my sound do I need to set it to have a note for example play 70 before I rite the riff? thanks everyone :slight_smile:

Hi @soundwarrior,

what do you mean by “2 wave forms”.

Just to be clear, there are two main ways. of generating sound in Sonic Pi:

  1. Using the built in software synths (triggered by calls to play or synth). You can easily combine simple wave forms using this approach to do basic additive synthesis - and then pass them through FX to do subtractive synthesis. Synths in this case all typically have a note: opt for choosing the pitch.
  2. Using the built-in sampler to play pre-recorded sounds (which you can also manipulate using the many opts and also pass through FX). Samples do not have a note: opt as they may or may not be pitched. However, you can stretch or shrink samples using rate: which will change the pitch. You can do this in a melodic way using rpitch: which will figure out the correct rate modification to shift the pitch up and down by the specified number of semitones.

Which of these approaches were you looking to do - or was it something else?

hi thanks for your help everyone, so I want to make a sound with 2 detuned squares witch I’ve done I’ve also rapped that sound in a function, how do I make a riff using the function I’ve made? the sound I made has notes in it for detuning will the presents of these notes in my sound effect the composition of the riff in any way? thanks again everyone :slight_smile:

The built-in tutorial has a section on additive synthesis, which you will want to look at for making a sound out of two detuned square waves. As for how to make a riff, you already have it in the functions above which takes notes. If you want to auto-generate a riff that repeats, take a look at the section on randomization in the tutorial.

If you want to access your synth in the same way you access the built-in synths, you’re going to have to make your own synthesizers in Supercollider and compile them to work with Sonic Pi. This is by no means a trivial thing.

I think you have all the ingredients you need for making the stuff you want to make, honestly. Now comes the fun part, practice :slight_smile:

Hi every one, thanks for your help so far :

So this is the sound I want to use for the riff hears the code:

“””

detune = 0.7

synth :square, note: :e3

synth :square, note: :e3 + detune

I’ve rapped it in this function:

Define : grime do

detune = 0.7

synth :square, note: :e3

synth :square, note: :e3 + detune

End

I want to use the sound I’ve just mentioned to play this riff: riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)

How would I do this? Thanks very much all, and thanks for your patience :slight_smile: p.s. i’ve never coded in my life and I come from a hardware background.

This should do it

define :grime do |n|
  detune = 0.7
  synth :square, note: n
  synth :square, note: n + detune
end

live_loop :playriff do
  riff = (ring :e, :r, :g, :r, :f, :e, :r, :r, :e, :r, :r)
  grime riff.tick
  sleep 0.5
end
1 Like

Hi @soundwarrior,

just to embellish on @robin.newman’s excellent answer, the key is to parameterise the function.

Essentially you want to see a function as a unit of behaviour that you can tweak. In this case your function describes the synths you want to trigger, the note and the detune value. These values are all “hard coded” into your function, so you can’t change them. Robin’s example parameterises the note. This essentially means that your function just talks about note n which could be any note. This note is then passed into the function when it is called as a parameter.

Take a look at Section 5.5 of the tutorial for a bit more background on this: http://sonic-pi.net/tutorial.html#section-5-5

Hope this helps!

1 Like

thanks everyone I was able to make a synth ref with the code Robbin provided now how can I do that with chords? thanks gang :slight_smile:

You just pass it a chord instead of a single not. The same function will work with a list of notes, since synth :square, note: n will take lists of notes (which is what a chord actually is) as well as single notes. When you’re using your function, you’re passing giving it the notes you want it to play, which the function then gives your synth functions. If you want an example (which is going to sound a bit funny), try passing it the entire riff instead of one note at a time by writing grime riff

As a more general thing in terms of getting better, just try things out. If it doesn’t work, it either sounds funny or gives you an error. Adjust your code a bit, and try again. :grinning:

hi everyone thanks for your help so far :slight_smile: so this is the code I typed to make a chord riff:
“”"
live_loop :chord do
use_bpm 140
riff = (ring :chord(:c4,:minor) , :r , :chord(:c4,:minor) , :r , : , :r).tick
end
sleep 1
end

but it doesn’t work please can someone tell me why this is and provide me with a small example of correct code? thanks very much all :slight_smile:

Hi @soundwarrior, I can see a few issues that need fixing:

  • the chord function should not have a colon at the beginning
  • there’s a single colon in the ring near the end, is it supposed to be another chord?
  • you don’t call play or synth (or the grime function from before) so it won’t make any sound

Try this:

define :grime do |n|
  detune = 0.7
  synth :square, note: n
  synth :square, note: n + detune
end

live_loop :playriff do
  use_bpm 140
  riff = (ring chord(:c4,:minor) , :r , chord(:c4,:minor) , :r , chord(:c4,:minor) , :r).tick
  grime riff
  sleep 0.5
end

Now I’m getting confused… so I went this way…

use_bpm 140
use_synth :sine


riff = (ring chord(:e4,:minor) , :r , chord(:c4,:minor) , :r , chord(:b3,:minor) , :r)

define :grime do |n|
  
  # To play chords you need to use 'notes:' not 'note:'
  # but I dont think 'notes:' allows :r as a rest...
  
  if n == :r then
    sleep 1
  else
    detune = 0.7
    synth :sine, notes: n
    synth :sine, notes: n + detune
  end
end

live_loop :playriff do
  grime riff.tick
  sleep 0.5
end

Eli…

hi guys thanks for all your help :slight_smile:

1 Like

Playing a little

acordes = (ring chord(:e3,:minor), chord(:g3,:major), chord(:c3,:major), chord(:d3,:major))
silencios = (ring 1,1,0.5,1)

define :detu do
  
  detun = (ring 0.2,0.4).choose
  use_synth q= (ring :square,:tb303).choose
  
  if q == :square
    play acordes.tick
    play acordes.look + detun
    sleep silencios.look
  else
    play acordes.tick,cutoff: 80,pan: 1
    play acordes.look + detun,cutoff: 80,pan: -1
    sleep silencios.look
  end
end


live_loop :gf do
  with_fx :reverb do
    detu
  end
end

@Eli according to my experiments (and verified by looking at the source code) note: and notes: behave the same, either can accept a single note, a chord, or a rest.