Building a Dynamic Sampler Plugin in Plugdata - Part3
Tutorial | Oct 12, 2023
In this video, I demonstrated how to make improvements to our small plug data sampler. I showed how to utilize symbols and send/receive objects to simplify the patch, as well as addressed bugs and added a solution to the clicking problem when writing and reading from the same array. Additionally, I explained how to convert the length of the buffer from seconds to milliseconds and sync it with the host's BPM using the playhead object.
You can watch the Video on Youtube - support me on Patreon
More Videos in this Series #
Questions & Answers #
Maybe you dont watch the video, here are some important takeaways:
What is the main focus of this video? #
The main focus of this video is to address bugs and improve the visual aesthetics of the small plug data sampler created in the previous videos.
How is the issue of clicks and pops in the audio addressed in this video? #
To solve the issue of clicks and pops, the video introduces the use of multiple arrays and array read and write modules. By copying the data from the first array to the second array at the appropriate time, the clicking problem is minimized.
How are the length of the sampler and the time frame synced with the host's BPM? #
The video demonstrates the use of the "playhead" object to access the host's BPM and convert it into milliseconds. By multiplying this value by different factors, the length of the sampler and the time frame can be synced with the host's BPM.
How are parameters exposed for automation in a DAW? #
To expose parameters for automation, the video shows the creation of automation parameters using the "parameter" object. By linking these parameters to specific interface elements, such as knobs, the values can be controlled and automated within the DAW.
This is what im talking about in this video. The text is transcribed by AI, so it might not be perfect. If you find any mistakes, please let me know.
You can also click on the timestamps to jump to the right part of the video, which should be helpful.
[00:00:00] Okay, so in this video, we want to finish our small little plug data sampler.
[00:00:22] And this is here where we left in the last video.
[00:00:24] If you haven't watched the last two videos, please do it now.
[00:00:29] Also we are on the same page.
[00:00:31] So in this video, we want to cover some of the bugs we still have in this patch and also
[00:00:38] want to change some things here to the patch itself.
[00:00:42] So it's more pleasant to look at.
[00:00:46] So the first idea is here that some of these interface elements have received symbols and
[00:00:54] send symbols as you can see on the right side in the inspector.
[00:00:58] And this means you can send data and receive data without using these kind of send objects
[00:01:05] here and also using here receive objects, right?
[00:01:09] So we can just take this address here, volume dry.
[00:01:13] And instead of connecting this and that, we just go to the interface element here and
[00:01:19] put this address into the send symbol.
[00:01:22] So now we send data directly from this knob to this address wall dry.
[00:01:28] And everything that uses receive wall dry like this one here receives the data.
[00:01:32] So we don't need actually that object here.
[00:01:34] I can see it's more pleasant to look at, right?
[00:01:37] So all we have to do now is here take all these addresses, put this here into the send
[00:01:43] symbols and can remove here the feedback, the send objects.
[00:01:50] So here we take feedback, send simple feedback.
[00:01:56] And delete this also here.
[00:02:00] Take this address and send it over here and so on.
[00:02:06] Also at the same time, we can use send objects here and say we want to send this to a knob,
[00:02:17] try level.
[00:02:18] We can take this address here.
[00:02:22] And then instead of going in here, take this, put this into the send knob and then we can
[00:02:29] receive this here with the same address, knob dry level.
[00:02:33] Or let's go here for the same, I have to work a bit on my naming conventions, knob wall dry.
[00:02:41] Okay, that's a bit shorter.
[00:02:46] And then we do the same here with, let's say, feedback.
[00:02:51] So we say here it's knob feedback.
[00:02:55] Take this address and then put this into the send object.
[00:03:01] And we can connect here these two.
[00:03:04] Also length here, s length, knob s length.
[00:03:12] Put this into the send object.
[00:03:15] Also connect here these two.
[00:03:17] So we can kind of separate here these smaller islands.
[00:03:26] We also have here a connection from load bank to the playback bang knob here, which is also
[00:03:34] an interface element.
[00:03:36] So we can use here also a send symbol or receive symbol.
[00:03:39] Let's say knob play.
[00:03:48] Take this address, send it, connect these two and we can remove here this small little
[00:03:57] connection and we have here a separate thing sending signals to all kinds of addresses
[00:04:05] all over the patch.
[00:04:08] If you do this too much, maybe then of course it comes a bit, you know, you lose control
[00:04:14] or where something is flowing.
[00:04:17] Maybe we get in the future some kind of hints, some data flowing lines here so we can see
[00:04:25] where data is sent and received would be nice to have.
[00:04:30] So there are many more places we can use this trick on.
[00:04:34] So let's see, we have here for instance this metro bang receiving data from the metro.
[00:04:41] So we are using here a send and call it maybe a metro bang.
[00:04:50] Go into that and we can say this address here is received with this knob, metro bang.
[00:04:57] We can delete here this connection.
[00:05:02] It's over here maybe.
[00:05:03] Then we have here let's say, yeah, this output here for instance this line we can use a send
[00:05:14] here and can say this is let's say time frame in milliseconds.
[00:05:25] We go into that, use this address here.
[00:05:28] We can use this also on this number which is also an interface element.
[00:05:32] So it has also your receive symbol time frame and we can just remove this connection here.
[00:05:41] Also here, of course, we go from here to here, right?
[00:05:45] So we can take this one, put this over here, connect these two and delete this because
[00:05:51] here is also a receive symbol time frame in there.
[00:05:55] So we receive data there.
[00:05:58] So maybe let's try and change the length here.
[00:06:01] You can see we change the values here even though there's no connection.
[00:06:10] So then we have here the vline.
[00:06:12] There's the last kind of connection here.
[00:06:16] So use a send and call it vline.
[00:06:25] Connect this here.
[00:06:28] Choose receive.
[00:06:36] Connect these two and we can disable or remove this kind of connection.
[00:06:40] So we have here an island for our calculations with the sample rate.
[00:06:44] We have here the load bank for the init values.
[00:06:48] We send all these init values around to our or all over the patch here and we don't need
[00:06:55] a connection for that.
[00:06:56] So it's much, much cleaner to look at.
[00:06:58] Maybe you lose control at certain points.
[00:07:00] Like I said in the beginning, when you do this too much and the patch becomes too big,
[00:07:06] then of course you have to use sub patches and so on.
[00:07:09] But I don't want to do that in this video.
[00:07:12] Again later videos we go into sub patching.
[00:07:16] We can also remove these two here when I look at it.
[00:07:21] So let's use here receive.
[00:07:26] Metro bank.
[00:07:27] We can connect this, that can remove these two connections.
[00:07:40] We have also this one here, which changes basically the dry volume.
[00:07:48] So another problem we had in the beginning was that we on the last video at least is
[00:07:54] that we had some clicks and pops.
[00:07:57] So here there's no plug-in at the moment.
[00:07:59] So let me use here.
[00:08:02] Yeah, no tech.
[00:08:07] This is tremendous.
[00:08:08] We have some audio to work with.
[00:08:11] Let's go with this one.
[00:08:14] Let's use the input.
[00:08:16] And of course, let's use my MIDI keyboard.
[00:08:19] So now I can play something here.
[00:08:23] You can hear there's some kind of click and pop in the middle.
[00:08:38] And the problem with that is that we write and read into and from the same array all
[00:08:45] the time.
[00:08:46] So you write into the array from the left side to the right side, right?
[00:08:51] And then we read from the array from the right side to the left side.
[00:08:56] And you can see in the middle here basically is when we have this click because we meet
[00:09:02] the new recording and the last playback basically.
[00:09:23] It's always here.
[00:09:29] You can see here where you can see the new buffer is overwritten and then we read from
[00:09:33] the back here.
[00:09:34] And then in the middle we have this click kind of where these two waveforms meet.
[00:09:41] And my solution for that is basically that I use multiple arrays for that.
[00:09:49] So just downsize here this one.
[00:09:53] And then I kind of copy it over here to a second one.
[00:09:58] So I just use copy and paste.
[00:10:01] And this one here is called differently.
[00:10:03] There's a different address.
[00:10:05] It's sampler 2.
[00:10:08] And we still record here basically to the first buffer.
[00:10:12] And what we want to do is when the write process is done, when we are done writing here into
[00:10:19] the buffer, I want to copy this whole buffer into the second buffer.
[00:10:24] And we can do this here with some array read and write modules.
[00:10:32] So let's do this here by using array get sampler.
[00:10:45] So this one basically gets all the data that is in the first array.
[00:10:51] And we use here a bang knob that we don't need to use a bang knob, but I use it.
[00:10:58] And then we do a second one array set sampler 2.
[00:11:08] So I can write now into the first array.
[00:11:13] Then at a certain position I can say copy everything over to the second array like this.
[00:11:19] And can make a snapshot basically of the current thing here.
[00:11:26] So then I want instead of reading from the first array, I'm reading from the second array
[00:11:34] And I want to use metro bang basically here to do this whole process.
[00:11:39] So I go into the bang here and say receive metro bang.
[00:11:46] So every time we bang here basically, we also just copy the first array into the second
[00:11:57] So now it's basically when we read from the second array, we are left alone from the writing
[00:12:30] The second sampler is basically only refreshed and the writing process is done for the whole
[00:12:35] And then everything is copied from the first array into the second array.
[00:12:39] So it's much better this way in my opinion.
[00:12:43] Maybe there are some pure data specialist experts that can write something in comments
[00:12:48] what would be the better solution for that, but I think it's pretty okay to do that.
[00:12:56] So then we have this.
[00:12:57] We also need to resize here the second sampler.
[00:13:04] So if you can remember from the second video, when we change the length basically, we also
[00:13:09] need to change the length of the array, the index size.
[00:13:14] When we do this here basically with this resize message sending this to the sampler, but we
[00:13:19] also need to send this here to the sampler too, of course.
[00:13:24] So that's that.
[00:13:25] So this is basically my solution for the clicking problem.
[00:13:27] And I think you shouldn't have any clicks now in your audio material.
[00:13:54] I still just click when we copy from the first to the second.
[00:14:08] But maybe we can introduce their volume fade later on at the moment.
[00:14:13] It's better than before.
[00:14:23] So let's move on.
[00:14:26] So the length now at the moment is in seconds, I believe it's in seconds.
[00:14:32] And we want to change this to milliseconds firstly, and also secondly to for the interface
[00:14:40] in fourth notes.
[00:14:41] So we want to time sync this with the BPM of the host, right?
[00:14:47] So you have 120 BPM maybe or 100 BPM and then these time frames for one bar or for one fourth
[00:14:54] note and so on changes, of course, with the BPM.
[00:14:57] So we have to we have to recalculate this stuff, right?
[00:15:01] And we can do this by using an object called playhead and playhead gives us a lot of outlets
[00:15:13] You can see we get here a one or a zero when the host is playing on the playback state or
[00:15:21] when we are on the record state.
[00:15:23] We also get here the BPM.
[00:15:26] So BPM is in say print here is one at 10 and we receive this basically as a number here
[00:15:39] when we change this to 90, right?
[00:15:43] You can see it on the right side and it's firing all the time.
[00:15:48] So it's updating, I think, each millisecond probably some something like that.
[00:15:54] So one on the 10 is not really what we need.
[00:15:57] We need to convert this into milliseconds and exactly milliseconds for one fourth note
[00:16:05] and we can do this by using an object called BPM.
[00:16:08] I mean, we can do some math here using just division and so on.
[00:16:14] But this object is pretty helpful.
[00:16:16] So I just use that.
[00:16:19] So BPM here gives us basically so you can see a millisecond.
[00:16:24] So for 90 BPM or 100 BPM, we get exactly 600 milliseconds.
[00:16:32] This is one fourth note.
[00:16:33] So this is here one bar.
[00:16:38] I think this is one bar, right?
[00:16:39] This is one bar.
[00:16:40] So this time frame here is basically 600 milliseconds.
[00:16:46] So this is one fourth notes.
[00:16:48] So now with multiplication, we can of course just duplicate this and say times two, right?
[00:16:53] And then we have two fourth notes and then we multiply this by four.
[00:16:57] We then get one bar, the length of one bar in milliseconds.
[00:17:01] So this is the idea for that.
[00:17:06] So the first thing we need to do is to change here down here, where we receive the length
[00:17:12] of the snob, which at the moment is in seconds.
[00:17:16] So we use here a value between zero dot one and 10.
[00:17:20] So this is seconds.
[00:17:21] We send this over to here and then we multiply this here with the sample rate.
[00:17:28] So we need to divide basically this by 1000.
[00:17:33] So we take here a division 1000 to kind of change the unit from seconds to milliseconds
[00:17:46] that I have to see in place.
[00:17:49] Then we want to use instead of a print here, don't need to print.
[00:17:54] Use a change object here.
[00:17:59] You can see change is I use this because I only want to receive updates or messages
[00:18:06] when something changes, when the BPM changes.
[00:18:09] I don't want to update here every millisecond.
[00:18:13] So when we use the print here, you can see here, this is flashing blue.
[00:18:19] This is flashing in blue.
[00:18:20] This is flashing blue is getting updated all the time.
[00:18:23] Only print doesn't receive any updates.
[00:18:26] Because the BPM stays the same.
[00:18:28] And when I change this here, when I change the BPM on the host tempo, you can see now
[00:18:33] it flashes and updates the value and we receive data here on the print.
[00:18:38] So with the change object, you can basically prevent these updates and only let messages
[00:18:48] pass through when something changes, when the value is changing, when the value stays
[00:18:52] the same, you don't receive an update.
[00:18:55] So it's a nice object to use here.
[00:18:58] So then I don't need the print here at all.
[00:19:02] And then we need to introduce maybe here number.
[00:19:09] And we want to have a minimum of maybe one and maximum number maybe of, I don't know,
[00:19:16] eight or something like this.
[00:19:18] So this is basically the multiply K-term.
[00:19:21] I don't know what the real name is.
[00:19:25] So how many times we want to multiply basically our one fourth note time frame in milliseconds.
[00:19:34] So we do this here with a multiply.
[00:19:40] Go into that and we take the output of the change for that, right?
[00:19:45] So we multiply basically here the milliseconds times how many times we want to have this
[00:19:51] one fourth note.
[00:19:52] So this is basically one fourth note and we go to two, we have two fourth notes and if
[00:19:57] you go for four here, then we have basically one bar.
[00:20:01] So the time frame of one bar.
[00:20:04] And then we need to put this into first and foremost into the interface of this knob here
[00:20:14] because we want to change the range of the knob.
[00:20:17] So we do this by sending something to, let's say this receives on this address.
[00:20:25] So we go in here, send something to that and we send basically here, let's say, let's use
[00:20:35] a message, change the ticks to a certain number.
[00:20:50] And we also want to change the range.
[00:20:55] So right from here at the moment, the range is 0.1 and maximum is 10.
[00:21:00] So we want to change this accordingly.
[00:21:03] So we also sent here another message and change the range to start value, start value and
[00:21:17] end value.
[00:21:20] So now we have to pack this here, float, float.
[00:21:29] So basically say what we receive on this input that goes into the first float and the second
[00:21:36] inlet here goes to the second float, right?
[00:21:38] We packed this together in one message package and then we send this over here to this message.
[00:21:44] We then replace here the first float with the first variable and the second float of
[00:21:49] the second one.
[00:21:50] And then we basically create this kind of message which has this word, this keyword and
[00:21:56] then these two numbers and then we send this over to the knob here and then we receive this
[00:22:01] here and then we change with that the range, the minimum and maximum number.
[00:22:07] So this is kind of the idea of that.
[00:22:10] So the second input here is of course the last number.
[00:22:15] So the range, the end range is basically, yeah, this multiplies.
[00:22:19] So we take basically here the one fourth notes in milliseconds, multiply it by four, which
[00:22:25] is one bar and then we get milliseconds as the time frame for one bar.
[00:22:30] And this is the end range, right?
[00:22:33] The maximum number.
[00:22:34] This is the second floats.
[00:22:35] We take this and first float is basically the minimum time frame in milliseconds and
[00:22:44] this is what we get here from change.
[00:22:47] So this is the smallest kind of range of the knob, which is just one fourth note.
[00:22:53] So you have to always sample one fourth notes.
[00:22:56] You can divide this here if you want to go shorter, of course, but I just use here one
[00:23:01] fourth note as a minimum starting number or minimum range basically.
[00:23:12] So we also need to use here the output of that for the ticks down here and ticks are
[00:23:19] basically here some interface elements.
[00:23:22] You can see this in a moment when I change this here, right?
[00:23:25] For you can see now we have these dots here.
[00:23:27] One, two, three, four.
[00:23:30] It's basically a quantized interface element.
[00:23:33] So we have maximum number of five fourth notes.
[00:23:38] So we have here one fourth, two fourth, three fourth, one bar and then five fourth, right?
[00:23:45] So we can kind of quantize here the interface with the ticks.
[00:23:50] So we use this number here for the ticks.
[00:23:52] We use the number to multiply here to milliseconds for one fourth notes and use this as a maximum
[00:23:57] range and then we use them as a minimum range.
[00:24:00] We use, yeah, one fourth notes coming here from the BPM setting.
[00:24:07] So this is my totally genius idea of how to structure this.
[00:24:14] Well, it kind of works.
[00:24:19] And then after that we want to receive what's coming from S length and we don't want to
[00:24:25] send this to S length.
[00:24:26] We don't want to send this from here to here, right?
[00:24:31] We don't want to do that.
[00:24:32] We want to put a quantizer in between.
[00:24:35] So we send this here instead of S length, we send this to maybe a length.
[00:24:42] You receive this data here and then we put this into a quantizer and then we send this
[00:24:56] back out to the original address, right?
[00:25:03] So instead of going from here to here, we go now from here to here and we quantize it,
[00:25:11] go back to here and then we send it here.
[00:25:14] So it's just in between now a quantizer.
[00:25:18] And as a quantizing number here, step value to quantize to, right?
[00:25:24] We take basically the output here of change.
[00:25:28] So it's the quantized step size is one fourth note.
[00:25:32] So that's the idea.
[00:25:35] And with that, we want to also save this here just to make sure, say, it's now part
[00:25:44] three, so we make sure everything is saved.
[00:25:49] So now that we have this, we can now change here, I think, in different sizes.
[00:25:59] So let's update here to BPM.
[00:26:04] You can see here the step size now.
[00:26:07] So the minimum number is 600, right?
[00:26:11] Then we increase here the number.
[00:26:13] Then the next one is to 1200 and so on.
[00:26:19] So we have kind of a quantized number now, which is a milliseconds, but it's always the
[00:26:23] size of one fourth notes and it changes when you change the BPM.
[00:26:29] So when you go to 110 here, right, you can see now the numbers are different, but they
[00:26:34] are still stepped.
[00:26:36] So this is basically the calculation for having exactly the right buffer size in milliseconds
[00:26:42] for the BPM you are currently choosing in your host.
[00:26:46] I know it's a bit complicated, but if you think about it, it kind of makes sense.
[00:26:52] Okay, so the next thing would be to expose some of these parameters to the DAW.
[00:26:58] Automation and so on.
[00:27:01] But there's still here some problem we have to solve and that's here.
[00:27:08] We basically used to have here seconds, now we have milliseconds, so we don't need to
[00:27:13] use actually here times 1000.
[00:27:17] That leads to some kind of problem.
[00:27:18] So we just need to remove here because this is now already milliseconds.
[00:27:26] So we use this here and timeframe there.
[00:27:31] So that's better.
[00:27:33] And then we want to expose some parameters like I said to the DAW.
[00:27:37] So we can use here these automation parameters and can say we want to expose your feedback.
[00:27:47] If we change this here, you can see it in the background probably sizes a bit.
[00:27:54] You can see it down here, right?
[00:27:57] You have created basically this automation parameter called feedback and we can use this
[00:28:01] in the DAW.
[00:28:03] And we can access this by using parameter and the name of it feedback.
[00:28:13] And we send this here to our knob.
[00:28:16] The address of this is knob feedback and then can change the feedback here with the slider
[00:28:30] and also in here.
[00:28:38] And I think we can also use the output of this send symbols feedback.
[00:28:44] So we receive feedback here and send this to the parameter.
[00:28:52] That's not gonna work.
[00:28:59] Maybe we have a second.
[00:29:05] We have to make a second one here.
[00:29:06] I know.
[00:29:07] I don't know.
[00:29:12] So we can move this here, but it doesn't move here.
[00:29:29] This connection still works.
[00:29:34] It looks like we can't make a connection here from this one to that one for some reason.
[00:29:42] Maybe if I remove this here, let's see.
[00:29:46] Yeah, there's no connection happening here for some reason.
[00:29:51] Maybe this is a bug.
[00:29:53] Maybe I'm doing it wrong.
[00:29:55] But I guess in the future this kind of works if you do it like this, right?
[00:30:01] So we take the output of this interface element, send it over here, go into parameter feedback,
[00:30:09] change basically here the automation parameter, expose it then here and everything that we
[00:30:16] receive here, this connection works.
[00:30:19] So if we turn this knob here, we can change it here and also inside of the patch.
[00:30:29] This kind of works.
[00:30:32] Maybe we do this also here with the wet level.
[00:30:40] So we send it to volume bed.
[00:30:43] So we receive this here, go into new parameter, volume bed.
[00:31:00] And then we send the spec to the object here or to the interface element.
[00:31:09] And we are good to go.
[00:31:14] So let's see if we actually use here, oh, we have it already here.
[00:31:24] We can automate this.
[00:31:26] You can see it's updating here the value.
[00:31:33] Also change here feedback.
[00:31:46] So this is how you expose parameters you create here on the right side, these automation parameters
[00:31:53] and then you can use these modules here called param and then you use the address of this
[00:32:02] thing here and then you can say that send data and receive data from it.
[00:32:07] So this, this is the idea about it.
[00:32:10] So let's try it out.
[00:32:12] If it still works here.
[00:32:21] Let's update here this one to play back.
[00:32:32] Maybe maybe increase your the sizing of that.
[00:32:41] Yeah, something like this.
[00:32:58] And then let's see size of the plug in right click pair properties.
[00:33:04] Right is 375.
[00:33:16] See how it looks like in plug in mode.
[00:33:22] I think you have also to expose all parameters if you want to preserve this when you save
[00:33:27] the project.
[00:33:28] I'm not really sure, but I think you have to do, you have to do all these kind of automation
[00:33:34] parameters for all these knobs here if you want to save it with a preset or with the
[00:33:40] project itself.
[00:33:48] Oh, yeah, we have to do just one more thing because the playback is always what you start
[00:34:03] basically the metronome here every time you load the patch, but that's not specifically
[00:34:11] when you hit play, right?
[00:34:13] You need to synchronize it here with the playhead in some way.
[00:34:16] So instead of using here, instead of using let's say load bang here and then trigger the
[00:34:26] playback, I want to use the output of the playhead here.
[00:34:34] So I'm using change and the output of play or change.
[00:34:46] So we receive basically here a one when you hit play on the transport.
[00:34:55] Select one.
[00:34:57] So we only pass through messages here when we have basically one or when we receive one.
[00:35:05] You can see when I stop nothing really changes here only when we hit play it flashes basically
[00:35:16] and then we start here the whole process instead of using load bang.
[00:35:23] So that's probably much better.
[00:35:25] So now we synchronize basically the start of the metronome and then all these milliseconds
[00:35:30] make sense for these one fourth notes and so on.
[00:35:34] So we need to basically synchronize the start point or the playback.
[00:35:40] Okay, so let's save this here.
[00:35:44] Let's go back to plug in mode.
[00:36:01] So it's synchronized.
[00:36:16] The buffer size is the right right right time frame.
[00:36:21] We synchronize it with the host tempo and we also expose some parameters for automation.
[00:36:27] I showed you in the second video how to use the plug in mode.
[00:36:30] There are probably some some errors in here and plug data is also still in heavy alpha.
[00:36:37] So there's a lot a lot of changes sometimes it also crashes as you can see it in the face.
[00:36:41] It's behaving weird for some reason.
[00:36:45] So yeah, keep that in mind.
[00:36:48] And I think that's it for this tutorial for these three videos.
[00:36:52] There's still a lot of stuff you can do of course and change things and make it different.
[00:36:58] What I want to give you basically an intro how to approach these kind of devices, how
[00:37:04] to use plug data and how to expose parameters certain features right that you can also use
[00:37:09] here play head and get some information from the DAW into plug data and use that to react
[00:37:16] on it right.
[00:37:18] How to use these send and receive objects here also with the interface elements.
[00:37:24] It's very neat and maybe in the next next tutorials I talk about sub patching and stuff
[00:37:31] like this.
[00:37:32] And yeah, I think that's it for this video or for this type of series.
[00:37:37] Leave a like if you like the video, subscribe to the channel and also head over to the plug
[00:37:43] data site and make sure you are sponsor.
[00:37:46] If you want to spend a bit of money on it because it's completely open source, it's free.
[00:37:50] All these guys working basically for free and try to give you this environment here.
[00:37:57] Okay, thanks for watching.
[00:37:59] See you in the next video.