Render Sample To Automation

Hey all !

Are you ready ?

I have been able to paste digitized sounds in a Renoise 2.7.2 automation enveloppe. :blink:

(yep I took my inspiration in the “bad ideas” thread :badteethslayer: ).

Download HERE the .xrns small test song that shows it’s possible.

Start the playback and you’ll hear a typical speak & spell digitized voice and a 303 sample loop, played from the automation envelope only.

Features :

  • no crazy playback definition needed (this time I won’t crash your computer, even if you’ve let the Automatic PDC system activated), the song works well on every computer, I’ve choosen 8Bits LOFI RAW digitized sounds that don’t require 999 BPM and 256 LPB.
  • no instruments, no samples, no notes, no ringmod, no pattern commands, no input line sound (volume = -INF)

It works with a line-in device, with no volume, a dc-offset, 100% controlled by high definition automation envelopes.

Note : if you want to completely cut the sound after the test playback PLEASE CLICK TWICE on the STOP BUTTON.

Thanx and
Have fun with Renoise !

cool trick!

You mad bastard! :)

This video shows you that Renoise automation graphical envelopes are internally converted on the fly into a XML data structure when copied into the windows’ clipboard.

After a brief analysis of this XML structure, we can see that envelope points are converted into FLOATING points values ranging from 0 to 1.

So the only thing we need to do then, is to build a simple utility or write a script that read 8 bits WAV files, and for each sample data, divide it by 255 and display the result into a floating point value.

I show you a quick done conversion utility I’ve compiled, able to perform it quickly and build a clipboard-friendly content for Renoise.

LEGEN… wait for it… DARY!
really, really cool and clever trick Kurtz, awesome.
but damn it you speak slowly! :)

That’s fun!

yes… because… I… am… heeeeee… how do they say… slow… ? it’s… even not… a question of language…, even in french… sometimes… I search my words in the middle of the sentences…, people are listening… and waiting in silence… and… I can finish then…

well, as far as i’m concerned, you’re allowed your slowness anytime, but even more so when you use it to do awesome stuff like this.

Now let’s see the very complex code of this small conversion utility. It’s a Win32 application. I’ve coded it in DELPHI, just because I know it well and because there are pre-coded functions in it, especially the function floattostr that allready do the job.

  
unit RAW2AUTOM;  
  
interface  
  
uses  
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
 Dialogs, StdCtrls, ComCtrls, JvDialogs ; // note that JvDialogs comes from the JEDI project and ensures you that at compile time you'll get Win32 compatible dialog boxes and not Win64 only compatible dialog boxes.  
type  
 TForm1 = class(TForm)  
 Button1: TButton; // top button  
 Button3: TButton; // bottom button  
 ProgressBar1: TProgressBar; // self explicit  
 RichEdit1: TRichEdit; // the editable text box where the XML will be built  
 JvOpenDialog1: TJvOpenDialog;  
 procedure Button3Click(Sender: TObject);   
 procedure Button1Click(Sender: TObject);  
 procedure FormCreate(Sender: TObject);  
 private  
 { Déclarations privées } // hey it's french language but anyway, DELPHI ignores it  
 public  
 { Déclarations publiques }  
 end;  
  
var  
 Form1: TForm1;  
  
implementation  
  
{$R *.dfm}  
  
  
procedure TForm1.Button1Click(Sender: TObject);  
begin  
richedit1.SelectAll; // selects the content of the edit box  
richedit1.CopyToClipboard; // copy the selected content in the clipboard  
showmessage ('The XML envelope has been copied in the Windows clipboard.');  
end;  
  
procedure TForm1.Button3Click(Sender: TObject);  
var  
 ms: TMemoryStream; // stream loaded in memory  
 i: Longint; // loop var. for the file read and conversion  
 p: byte; // read byte  
 ws : string; // converted string  
 FFrequency : Int64 ; // high performance timer.  
 FStart, FStop : Int64 ; // begin and end vars.  
 FElapsed : Extended; // final duration, in seconds.  
  
begin  
 if JvOpendialog1.Execute then begin  
 ms := TMemoryStream.Create; // will be used to read the RAW file  
 ms.Clear; // cleans the memory buffer  
 try  
 ms.LoadFromfile(jvOpenDialog1.FileName); // load file  
 ms.Position:=0; //  
 ms.Seek(0,soFrombeginning); // reads from the start  
 ProgressBar1.Min:=0; // progress bar update  
 ProgressBar1.Max:=ms.Size-1;  
 Richedit1.Lines.BeginUpdate; // prevent the box to be updated  
 Richedit1.Lines.Clear; // cleans the edit box  
  
 Richedit1.Lines.Add('<?xml version="1.0" encoding="UTF-8"?>');  
 Richedit1.Lines.Add('<envelope doc_version="0">');<br>
  	Richedit1.Lines.Add(' <playmode>Curve</playmode>');<br>
  	Richedit1.Lines.Add(' <length>'+InttoStr(ms.Size-1)+'</length>');<br>
  	Richedit1.Lines.Add(' <valuequantum>0.0</valuequantum>');<br>
  	Richedit1.Lines.Add(' <polarity>Bipolar</polarity>');<br>
  	Richedit1.Lines.Add(' <points>');<br>
  	Button1.Visible:=false;<br>
  	Button3.Visible:=false;<br>
<br>
  	// Initialisation of high rate timer metering.<br>
  	If Not QueryPerformanceFrequency(FFrequency) Then<br>
    	Raise Exception.Create('No high rate timer on this system.');<br>
  	QueryPerformanceCounter(FStart) ; // starts the timer<br>
<br>
  	for i := 0 to ms.Size - 1 do begin<br>
    	ProgressBar1.Position:=i;<br>
    	ms.Read(p,sizeof(p)); // reads one byte, 8 bits<br>
    	ws:=floattostr(p/255); // converts it into a renoise point<br>
    	if (p&lt;&gt;0)then ws[2]:='.' else ws:='0.000000000000000';<br>
    	Richedit1.Lines.Add('	<point>'+Inttostr(i)+','+ws+'</point>');<br>
    	end;<br>
<br>
  	QueryPerformanceCounter(FStop) ; // stops timer<br>
  	FElapsed := (FStop-FStart)/FFrequency ;<br>
  	Richedit1.Lines.EndUpdate; // allow edit box to be updated<br>
  	Richedit1.Lines.Add(' </points>'); // finishes to write the XML<br>
  	Richedit1.Lines.Add('</envelope>');  
 showmessage('XML Envelope Generated. '+InttoStr(ms.Size-1)+  
 ' points created in '+FloatToStrf(FElapsed,ffFixed,4,2)+' seconds.');  
 Button1.Visible:=true;  
 Button3.Visible:=true;  
  
 finally  
 ms.Free // free the dedicated memory stream  
 end;  
 end;  
end;  
  
procedure TForm1.FormCreate(Sender: TObject);  
begin  
Form1.Name:='RAWTOAUTO'; // raw data to automation  
end;  
  
end.  
  
  

Yep, that’s all. There’s nothing more. You compile it, and it does the job.

okay

Since I’ve got a few requests through PM and mails, from those who don’t have a DELPHI compiler, I provide the .exe conversion tool here. WARNING it’s coded in 10mn, it’s “quick done”, unoptimized, unthreaded, so it’s slow, and most of all it loads everything, even too big samples that will never fit in the patternlength and automation maximum size. It does not detect the samplerate, nor the bit depth, no pretty preview of generated XML code through a “treeview” mode, the timer looks inaccurate (I even don’t know why). It lacks of other functions, for example, it does not cleanse the first bytes of a WAV file, and it converts anything, even what should not be converted.

GET IT HERE

I will revamp all this and add in the future :

  • a treeview of generated XML structures
  • a flac/mp3/ogg/wma files loader !
  • an internal scope view of the envelope points !
  • LFO / instrument envelopes exporter !
  • 48KHz 32Bits samples !!!
    .
    .
    .
    nah I won’t improve it, I was jokin… :lol: :lol:

i dont know what its good for, but interessting approach.

You’re right, that “render sample to automation” thing is not really usefull. The sound quality isn’t that high and it increases the size of the .xrns tracks. I see it first, more as the consequence of a “state of mind”. In this state of mind, imagine that you’re like a magician, that does something unexpected, surprising, and people used to think it’s impossible ; and however, it’s done, so people ask themselves “what’s the trick” ?

Well, they for sure didn’t asked it here :P