Csound Csound-dev Csound-tekno Search About

[Csnd] manipulation of pv data

Date2011-11-04 19:07
FromDennis Raddle
Subject[Csnd] manipulation of pv data
Okay, so as previously described,  my goal is to do some custom analysis and manipulation of pv data, specifically to analyze a source that is close to harmonic (such as a piano note) and modify the playback so it is exactly harmonic. I'm thinking of two options--- either using the pvs opcodes, or reading a pvoc-ex file generated by pvanal.

With both options I need some help understanding the format of the output.

Option 1: pvanal and pvoc-ex file

I see documentation of the pvoc-ex file format here: <http://www.cs.bath.ac.uk/~jpff/NOS-DREAM/researchdev/pvocex/pvocex.html> However, just when it gets to the "data" section of the file, it stops giving detailed description of the data format. It just says the data is a series of frames, but I can't find any description of the format of a frame.

Option 2: pvs opcodes

Using pvsanal, I can generate an fsig. Then use pvsftw, I can write that at k -rate to a function table. I can save the table. However, I am not sure what to make of the data. There is both "amplitude data" and "Frequency data." Do I need only the amplitude data? Does this correspond to fft bins? Do I look for bins which cover the region of each harmonic?


Date2011-11-04 19:56
FromRichard Dobson
SubjectRe: [Csnd] manipulation of pv data
On 04/11/2011 19:07, Dennis Raddle wrote:
..
>
> I see documentation of the pvoc-ex file format here:
>  However,
> just when it gets to the "data" section of the file, it stops giving
> detailed description of the data format. It just says the data is a
> series of frames, but I can't find any description of the format of a frame.
>

Good point - I should add that to the page. Frames are simple blocks of 
floats, interleaving (in the most common formnat) amplitude and 
frequency values. Each pair of values constitutes a "bin". The size of a 
frame is (N/2) + 1 bins, ranging nominally from DC to Nyquist (but the 
lowest bins can have negative frequencies). So, with an FFT size of 
1024, each frame has 513 bins of amp/freq pairs. Only 32bit floats are 
currently supported in PVOC-EX, simply for reasons of file size. So in 
this case, there are 513 *2 * 4 bytes per frame. As the code is based on 
CARL pvoc, the amplitudes have the same range as that, as noted on the 
page, 0.0-1.0. Other pvocs may use different ranges. The pvs table 
opcodes write the amplitude and frequency values into different tables.


> Option 2: pvs opcodes
>
> Using pvsanal, I can generate an fsig. Then use pvsftw, I can write that
> at k -rate to a function table. I can save the table. However, I am not
> sure what to make of the data. There is both "amplitude data" and
> "Frequency data." Do I need only the amplitude data? Does this
> correspond to fft bins? Do I look for bins which cover the region of
> each harmonic?
>

The standard approach is to use the amplitude data, find each peak 
(hopefully involving at least four bins, could easily be more) and 
calculate the "true' peak from those values; then read the corresponding 
frequency value. It would make sense for your application to use Csound 
rather than process analysis files directly.  There is also the option 
of using Victor's partial track opcodes, since that is really what you 
want anyway.

Richard Dobson


Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"

Date2011-11-04 20:07
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data


On Fri, Nov 4, 2011 at 12:56 PM, Richard Dobson <richarddobson@blueyonder.co.uk> wrote:
The standard approach is to use the amplitude data, find each peak (hopefully involving at least four bins, could easily be more) and calculate the "true' peak from those values; then read the corresponding frequency value. It would make sense for your application to use Csound rather than process analysis files directly.  There is also the option of using Victor's partial track opcodes, since that is really what you want anyway.

Richard Dobson


What are the partial track opcodes? 

So the data that the pvs opcodes write is not simply the bins of an fft (the frequencies are equally spaced), but frequency/amplitude pairs in which the frequencies are not evenly spaced?



Date2011-11-04 20:09
Fromjpff@cs.bath.ac.uk
SubjectRe: [Csnd] manipulation of pv data
> Option 1: pvanal and pvoc-ex file
>
> I see documentation of the pvoc-ex file format here: <
> http://www.cs.bath.ac.uk/~jpff/NOS-DREAM/researchdev/pvocex/pvocex.html>
> However, just when it gets to the "data" section of the file, it stops
> giving detailed description of the data format. It just says the data is a
> series of frames, but I can't find any description of the format of a
> frame.


With option 1 you could us pvexport to get description of frame which is
basically magnitude/phase pairs for each bin

pvimport takes the same format nback, so you can edit in text mode

Not tried this for a while.  Option2 is probably better....
>




Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"

Date2011-11-04 21:27
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data
To reply to my own post, I discovered that it's easy to understand the amp/freq pairs created by pvsanal. The freqs cluster around the partials that I expect. It should be easy to read the total amplitude of each partial.

On Fri, Nov 4, 2011 at 1:07 PM, Dennis Raddle <dennis.raddle@gmail.com> wrote:


On Fri, Nov 4, 2011 at 12:56 PM, Richard Dobson <richarddobson@blueyonder.co.uk> wrote:
The standard approach is to use the amplitude data, find each peak (hopefully involving at least four bins, could easily be more) and calculate the "true' peak from those values; then read the corresponding frequency value. It would make sense for your application to use Csound rather than process analysis files directly.  There is also the option of using Victor's partial track opcodes, since that is really what you want anyway.

Richard Dobson


What are the partial track opcodes? 

So the data that the pvs opcodes write is not simply the bins of an fft (the frequencies are equally spaced), but frequency/amplitude pairs in which the frequencies are not evenly spaced?




Date2011-11-04 21:35
FromRichard Dobson
SubjectRe: [Csnd] manipulation of pv data
On 04/11/2011 20:07, Dennis Raddle wrote:

>
> What are the partial track opcodes?
>

"partials", "trlowest" etc. The latter outputs amp  and freq ksigs of 
the lowest track - assuming that is a coherent fundamental, you can use 
that as the basis for controlling any oscillator with any arbitrary 
spectrum. But I realise these still may not be what you want, as you 
seem to want to read each frequency track and fix it to a harmonic of 
the fundamental, and that would appear to be something needing a 
dedicated opcode.

> So the data that the pvs opcodes write is not simply the bins of an fft
> (the frequencies are equally spaced), but frequency/amplitude pairs in
> which the frequencies are not evenly spaced?
>

The centre frequency (or if you like, its nominal frequency) of each bin 
is equally spaced. A non-linear distribution is what is called an 
"active research area" (e.g. "const-Q"). The frequency bunching I 
referred to is a consequence of the phase tracking of the phase vocoder 
(frequency being the rate of change of phase;  the underlying FFT is an 
entirely standard one.

I think for what you want to do it is still worth persevering with hetro 
(assuming it hasn't got completely broken over the years - I recall 
getting perfectly good analyses of a piano tone out of it).

I have put my old toy program (windows, GUI) "adsyn2ft" on my web site here:

http://people.bath.ac.uk/masrwd/adsyn2ft.zip

Basically, you load in a hetro file (with .ads or .het extension), 
select the time position you are interested in (for piano you will want 
a time when the partials have more or less stabilised, perhaps 10msecs 
in), set the number of partials, and click "generate ftable" - this 
writes a Csound GEN 10 function line, with just the amplitude values, to 
a text window from whence you can cut and copy to your score. Pass this 
ftable to any plain oscillator you choose, and set the fundamental 
frequency as you want. So you get a fixed tone with at least the moral 
satisfaction of knowing it was once a piano.  You can generate 
successively numbered ftables from arbitrary time positions, so 
conceivably you could "ftmorf" from one to another over the note to 
capture the essence of partial envelopes.

This program is 9 years old, assumes the hetro file format has not 
changed so as to break the program, and (to use the full technical term) 
was thrown together, so YMMV etc.

Richard Dobson




Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"

Date2011-11-04 21:56
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data


On Fri, Nov 4, 2011 at 2:35 PM, Richard Dobson <richarddobson@blueyonder.co.uk> wrote:
On 04/11/2011 20:07, Dennis Raddle wrote:


What are the partial track opcodes?


"partials", "trlowest" etc. The latter outputs amp  and freq ksigs of the lowest track - assuming that is a coherent fundamental, you can use that as the basis for controlling any oscillator with any arbitrary spectrum. But I realise these still may not be what you want, as you seem to want to read each frequency track and fix it to a harmonic of the fundamental, and that would appear to be something needing a dedicated opcode.

I don't need to do it in real time--so I can post-process. I don't think I need a dedicated opcode.


 

I think for what you want to do it is still worth persevering with hetro (assuming it hasn't got completely broken over the years - I recall getting perfectly good analyses of a piano tone out of it).


There are two problems with Hetro-- one is that the frequecies are messed up, so the output is bell-like rather than a (nearly) harmonic piano tone. The other problem is that all amplitudes above the 10 th partial (about 2500 Hz in my test) were zero. That means nothing in the output above 2500 Hz, which is bad (rolled-off sound). I tried every combination of input flags I could think of. I don't hold hope that I can solve it, but maybe a csound coder can fix it.

 
I have put my old toy program (windows, GUI) "adsyn2ft" on my web site here:

http://people.bath.ac.uk/masrwd/adsyn2ft.zip

Basically, you load in a hetro file (with .ads or .het extension), select the time position you are interested in (for piano you will want a time when the partials have more or less stabilised, perhaps 10msecs in), set the number of partials, and click "generate ftable" - this writes a Csound GEN 10 function line, with just the amplitude values, to a text window from whence you can cut and copy to your score. Pass this ftable to any plain oscillator you choose, and set the fundamental frequency as you want. So you get a fixed tone with at least the moral satisfaction of knowing it was once a piano.  You can generate successively numbered ftables from arbitrary time positions, so conceivably you could "ftmorf" from one to another over the note to capture the essence of partial envelopes.



I need an automated system because I want to read all partials up to the Nyquist of dozens of tones of different instruments (piano, strings, brass, and on). I've done this in the past by writing programs in Haskell or Python to generate and run the csound code and post-process the output. So far using pvs opcodes is going well.
 
Dennis


Date2011-11-05 01:35
FromRichard Dobson
SubjectRe: [Csnd] manipulation of pv data
On 04/11/2011 21:56, Dennis Raddle wrote:
..
>>
> There are two problems with Hetro-- one is that the frequecies are messed
> up, so the output is bell-like rather than a (nearly) harmonic piano tone.
> The other problem is that all amplitudes above the 10 th partial (about
> 2500 Hz in my test) were zero. That means nothing in the output above 2500
> Hz, which is bad (rolled-off sound). I tried every combination of input
> flags I could think of. I don't hold hope that I can solve it, but maybe a
> csound coder can fix it.
>

I just ran a short test using a C4 (~263Hz) piano sample (Bosendorfer). 
You may get better results with hetro if you set a very low starting 
frequency (such as 20). The piano sound has not only the string itself, 
but the very low-frequency noisy mechanical strike of the key, and this 
would appear to throw hetro out, if the base frequency (-f option) is 
set to the nominal fundamental. With, say, -f200 I do get a bell sound 
as you describe; but at -f20 I get the correctly pitched harmonic tone, 
but with a heavily damped (soft) attack.  Of course that hammer/frame 
noise is what makes the sounds distinctly that of a physical piano 
(without it, it is more like a classic electronic piano such as a 
Rhodes), but it is likely getting in the way of the strictly pitched 
tone analysis you are looking for. Poissibly, choosing a higher pitched 
sample will help - easier to filter out most of the mechanical noise 
component beforehand.

The acoustic piano may therefore be uniquely difficult for hetro; I 
would expect other instruments to fare better.


..
>
> I need an automated system because I want to read all partials up to the
> Nyquist of dozens of tones of different instruments (piano, strings, brass,
> and on). I've done this in the past by writing programs in Haskell or
> Python to generate and run the csound code and post-process the output. So
> far using pvs opcodes is going well.
>

If hetro can be made to work, I have the original command-line version 
of adsyn2ft which would work in that context.


Richard Dobson



Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"

Date2011-11-05 09:38
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data


On Fri, Nov 4, 2011 at 6:35 PM, Richard Dobson <richarddobson@blueyonder.co.uk> wrote:
If hetro can be made to work, I have the original command-line version of adsyn2ft which would work in that context.




I got it working splendidly well with the pvsanal and pvsftw opcodes. I captured the data, constructed envelopes on the first N partials (where I could choose N to be anything), and played it back with a separate oscili for each partial. Sounded like a piano (but more like an electric piano). It should be a very useful musical instrument. Now I'm experimenting with writing the same format file as generated by Hetro and using adsyn, to simplify the playback code.

Dennis
 

Date2011-11-05 23:15
FromOeyvind Brandtsegg
SubjectRe: [Csnd] manipulation of pv data
It would be interesting to look at the csd for this.
best
Oeyvind

2011/11/5 Dennis Raddle :
>
> I got it working splendidly well with the pvsanal and pvsftw opcodes. I
> captured the data, constructed envelopes on the first N partials (where I
> could choose N to be anything), and played it back with a separate oscili
> for each partial. Sounded like a piano (but more like an electric piano). It
> should be a very useful musical instrument.

Date2011-11-06 01:02
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data
Well, the csound code for playback was generated by a Haskell program, so it's probably not that interesting. The program put the envelopes (something like 50 of them for just one note) in f tables and generated all the data based on the output of a prior csound run with pvsanal and pvsftw, then put in the 50 pairs of lines that read the envelope and control the oscillator. I'm probably going to modify this to use adsyn.



On Sat, Nov 5, 2011 at 4:15 PM, Oeyvind Brandtsegg <oyvind.brandtsegg@ntnu.no> wrote:
It would be interesting to look at the csd for this.
best
Oeyvind

2011/11/5 Dennis Raddle <dennis.raddle@gmail.com>:
>
> I got it working splendidly well with the pvsanal and pvsftw opcodes. I
> captured the data, constructed envelopes on the first N partials (where I
> could choose N to be anything), and played it back with a separate oscili
> for each partial. Sounded like a piano (but more like an electric piano). It
> should be a very useful musical instrument.


--

Oeyvind Brandtsegg
Professor of Music Technology
NTNU
7491 Trondheim
Norway


Send bugs reports to the Sourceforge bug tracker
           https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"



Date2011-11-06 11:57
Frompeiman khosravi
SubjectRe: [Csnd] manipulation of pv data
How did you extract the envelops? And how did you get the partials
from the fft data?

On 6 November 2011 01:02, Dennis Raddle  wrote:
> Well, the csound code for playback was generated by a Haskell program, so
> it's probably not that interesting. The program put the envelopes (something
> like 50 of them for just one note) in f tables and generated all the data
> based on the output of a prior csound run with pvsanal and pvsftw, then put
> in the 50 pairs of lines that read the envelope and control the oscillator.
> I'm probably going to modify this to use adsyn.
>
>
>
> On Sat, Nov 5, 2011 at 4:15 PM, Oeyvind Brandtsegg
>  wrote:
>>
>> It would be interesting to look at the csd for this.
>> best
>> Oeyvind
>>
>> 2011/11/5 Dennis Raddle :
>> >
>> > I got it working splendidly well with the pvsanal and pvsftw opcodes. I
>> > captured the data, constructed envelopes on the first N partials (where
>> > I
>> > could choose N to be anything), and played it back with a separate
>> > oscili
>> > for each partial. Sounded like a piano (but more like an electric
>> > piano). It
>> > should be a very useful musical instrument.
>>
>>
>> --
>>
>> Oeyvind Brandtsegg
>> Professor of Music Technology
>> NTNU
>> 7491 Trondheim
>> Norway
>>
>>
>> Send bugs reports to the Sourceforge bug tracker
>>            https://sourceforge.net/tracker/?group_id=81968&atid=564599
>> Discussions of bugs and features can be posted here
>> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe
>> csound"
>>
>
>


Send bugs reports to the Sourceforge bug tracker
            https://sourceforge.net/tracker/?group_id=81968&atid=564599
Discussions of bugs and features can be posted here
To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"


Date2011-11-06 21:55
FromDennis Raddle
SubjectRe: [Csnd] manipulation of pv data
> On Sun, Nov 6, 2011 at 3:57 AM, peiman khosravi <peimankhosravi@gmail.com> wrote:
> How did you extract the envelops? And how did you get the partials
> from the fft data?

Below is my "pvsanal" instrument. Notice it uses pvsftw to put the data in tables and uses ftsave to write them to disk every time new data is available. The filenames have the time in k-samples appended so they can be read and interpreted by my Haskell program.

Then to compute the envelopes I looked at the freq/ampl data. I summed the amplitude values of all bins close to each partial. If the fundamental is F, then to determine the value of Nth partial I looked at bins with frequencies "f" such that

  f is between  F*(N -1/2) and F(N + 1/2)

That gives one amplitude on the envelope (the time, as previously mentioned, came from the filename).



instr 2

inbins = 512
gi_a ftgen 0, 0, inbins, 10, 1
gi_f ftgen 0, 0, inbins, 10, 1

asig1 init 0
asig2 init 0
ktim init 0
   fin "../HetroFormat/pno-C4-trim.wav", 0, 0, asig1, asig2
asig = (asig1+asig2)/2

fsig  pvsanal asig, 1024, 256, 1024, 0
kflag pvsftw fsig, gi_a, gi_f


if kflag==0 kgoto contin

     ktim  timeinstk
     SfileNameA   sprintfk "/Temp/csound/tables/a%06d.txt", ktim
     SfileNameF   sprintfk "/Temp/csound/tables/f%06d.txt", ktim
     ftsavek SfileNameA, ktim, 1, gi_a
     ftsavek SfileNameF, ktim, 1, gi_f
contin:

endin