3

The result of the algorithm, described below, is here


I have an array of notes: { 60, 63, 67, 70, 73, 77, 73, 70, 67, 63 } and a NOTE_LENGTH variable

I start with sending the first to a MidiOutput device with a standard MIDI tenor saxophone.

When the last note is played for 2/3 of NOTE_LENGTH milliseconds, I send the next one. When a note is played for NOTE_LENGTH, I stop it.

Notes are started with Midi NoteOn and stopped wit Midi NoteOff


It's easy to find where a note starts in the resulting audio. It is not smooth, while a real saxophone is. How do I achieve a smooth transition like in this video? I'm not a musician, so I don't know, what a technical difference is.


UPDATE

Source code, C# + NAudio.dll 1.3.8.0 (Note, that it may not work in later versions of dll)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NAudio.Midi;

namespace Sax
{
    class Program
    {
        static void Main(string[] args)
        {
            MidiOut midi_out = new MidiOut(0);
            midi_out.Volume = 65535;
            midi_out.Send(MidiMessage.ChangePatch(67, 0).RawData);
            midi_out.Send(MidiMessage.ChangePatch(67, 1).RawData);
            int iteration = 0;
            int[] notes = new int[] { 60, 63, 67, 70, 73, 77, 73, 70, 67, 63 };
            //int[] notes = new int[] { 60, 61, 62, 63, 64, 65, 64, 63, 62, 61 };
            const int NOTE_LENGTH = 729;
            while (true)
            {
                midi_out.Send(MidiMessage.StartNote(notes[iteration % notes.Length], 127, iteration % 2).RawData);
                Thread.Sleep(1 * NOTE_LENGTH / 3);
                if (iteration != 0)
                    midi_out.Send(MidiMessage.StopNote(notes[(iteration - 1) % notes.Length], 127, (iteration - 1) % 2).RawData);
                Thread.Sleep(1 * NOTE_LENGTH / 3);
                midi_out.Send(MidiMessage.StartNote(notes[(iteration + 1) % notes.Length], 127, (iteration + 1) % 2).RawData);
                Thread.Sleep(NOTE_LENGTH / 3);
                midi_out.Send(MidiMessage.StopNote(notes[iteration % notes.Length], 127, iteration % 2).RawData);
                Thread.Sleep(NOTE_LENGTH/3);
                ++iteration;
            }
        }
    }
}
AStopher
  • 4,207
  • 11
  • 50
  • 75
user2136963
  • 2,526
  • 3
  • 22
  • 41
  • Might be better suited to [Computer Science Stack Exchange](http://cs.stackexchange.com/). – AStopher Sep 13 '15 at 10:34
  • Added the source code – user2136963 Sep 13 '15 at 11:25
  • 1
    @user2136963 You simulate a smooth transition using a *descrescendo* that you write yourself, instead of relying on a single "midi note". – amirouche Sep 13 '15 at 11:47
  • So, you basically say, that I should play first note more and more quietly while playing next note more and more loudly? – user2136963 Sep 13 '15 at 11:54
  • You should also tag the *language* you're using, which I believe to be C#. – AStopher Sep 13 '15 at 12:01
  • The problem is to find protocol, or feature of protocol, which enables to play smooth sound. I don't want to limit it to C# – user2136963 Sep 13 '15 at 12:05
  • Doesn't matter, if your question is to do with a language (being Stack Overflow, it should be), it needs to be tagged with the language. If you don't care about the language so much, you should say so in the question as many of us here are experienced with other languages (for example, I'm more of a VB.NET guy, but I've answered C# questions before with no problem). – AStopher Sep 13 '15 at 12:54
  • 1
    The are MIDI synthesizers that support legato for certain instruments (e.g., Roland SC-88Pro and its successors). But if you don't have one, you have to try to emulate it with pitch bend or portamento controllers. – CL. Sep 13 '15 at 13:32

1 Answers1

2

Use a midi pitch bend. See this SO answer for directions to some examples.

To the get the correct effect you'll probably need to do a quick pitch bend just before the end of the first note, with the bend ending at the second note pitch exactly as the second note is due to start.

You might also want to look in to interpolation of the bend to get the most realistic sound possible, i.e. rather than a liner pitch bend you might get better results with a slow-in-fast-out type interpolation (or vice-versa). I'm not sure if NAudio will support interpolation or if you'll have to implement this yourself.

Community
  • 1
  • 1
gingerbreadboy
  • 7,386
  • 5
  • 36
  • 62
  • Thanks! Also here is some pitch shifting with NAudio http://www.pluralsight.com/courses/audio-programming-naudio – user2136963 Sep 13 '15 at 13:50