Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 12th April 2024, 13:28   #1  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Multichannel 5.1 speed up + pitch adjustment

Hi there,
I have a 24p movie that I'm trying to speed up by 4% and pitch adjust so that it's gonna be 25p.
This is not something new as I've been doing it other times for stereo contents by using TimeStretch().

For stereo contents, to avoid having the left and right channels go out of phase and generate flanger effect (i.e the audio oscillating constantly from left to right) I use MergeChannels() before calling TimeStretch() so that both channels are processed together and timestretch is aware of it so that it doesn't make them out of phase.

In other words:

Code:
#Indexing 24p video & audio
video=LWLibavVideoSource("M11340.m2v")
Left=WAVSource("M11340_Left.wav")
Right=WAVSource("M11340_Right.wav")
audio=MergeChannels(Left, Right)
AudioDub(video, audio)

#Speed up + pitch adjustment 4% 48000Hz
ConvertAudioToFloat()
AssumeFPS(25, 1, false)
TimeStretch(tempo=100.0*25.0/(24000.0/1000.0))
SSRC(48000)
ConvertAudioTo24bit()

So far so good, but the question is: what happens with 5.1?
Can I just do:

Code:
#Indexing 24p video & audio
video=LWLibavVideoSource("M11340.m2v")
FL=WAVSource("M11340_01.wav")
FR=WAVSource("M11340_02.wav")
CC=WAVSource("M11340_03.wav")
LFE=WAVSource("M11340_04.wav")
LS=WAVSource("M11340_05.wav")
RS=WAVSource("M11340_06.wav")
audio=MergeChannels(FL, FR, CC, LFE, LS, RS)
AudioDub(video, audio)

#Speed up + pitch adjustment 4% 48000Hz
ConvertAudioToFloat()
AssumeFPS(25, 1, false)
TimeStretch(tempo=100.0*25.0/(24000.0/1000.0))
SSRC(48000)
ConvertAudioTo24bit()
and call it a day?
And if so, what is TimeStretch() actually doing with the 5.1? Do I have to specify the audio layout in the frame properties? Is it gonna know that it's a 5.1 or is it only gonna process the stream as 3 stereo pairs (i.e FL FR // CC, LFE // LS, RS)?

Last but not least, given that the output PCM 24bit 48000Hz audio file muxed as RF64 .wav is gonna be fed to a DolbyE encoder (Dolby DP600) which needs the 5.1+2.0, do I have to filter them separately 'cause otherwise TimeStretch() is gonna make a boo boo or can I just do something like:


Code:
#Indexing 24p video & audio
video=LWLibavVideoSource("M11340.m2v")
FL=WAVSource("M11340_01.wav")
FR=WAVSource("M11340_02.wav")
CC=WAVSource("M11340_03.wav")
LFE=WAVSource("M11340_04.wav")
LS=WAVSource("M11340_05.wav")
RS=WAVSource("M11340_06.wav")
Left=WAVSource("M11340_Left.wav")
Right=WAVSource("M11340_Right.wav")
audio=MergeChannels(FL, FR, CC, LFE, LS, RS, Left, Right)
AudioDub(video, audio)

#Speed up + pitch adjustment 4% 48000Hz
ConvertAudioToFloat()
AssumeFPS(25, 1, false)
TimeStretch(tempo=100.0*25.0/(24000.0/1000.0))
SSRC(48000)
ConvertAudioTo24bit()


Thank you in advance.
I'm currently trying to test stuff but I don't really trust my ears, you know...
FranceBB is offline   Reply With Quote
Old 12th April 2024, 16:50   #2  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 242
Try Audacity as other people have said it will speed up properly without pitch blah blah.
coolgit is offline   Reply With Quote
Old 12th April 2024, 19:26   #3  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
To be fair, the point isn't to try other things manually but rather to know whether I should correct my AVS Script or not, 'cause most of the time those would be part of a completely automatized workflow in FFAStrans, so... yeah... I kinda need to know.
Also, I'm extremely curious about the inner working of TimeStretch() and the SoundTouch library.
FranceBB is offline   Reply With Quote
Old 13th April 2024, 09:38   #4  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,903
I thought the TimeStretch multichannel issues had been fixed. Is there still a phasing problem?
https://forum.doom9.org/showpost.php...2&postcount=20

The SoundTouch changelog says multichannel support was added to version 1.8.0, which was a fair while ago.
http://www.surina.net/soundtouch/README.html
hello_hello is offline   Reply With Quote
Old 13th April 2024, 10:36   #5  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 7,086
In the readme of Avs+:
- Updated: TimeStretch plugin with SoundTouch 2.1.3 (as of 07.Jan 2019)

But I don't know if work fine with 5.1+2.0
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 19th April 2024, 20:20   #6  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Ok, so after a few tests, after checking with a tektronix waveform monitor and after sending out the files to the AVID ProTools guys I came back to the following conclusion:


1)
In single channel mode (i.e if you have several mono tracks and you use TimeStretch on each one of them individually), the filter doesn't work correctly as it's unaware of the other channels. This means that we have a flanger effect with the audio oscillating from left to right due to the very small pitch variations between the left and the right channel.

2)
In multi channel mode those things don't happen. Effectively, if you have a stereo, you must use MergeChannels(left, right) after indexing left and right before you perform the speed up with pitch adjustment. Now this has worked remarkably well and it also works with 5.1. Does it mean that SoundTouch is aware of the audio channel layout? Nope. Does SoundTouch support the new Avisynth ChannelMask for audio? Nope. Nonetheless it gets it right and there's one very simple reason: any multi channel mode is actually a stereo mode under the hood. This means that if you actually have a stereo stream, SoundTouch will perform the speed up + pitch adjustment on left and right at the same time and it will keep them in phase with one another, thus producing a correct output. If you feed it with a 5.1 input, it will take 2ch at a time and perform it as if it was stereo. This works well 'cause it will apply the same logic to keep the channels in phase, so you'll have:

FL FR -> in phase
CC LFE -> in phase
LS RS -> in phase

The same goes if you feed a 5.1+2.0 stream made as SoundTouch will filter them as pairs once again:

FL FR -> in phase
CC LFE -> in phase
LS RS -> in phase
Left Right -> in phase

This also works for 7.1 when you have

FL FR -> in phase
CC LFE -> in phase
SL SR -> in phase
LS RS -> in phase

What if you have a 5.1 and another 5.1? No problem, once again it will filter them at pairs and therefore produce the right result:

FL FR -> in phase
CC LFE -> in phase
LS RS -> in phase
FL FR -> in phase
CC LFE -> in phase
LS RS -> in phase


I can't screenshot the Tektronix Waveform monitor 'cause it's literally a standalone hardware, but I can show you pictures of it:



As you can see at the bottom right, under the Lissajou graph, we have the phase between FL and FR and they're perfectly in phase with one another.

When I listened to it on my headsets by looking at my own VideoTek() - which is the closest thing I have to a Tektronix in software - I also didn't notice anything unusual through the entire movie:






The AVID ProTools guys were also happy and they also flagged the mono one as wrong and the multichannel one as good. Once I sent the multichannel file to QC, it also ended up with a QC PASS, so in this moment I'm as happy as Larry.



All is well what ends well.
When I have some time I'll update the TimeStretch() wiki page too to make the info readily available to everyone.

Last edited by FranceBB; 20th April 2024 at 16:20.
FranceBB is offline   Reply With Quote
Old 20th April 2024, 10:08   #7  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,369
The old fashion way of creating PAL telecine consisting of "just" speed up things from 24fps to 25fps, resulting indeed on a slighty higher pitch, audible when you compare to audio audio reference, but not realy audible without the reference (exception could be concert/music, or someone you know realy well and perfectly know the voice) is not enough ?
It was done for decades, and several decades ago, they didn't have all this digital audio processing, and the PAL telecine was just a basic simple speed-up, and people have watched the movies on TV for decades without noticing it. The PAL DVDs were the same.

Just simple question, as, on the time (at least a decade ago also...) i was doing my own anime PAL DVD from NTSC japanese DVDs, doing a reverese telecine to retreive original film frame and then doing PAL telecine, i tried some of the digital process, result was bad from my point of view, and so used basic usual speed-up.
__________________
My github.
jpsdr is offline   Reply With Quote
Old 20th April 2024, 12:37   #8  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
I wouldn't have any issues with a slightly elevated pitch, but the problem is that when you receive a movie you gotta have the major (i.e the production studio) sign off your processing. For instance, you couldn't just get a movie at 23.976, apply linear interpolation to 50p, divide it in fields to get 25i and encode it as it wouldn't get approved. For the same reason, blending it to 50p and dividing it in fields wouldn't work. Typically the way those things work is that you receive the master file, encode it once to a TX Ready file, then you send it back to the major who gave you the original master file and they either approve or reject the encode. Once they approve it, you become a trusted broadcaster and you're good to encode all the subsequent files you receive on your own. Of course some majors are stricter than others, some want you to perform some things and some others want you to perform some other things, so it's never easy to please everyone. In this case, they specifically asked for speed up with pitch adjustment on both stereo and Dolby, hence the original question about the updated SoundTouch library. Streaming platforms are very lucky as they don't have to go through this process at all given that they can easily put out a 23.976fps movie just fine, a 25p one and a 29.970p program without worrying about frame rate conversion.
FranceBB is offline   Reply With Quote
Old 20th April 2024, 13:11   #9  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,369
If i said that, it's just because when i've tried, i just found the result absolutely horrible... Putting a slighty elevated pitch as something just wonderfull !
But again, it was at least 15 if not 20 years ago, so... Things are probably better now, at least, i hope for you.
__________________
My github.
jpsdr is offline   Reply With Quote
Old 20th April 2024, 13:17   #10  |  Link
qyot27
...?
 
qyot27's Avatar
 
Join Date: Nov 2005
Location: Florida
Posts: 1,445
Quote:
Originally Posted by tebasuna51 View Post
In the readme of Avs+:
- Updated: TimeStretch plugin with SoundTouch 2.1.3 (as of 07.Jan 2019)

But I don't know if work fine with 5.1+2.0
TimeStretch with a much newer version of SoundTouch:
https://forum.doom9.org/showpost.php...postcount=2734


Quote:
Originally Posted by FranceBB View Post
Does it mean that SoundTouch is aware of the audio channel layout? Nope. Does SoundTouch support the new Avisynth frame properties for audio? Nope.
The Channel Mask isn't a frame property. It's stuffed into the VideoInfo block where the rest of the clip properties are.
qyot27 is offline   Reply With Quote
Old 20th April 2024, 16:19   #11  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Quote:
Originally Posted by qyot27 View Post
The Channel Mask isn't a frame property. It's stuffed into the VideoInfo block where the rest of the clip properties are.
Ah! Gotcha. Yep yep, there it is with GetChannelMask() and IsChannelMaskKnown(). Nice.

About using the version of SoundTouch shipped with the system, I know that you can do it with Linux, but that's because the OS has a completely different approach where everything is shared across multiple programs, which makes sense, but also introduces some complexities in the sense that everything must be updated. I don't actually have anything against still including SoundTouch in Avisynth for Windows to be fair 'cause at least we're shipping a version that we know is gonna work perfectly. I mean, currently I can see that in the source we're including version 2.3.1 as you updated it last time. The currently available version of SoundTouch outside of Avisynth is version 2.3.3. So... you might make the argument that on Linux they could just get version 2.3.3 without waiting for a new Avisynth release, which is fine, but in my mind I wouldn't have updated it anyway as I would consider it "dangerous". I mean, if it's shipped with Avisynth it means that 2.3.1 has been tested and known to be working, while if I update to a new version I might incur into API changes that might break the TimeStretch() function interacting with it. Anyway, I think the current approach is fine.

p.s thank you for keeping this updated!

Last edited by FranceBB; 20th April 2024 at 16:24.
FranceBB is offline   Reply With Quote
Old 11th June 2024, 16:29   #12  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Hey guys, I faced a new issue.
Essentially I've got a new file that had 18 audio channels in it, namely 5.1 ITA 2.0 ITA 5.1 ORI 2.0 ORI and then Music and Effects 2.0 for a total of 18 channels (6+2+6+2+2 = 18).
I blindly ran it through TimeStretch() however it errored out with "Illegal number of channels".

I tested a bit and I realized that the maximum number of supported channels for TimeStretch() is 16, in fact this works:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)

#16 ch ok - more no
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

ConvertAudioToFloat()
TimeStretch(pitch=96)
but this fails:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)

#18 ch fail
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

ConvertAudioToFloat()
TimeStretch(pitch=96)

Since I was applying the pitch adjustment manually to an already speeded up content, I just divided the audio in "sections", applied the Pitch Adjustment individually to each track and then combined the whole thing back together:

Quote:
video=LWLibavVideoSource("BURN OUT.mxf")
ch1=LWLibavAudioSource("BURN OUT.mxf", stream_index=1)
ch2=LWLibavAudioSource("BURN OUT.mxf", stream_index=2)
ch3=LWLibavAudioSource("BURN OUT.mxf", stream_index=3)
ch4=LWLibavAudioSource("BURN OUT.mxf", stream_index=4)
ch5=LWLibavAudioSource("BURN OUT.mxf", stream_index=5)
ch6=LWLibavAudioSource("BURN OUT.mxf", stream_index=6)
ch7=LWLibavAudioSource("BURN OUT.mxf", stream_index=7)
ch8=LWLibavAudioSource("BURN OUT.mxf", stream_index=8)
ch9=LWLibavAudioSource("BURN OUT.mxf", stream_index=9)
ch10=LWLibavAudioSource("BURN OUT.mxf", stream_index=10)
ch11=LWLibavAudioSource("BURN OUT.mxf", stream_index=11)
ch12=LWLibavAudioSource("BURN OUT.mxf", stream_index=12)
ch13=LWLibavAudioSource("BURN OUT.mxf", stream_index=13)
ch14=LWLibavAudioSource("BURN OUT.mxf", stream_index=14)
ch15=LWLibavAudioSource("BURN OUT.mxf", stream_index=15)
ch16=LWLibavAudioSource("BURN OUT.mxf", stream_index=16)
ch17=LWLibavAudioSource("BURN OUT.mxf", stream_index=17)
ch18=LWLibavAudioSource("BURN OUT.mxf", stream_index=18)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18)

AudioDub(video, audio)

ConvertAudioToFloat()

Dolby_ITA=GetChannels(1,2,3,4,5,6).TimeStretch(pitch=96)
Stereo_ITA=GetChannels(7,8).TimeStretch(pitch=96)
Dolby_ORI=GetChannels(9,10,11,12,13, 14).TimeStretch(pitch=96)
Stereo_ORI=GetChannels(15,16).TimeStretch(pitch=96)
Mute=GetChannels(17,18).TimeStretch(pitch=96)

MergeChannels(Dolby_ITA, Stereo_ITA, Dolby_ORI, Stereo_ORI, Mute)

#FL ITA FR ITA CC ITA LFE ITA LS ITA RS ITA
#Left ITA Right ITA
#FL ORI FR ORI CC ORI LFE ORI LS ORI RS ORI
#Left ORI Right ORI
#Music and Effects

but this made me think about how many other times I might be facing this, so I tried to use the following logic with a for cycle:


Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#18 ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

my_channel_number=(HasAudio)?AudioChannels:0


#Divide channels in stereo pairs and apply pitch adjustment
for (i = 1, my_channel_number-1, 2) {

GetChannels(i, i+1)
ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)

}
however it fails with "attempted to request a channel that didn't exist".
This is because this logic is FLAWED.
Effectively, if I do the above what's gonna happen is that my CH.1-2 will become "last" and therefore when it tries to access CH.3-4 it will fail.
At that point I thought "well, I could just use "video" in "GetChannels" like:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#18 ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

my_channel_number=(HasAudio)?AudioChannels:0

video=last


#Divide channels in stereo pairs
for (i = 1, my_channel_number-1, 2) {


GetChannels(video, i, i+1)
ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)

}
but this is also flawed as I end up with just CH.17-18.


Now, to understand this, when I replace GetChannels(i, i+1) thingie with Subtitle() it prints the right channels.
In other words:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#18 ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

my_channel_number=(HasAudio)?AudioChannels:0


#Divide channels in stereo pairs and apply pitch adjustment
for (i = 1, my_channel_number-1, 2) {

Subtitle(String(i), x=8+i*30)

}



As we can see, we get 1, 3, 5, 7, 9, 12, 13, 15, 17, which means that in theory GetChannels(i, i+1) should translate to:

GetChannels(1,2), GetChannels(3,4), GetChannels(5,6), GetChannels(7,8), GetChannels(9,10), GetChannels(11,12), GetChannels(13,14), GetChannels(15,16), GetChannels(17,18).

Indeed if I use:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#18 ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

my_channel_number=(HasAudio)?AudioChannels:0


#Divide channels in stereo pairs and apply pitch adjustment
for (i = 1, my_channel_number-1, 2) {

Subtitle(String(i), x=8+i*30, y=0)
Subtitle(String(i+1), x=8+i*30, y=30)

}
I can clearly see all the channels couples, namely CH.1-2 CH.3-4 CH.5-6 CH.7-8 CH.9-10 CH.11-12 CH.13-14 CH.15-16 CH.17-18.



The problem however is that in the very moment in which I use "GetChannels()" then I get two channels to filter up but then I don't know how to add all the two channels I divided in pairs back together to get the 18 channels as part of the loop.
FranceBB is offline   Reply With Quote
Old 11th June 2024, 17:03   #13  |  Link
richardpl
Guest
 
Posts: n/a
The whole idea of time-stretchng and/or pitch-adjustment for >1 channel audio is going to fail horribly unless all channels are independent.
  Reply With Quote
Old 11th June 2024, 17:33   #14  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,433
Quote:
Originally Posted by FranceBB View Post
The problem however is that in the very moment in which I use "GetChannels()" then I get two channels to filter up but then I don't know how to add all the two channels I divided in pairs back together to get the 18 channels as part of the loop.
How about something like this (untested):
Code:
result = video.KillAudio()
for (i = 1, my_channel_number-1, 2) {
  GetChannels(video, i, i+1)
  ResampleAudio(48000)
  ConvertAudioToFloat()
  TimeStretch(96)
  ResampleAudio(48000)
  result = MergeChannels(result, last)
} 
return result
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 11th June 2024, 17:36   #15  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Quote:
Originally Posted by richardpl View Post
The whole idea of time-stretchng and/or pitch-adjustment for >1 channel audio is going to fail horribly unless all channels are independent.
Yes if I have a multi channel and I filter it individually as mono it will not keep them in phase and therefore I'll have problems, however if I filter them as stereo pairs it's gonna work.

This is because TimeStretch() can work in two modes: mono mode and stereo mode.

By default, if it's fed with 1 single channel, then it works in mono mode, while if it's fed with 2 or more channels it works in stereo mode.

For instance, here it's working in mono mode:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ResampleAudio(48000)
ConvertAudioToFloat()

ch1=GetChannel(1).TimeStretch(96).ResampleAudio(48000)
ch2=GetChannel(2).TimeStretch(96).ResampleAudio(48000)

MergeChannels(ch1, ch2)
while here it's working in stereo mode:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
Of course what you're saying is true and indeed working in mono mode should be avoided for multi-channel tracks 'cause in that case TimeStretch() won't know that they're actually stereo and therefore won't keep them in phase, thus leading to some potentially bad results.
This means that stereo mode is always desired unless you have unrelated tracks.

Now, suppose you have a 5.1 track, then this is gonna work:

Quote:
ColorBars(848, 480, pixel_type="YV12")

# Creating 6 fake channels
ch12=GetChannels(1,2)
MergeChannels(ch12, ch12, ch12)

ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
'cause under the hood it's actually doing this:

Quote:
ColorBars(848, 480, pixel_type="YV12")

# Creating 6 fake channels
ch12=GetChannels(1,2)
MergeChannels(ch12, ch12, ch12)

filtered_ch12=GetChannels(1,2).ResampleAudio(48000).ConvertAudioToFloat().TimeStretch(96).ResampleAudio(48000)
filtered_ch34=GetChannels(3,4).ResampleAudio(48000).ConvertAudioToFloat().TimeStretch(96).ResampleAudio(48000)
filtered_ch56=GetChannels(5,6).ResampleAudio(48000).ConvertAudioToFloat().TimeStretch(96).ResampleAudio(48000)

MergeChannels(filtered_ch12, filtered_ch34, filtered_ch56)
This works 'cause it's actually keeping FL FR in phase, CC LFE in phase, LS RS in phase.

This can scale all the way up to 16 channels, in fact this works

Quote:
ColorBars(848, 480, pixel_type="YV12")

# Creating 16 fake channels
ch12=GetChannels(1,2)
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
however as soon as I add one more fake pair, like 18 channels, I get an error:

Quote:
ColorBars(848, 480, pixel_type="YV12")

# Creating 18 fake channels
ch12=GetChannels(1,2)
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)



What I'm trying to do then is to divide the tracks in stereo pairs myself and for that I've created the for cycle above.
Now, the problem I'm facing is to get the filtered stereo pairs from CH.1-2 all the way up to CH.17-18 out of the for cycle.

My latest attempt has been the following one:

Quote:
#Creating fake video
ColorBars(848, 480, pixel_type="YV12")

#Grabbing the fake stereo
ch12 = GetChannels(1, 2)

#Generate 18ch fake audio to simulate an actual scenario
audio18ch = MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

#Save a few variables as audio channels, frame rate and length in frames
my_channel_number = (HasAudio) ? AudioChannels : 0
my_fps=FrameRate()
my_length=FrameCount()

video = last

#Create a placeholder clip that I'll use to extract the filtered audios
audio = BlankClip(length=my_length, fps=my_fps, audio_rate=48000, channels=0)

#Divide channels in stereo pairs and process them
for (i = 1, my_channel_number - 1, 2) {
stereo_pair = GetChannels(video, i, i + 1)
processed_pair = stereo_pair.ResampleAudio(48000).ConvertAudioToFloat().TimeStretch(96).ResampleAudio(48000)

#Merge the processed pairs back into the placeholder I created outside of the for cycle
audio = MergeChannels(audio, processed_pair)
}

#Merge the processed audio back with the video
final_output = AudioDub(video, audio)

return final_output


The problem is that once again I'm getting a clip with 2 audio channels instead of the 18 filtered channels.

So... how do I get the 18 channels I filtered in the for cycle out of the cycle and into the final result?

I'm sure I'm doing something stupid and it's gonna be obvious to you guys, but I'm really struggling with this...
FranceBB is offline   Reply With Quote
Old 11th June 2024, 17:53   #16  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,433
Quote:
Originally Posted by FranceBB View Post
I'm sure I'm doing something stupid and it's gonna be obvious to you guys, but I'm really struggling with this...
Your solution is similar to mine posted a few minutes earlier, but has a small error in the script.
Quote:
audio18ch = MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

#Save a few variables as audio channels, frame rate and length in frames
my_channel_number = (HasAudio) ? AudioChannels : 0
Here 'last' is still the ColorBars source, so AudioChannels is just 2.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 11th June 2024, 17:56   #17  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Quote:
Originally Posted by Gavino View Post
How about something like this (untested):
Code:
result = video.KillAudio()
for (i = 1, my_channel_number-1, 2) {
  GetChannels(video, i, i+1)
  ResampleAudio(48000)
  ConvertAudioToFloat()
  TimeStretch(96)
  ResampleAudio(48000)
  result = MergeChannels(result, last)
} 
return result

Thank you so much!

I tested it with:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#create 18ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)


#Check the number of audio channels
my_channel_number=(HasAudio)?AudioChannels:0

video=last


result = video.KillAudio()
for (i = 1, my_channel_number-1, 2) {
GetChannels(video, i, i+1)
ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
result = MergeChannels(result, last)
}
return result

and initially it basically said that I couldn't use MergeChannels() at the end 'cause you can't merge a clip without audio with the one that has audio, therefore I changed it to:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#create 18ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)


#Check the number of audio channels
my_channel_number=(HasAudio)?AudioChannels:0
my_fps=FrameRate()
my_length=FrameCount()

video=last
my_mute_audio = BlankClip(length=my_length, fps=my_fps, audio_rate=48000, channels=0)
my_mute_video=AudioDub(video, my_mute_audio)


result = my_mute_video
for (i = 1, my_channel_number-1, 2) {
GetChannels(video, i, i+1)
ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
result = MergeChannels(result, last)
}

return result


And it worked!!




Thank you so much, Gavino! I owe you a beer!
If you were here I would have offered you one straight away!





I really love this community and I'm so happy to be part of it.
FranceBB is offline   Reply With Quote
Old 11th June 2024, 18:12   #18  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Uh, small revision, basically when you're using MergeChannels() with different sample types, it will merge to the lowest sample type instead of the highest one, therefore I changed the BlankClip to sample_type="float" like so:

Quote:
ColorBars(848, 480, pixel_type="YV12")

ch12=GetChannels(1,2)
#create 18ch
MergeChannels(ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12, ch12)

m_clip=trim(0, 50)

#Convert audio to 32bit float
ConvertAudioToFloat(m_clip)


#Check the number of audio channels, framerate and frame length of the clip
my_channel_number=(HasAudio)?AudioChannels:0
my_fps=FrameRate()
my_length=FrameCount()

video=last

#Create a blank audio to save all the filtered audios
my_mute_audio = BlankClip(length=my_length, fps=my_fps, audio_rate=48000, channels=0, sample_type="float")
my_mute_video=AudioDub(video, my_mute_audio)

#Divide the audio in stereo pairs and perform pitch adjustment
m_clip = my_mute_video
for (i = 1, my_channel_number-1, 2) {
GetChannels(video, i, i+1)
ResampleAudio(48000)
ConvertAudioToFloat()
TimeStretch(96)
ResampleAudio(48000)
m_clip = MergeChannels(m_clip, last)
}

#save the results and return the final clip
return m_clip

so that the output is 32bit float.
Now it truly is perfect.
FranceBB is offline   Reply With Quote
Old 18th September 2024, 22:45   #19  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,040
Good news everyone!
The developer of the SoundTouch library pushed the limit up from 16 channels to 32 channels, so now it's just a matter of integrating the new SoundTouch version in Avisynth and you won't need to use the workaround above to divide the channels into stereo pairs.

Check here for the relevant commit: Link
FranceBB is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:20.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.