2019-01-26 15:16:42 (edited by philip_bennefall 2019-02-16 15:53:03)

This is not really game related as such so feel free to move it to a more appropriate place, but I am posting it here initially since it does relate to audio and development at least.

A few weeks ago I wrote a little vocoder. It's pretty basic but I personally think the output sounds OK. I was thinking of cleaning it up and posting it on GitHub as a ready to use C library for easy integration into other projects. Would there be any interest in this?

I posted some audio examples of the vocoder in my speech synthesis thread in the Off Topic forum, but am reposting them here.

This is the original speech I used:
https://www.dropbox.com/s/wdskvp98zpnuu … h.wav?dl=1

And this is how the vocoder sounds when run through a triad chord played by a sawtooth:
https://www.dropbox.com/s/1pxxlhq14kaq6 … l.wav?dl=1

You can also shift the modulator formants to make it sound larger or smaller, like this:
https://www.dropbox.com/s/mokw4va4vwoz7 … r.wav?dl=1

And if you are using a carrier which can be easily stretched, like a basic waveform, you can get the speech to play slower or faster like so:
https://www.dropbox.com/s/19vrtok5ftqgg … w.wav?dl=1

Would love to get some feedback, and am curious to see whether any of you think it would be useful as an open source library.

Edit:
The vocoder has now been released and can be found at the following URL:
https://github.com/blastbay/voclib

For those just wishing to use it, I have built a Windows binary of the command line shell which operates on Wave files. It can be found here:
https://www.dropbox.com/s/3a8hr9rbe5ghe … 1.exe?dl=1


The shell is a command line aplication. You can print the usage by invoking it with no arguments. Do not click it in explorer; there is no GUI.

Enjoy!

Kind regards,

Philip Bennefall

2019-01-26 17:26:05

Hey does ti work with BGT? If not I will just use python.

Ivan

2019-01-26 17:46:59

If I make some high level functions that operate on Wave files it would be possible to call those from BGT, but it would only be able to do offline processing. I'm sure there are plenty of similar things in Python if that is your environment of choice; the package I would be releasing would be aimed at C and C++ developers primarily.

Kind regards,

Philip Bennefall

2019-01-26 18:31:20

what is a vocoder?

regards
Remi

Thumbs up

2019-01-26 18:39:23

Awesome job. Look forward to try it myself. When you are programing, you seem to most often program fun and interesting stuff. Keep up the great work.

Best regards
T-m

Internet access is a human right.

Thumbs up

2019-01-26 18:52:35

at philip, i would suggest also to make a dll for it so it's not made just for c and c++ programmers.

Thumbs up

2019-01-26 19:57:46

Sure, all sorts of wrappers could be made including a VST plugin, a regular old dll, a command line application etc etc. I plan to have at least a command line application included in the repository if I do release the vocoder.

Kind regards,

Philip Bennefall

2019-01-26 21:32:59

I'd be happy to make a wrapper for it sometime when its released. If its possible, anyway... some DLLs are so simple to use in Python that you don't need to make wrappers for them. smile

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 04:20:29

Yeah, that makes sense. I was thinking of doing a low level API where you simply pass it two streams of floats and get another stream back with the result, as well as a higher level API which allows you to feed it Wave files. With the low level API you would process very small chunks, so you could generate the carrier however you wanted. Based on MIDI input, for instance.

Kind regards,

Philip Bennefall

2019-01-27 05:03:03

@9, I'd have a lot of fun working with a wrapper like that. Passing in a float* (that's really a float[] or float[][] or more) from Python is a bitch (I'm not really sure how I'd do that). Its even harder with structures, from what I've found.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 05:11:19

In this case it would be a float[] array with a single dimension, where the samples are stored in an interleaved fashion. For stereo that means the first float is the left channel of sample frame 0, the second float is the right channel of frame 0, the third float is the left channel of frame 1, and so on.

But yes, Wave files would be a lot easier if all you're wanting to do is process some audio offline. It will be included for sure.

Kind regards,

Philip Bennefall

2019-01-27 05:52:47 (edited by Ethin 2019-01-27 05:53:18)

@11, I've always had trouble figuring out how you pass arrays to C functions. At least, in structures, ctypes doesn't allow me to use ctypes.Array in ctypes.Structures. I could try a list... tat I haven't tried.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 06:17:17

I have decided to go ahead and release the vocoder. I will make it public domain, under the Unlicense (http://unlicense.org). It will take a little while for me to prepare and clean up the code; stay tuned.

Kind regards,

Philip Bennefall

2019-01-27 06:34:31

Nice! I just figured out why I couldn't figure out ctypes arrays -- messing with this will be fun!

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 06:52:33

hello philip.
will you release it as an vst plugin also?

Thumbs up

2019-01-27 07:22:43

I am not sure, it all depends on how much time I have available to mess around with it. If I do, it will certainly not look pretty.

Kind regards,

Philip Bennefall

2019-01-27 07:28:37

hi,
@philip_bennefall, that is really cool to have such a great lib
@ethin, you should declare the variable as ctypes.c_float*4 for float[4]
if you want to declare a pointer, you can do ctypes.POINTER(ctypes.c_float)

bitcoin address: 1LyQ3hziMC2DTnCtgM3V1zfuZ73P3CYT9P

2019-01-27 08:04:39 (edited by Ethin 2019-01-27 08:05:41)

@17, that's the problem though -- when I have a C function that writes to an array, I don't know how large the array will be since its of arbitrary length. So I can't do that. Like, if I have a function:
void write_to_array(float *array);
And float* is the array, I have no way of determining beforehand the size of the array.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 08:20:46

A C API always has to give you a way to know the length of an array. Passing a pointer on its own like that, with no way to know how large the memory block needs to be, is a broken API. I will not be doing that smile

Kind regards,

Philip Bennefall

2019-01-27 10:00:47 (edited by Ethin 2019-01-27 10:03:12)

@19, true. The FMOD docs (for example) in the FMOD_Channel_GetMixMatrix() do say that "The matrix size will generally be the size of the number of channels in the current speaker mode." However, I note here the use of the word "generally" -- it doesn't mean it is always the size. Now that I know how to create arrays like that with the multiplication operator, I can determine the number of input and output channels and create an array to hold the mix matrix. Post 18 said that at the time I "had no way of determining the size of the array" -- now I do! smile

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-27 12:03:13

for example,

int function(float* data, int length);

is correct and you can work with them!.
also if the api doesn't have a way of allocating the new data in memory (like malloc / free, new / delete etc), and you are going to allocate that by your own, the function should have a way of determining the length

bitcoin address: 1LyQ3hziMC2DTnCtgM3V1zfuZ73P3CYT9P

2019-01-27 22:18:07

@21, yeah, the docs that I have indicate the size I can allocate.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-28 05:02:41

The vocoder has now been released and can be found at the following URL:
https://github.com/blastbay/voclib

For those just wishing to use it, I have built a Windows binary of the command line shell which operates on Wave files. It can be found here:
https://www.dropbox.com/s/mfr8j3gmlcwh9 … l.exe?dl=1

The shell is a command line aplication. You can print the usage by invoking it with no arguments. Do not click it in explorer; there is no GUI.

Enjoy!

Kind regards,

Philip Bennefall

2019-01-28 05:35:47 (edited by Ethin 2019-01-28 05:36:02)

I like how its a C header file. Very nice. Not sure if I can easily write a wrapper for Python for it though -- I thought it'd be a DLL or DSO that ctypes could look at. Worth a try in something like boost.python though...

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.

Thumbs up

2019-01-28 05:49:13

It is definitely possible to turn it into a dynamic library. I have not yet made a high level API for it though, so it currently only works on raw float arrays. If/when I do write the high level API it will be in a separate file, as to not introduce external dependencies for Wave file I/O in the core implementation.

For now, the shell is a good starting point for high level operations.

Kind regards,

Philip Bennefall