render audio in background?
-
Is it possible to set a function to push buffers through modules silently in the background?
Lets say I have an audio buffer, can I let it through different effects, nodes silently in the background, and then store the processed buffer and write to an audio file?
-
@ulrik I haven't tried pushing audio to a separate thread, my understanding is pretty limited but it should, hypothetically, be possible.
The BackgroundTask API is certainly what you would want to use for this. I may be working on this exact topic in a few weeks so let me know if you make any progress with it!
-
@ulrik There are multiple ways to achieve this, the most fun one is this here:
- a scriptnode network with a split container that provides a "silent processing chain" by adding a clear node at the start and the end
- two audio file slots, the first is connected to a file player and a file analyzer.
- the second is connected to a recorder node
- the file analyser sends the length of the loaded file of the first slot to the length parameter of the recorder note and starts the playback and recording
- you can add whatever DSP processing you want between the file player and the recorder.
- once the file player is done, the recorder will save the incoming audio into a new buffer
- we can then register the content callback of the second slot to flush the recording. pick and save a file, clear out the first audio file slot.
HiseSnippet 2001.3oc4Y0saaibEdnrGmXkra1TrK1a45qjaSIjbb7lfEoV9GoV05eTkz5cw1KLFSNxZfI4vRNxxZCBvdQun.8pdYtoMOB8191r8MHuAsmYFRQRIYYKA6Esn1.wjyYNy7Mme9NmgoYH2lFEwCQFE6LLfhLdLt8PeQu85QX9nF6iL9X7gjHAMzTOztCCHQQTGjgwR+Z4.FqtLR8yG1dWhKw2llNDBcBmYSOf4wDoi1r5ui45Vm3P6v7xL6Mq1vl6uG2k2GvyR3xn.h8EjyoGQjSq.F8aHQ8PF+b7K1341a57kNarwKd0V1jsnupKoa2JO2YyM25kupxyeEYyWtEs7KPFqTygI3gsEDAMBVzc4NCa2iOvWuAmvhXm4RkuTA0F1Y8vn85wbcZlXbhPHikalZpVRap9T7gLG1nwSMYehRfYpFYMZFElEjpLGPxHCjVVComhaaGxBDoRj34Q3F9fGrKA7MYghdtnB+9kv6wgY3Kr7HWPqGBuLRiRaUt7yLg+Y8upXQv+DILujDZFEX9ZSUnh04TwN8cX71Du.W5nstzZ502r92VYswTF7v1TXAhBFocclKszXahfDBhmx7pHmmVpUDUDi98HttmAgLk5122Vv39kr6Q7Om5zv2gd05EeSwUgYFwcoVAgLeQo0ZQAIvimaZykfWPsrrjfc0hqJAvY861EB8ecLRjfHduJomT90SetTypeXHLK2gGvg3bGEnWWpR5wWNFrxx+zdHjg4Y0Mj60hBaHExhZKj35lVxmkU+Q1mnzSfLXRd9dclcUtZMIxEaeVH0FBFGVZc0VHiwTK7ZAZ2H0wZ.4xXKR7ZYMHjInoNCsQ5Yl07Om4qVbcjPKH.WhvM1bZ1p0Tme4RAlSSA2bMyeQBZsD73ieYkQK1H3BGbM5j.5sq+UI9YSt+QbA8X+RJmbw2VzbbQc6NUYRuYH20kFNUwRBpvYoXI+9dmIO7WRb6SGMQHgLeV9J2trbacvUlIx8a3yDGGPieuN20Ql8JedRNATbzojcHFgvdKTbCeVL2fxw8MjKoc4gdHlijuJ2XUPpCSVZbGhfnXfCk4SvgJD3ywFRQpQp46j7N5qarub1wH..C.v.ZnfIsCF6SuDpHnYqVEuOM5BAOPMWu.tuD5FOXtw6UxM+e.68P4CuGdHHwnzvQUSaDSDpGkcduzpQ+ven5.lin2nAdunJZRhUfRm6z2kHxyyKq.FK.BKxQtJIP8iXhgYqPNGj+kmI4+sEhOE2jIr6McLVXJXD7a2GXLtj4GgqAbE1hT.tLt92tn0GKe6qOh06ew3HAXOkadt.irf3n9dojoxXpBvwItboweFmRDDDRC.lzN7ltjgkhFw68Lyyb41Wzl88zIYOhCN2UNCUIJepazhPxrxcTqDnV79Bft8PBv5JSlfyeaEm6dwnKwFD+d4jr81PAT0K+a3mXgUjuaDKrRhvTpIzQTw.d3EJeT7yHiGpcHQJi7ocupBZGWW9.Iu.KNzEbLpwZxcGFzi6yrkComQBR2wi22Wj.2z39cSbGIHG5krCg4JSCZ2OB3WcN1uMrNpFXMV5DZXjZOe.trE7KjVbD2ADsRchphYShjz3oXIkMDLSCsrGETm6XjKtR0IaNwxUMomWMxfCjmhHD3aMVJC6oNjV9FjvVPuQMhNQJ0l3hNQyZCGb4ZpstZHKm5CvQAtPa3WK70hmDsIJNO.cDBJjCAZKzMX.mFBzRtGMUHneHXufddSPeLnenduq7ekn1Xk7H0kRBGCoOF6A+0RIZJfbjR2.JKjy6l0XAPN4MX4Nj4ex3MObH4pwF6Ca2VPCzYioyq8EzAZrmcl5HG8BzgdknCW8LvlbIfG4l9H7WCcw2EbFNnI178ocI8cESLdVe7Gg6BI9mF.T3v5ky78y.GcH0Jq7IMh40etxS1ScsiqR5XJSQmruAkIUWgIYAqAkCbf1.UpY7E32zr0w+1Z604z5Gev90Z81NzHQCuf9tQTY66nTuhV+TORbOa4bnKO+NTT0IcnfS9ZcneLVVuTdWsCktg6R+ZFvu5hGMNKvuBz1m3NDzeX6c5K3PZptoLzrM+aVchSP0+d04Ke5I3VbtndH8O1Gp2MbtOJ+vapN0iBLN5NH3o5+56+Syv9+HrD4sjk0memvG195bBYYDdhNil3SbGFMNmvmqH+g9xrxOoIIFFeYtApgkmYofUvpbkXb+P7AT+yA3joGmNpORgTWnoHnYHacWSpZvx6AUDC21mG5.HYjWRN9SwsTiCc.lrnyk9O.q5.8ZzJO6XNEiyjtSXA0cYNWLc4qyGRgvmyx6peDt6UVwBlVwyXQyvu9Kw633XNnGbNgolz5u7KxLj22b.wWXx7M6QCke4oYVmco6+5rvExgav.fa9yq9wqIu5G2F8SQ+Aei5N7+uEpWAql6cInyDPmIYMWH8SzczLR3jg0Yz7dtWFiIxheL9MMNpSsVGsyAuclss7W9twyOJb+W4Ogn6Nrekqsz+s6HLYo+2+t28OmwQXRt945v7q9au6uFV81cXxe0O0EPlmqljny+2cyjbknt9W1kyuvin9LJKz2b8mjO5iGwNjeZb+RRexCUi.TG9Jm7p3CkuaNku4rGygcpsc9kZBE2XQU74KphatnJ9hEUwsVTE+xEUwWdyJJ+u3LNeW1uGjL0rllC2nlO4LWcpL5+fcNTD0
-
@Christoph-Hart that sounds great, I will study your example, thanks!
-
@Christoph-Hart This works great!
If I set a stretch node instead of the "file player" node, I am able to pitch shift the original audio, nice!
If I change the time ratio on the stretch player, I am also getting a time stretched result, however I need to change the "recording length" dependent on the time ratio.
Now the file analyser provides me with the original length of the audio file, is there a way to modify the recording length related to the time ratio set in the stretch player? -
@ulrik never mind, I found out, I need to scale the length coming from the file analyzer with the time ratio value, and set it to the recorder.
Using a pma node will fix that I guess -
@ulrik said in render audio in background?:
@ulrik I need to scale the length coming from the file analyzer ...
That was harder than I thought.
I set it up like this:
Using the min max node to invert the TimeRatio value and feed that into the pma Multiply.
That is working if I can find the exact Skew value on the min max node.
As it is now I have set the skew to 0.65, and it's close.Is it possible to find the exact skew value considering the TimeRatio range 0.5 => 2.0
-
@ulrik Right click on the stretch player's time ratio parameter and you'll see this:
Here it is as a number so you don't have to do it yourself:
0.6309297680854797
-
@Christoph-Hart perfect, thanks!
One more question, when I render the buffer through the stretch node, there is latency baked into the resulting file (there is a small part at the beginning which is silent), is there a way to find out how many samples that is?
I'm thinking of adding the silent length to the resulting buffer and then trim the start, is that a proper way to get rid of it? -
@ulrik yeah there are tools in the Buffer API:
- getNextZeroCrossing() should give you the first non-zero value (haven't checked that though), otherwise it's trivially to implement this with a loop
- trim() can be used to create a buffer from a sub range of an existing buffer, this is the most efficient way.
-
@Christoph-Hart thanks a lot!