I'm doing some simple simple programs with libsndfile and currently and trying to find a way to print silence in an audio file- other than muting the out of another file. Ostensibly, I'm making a drum machine.
At the given moment, I am only able to write the length of an inputed audio file and append them onto each other if I so choose.
Would love to have some more insight on this seemingly super simple task.. or a slap in the face if it is actually so simple.
Thanks!
Silence in an audio file is simply a bunch of consecutive zero valued samples.
To insert N frames of silence at the current write postion of a file is as simple as:
void sf_insert_silence (SNDFILE *file, int channels, int frames)
{ short silence [frames * channels];
memset (silence, 0, sizeof (silence));
sf_writef_short (sndfile, silence, frames);
}
Related
I'm learning about audio with openal and trying to load ogg files into memory so I can play them with openal. I have been searching for a library to load ogg files and the best one I found was this one, it has no dependences. But the documentation is messy and I can't find a decent tutorial-example online.
All I want to know is how to load an ogg and get something that I can actually send to a openal buffer.
Q: If I have this call:
stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output);
it should decode "filename" and store the data into "output". So I can send it to openal right?
It's not lack of research, after hours of reading I can't really get how it works. If there's another library to load ogg files easily then please let me know.
Thanks!
Have you tried it? What results/error did you get? Perhaps something like this:
int channels;
int sample_rate;
short * output;
int rc = stb_vorbis_decode_filename("somefile.ogg", &channels, &sample_rate, &output);
if (rc == -1) fprintf(stderr, "oops\n");
In file text.txt I have this sentenc:
"Příliš žluťoučký kůň úpěl ďábelské ódy."
(I think Windows uses Windows-1250 code page to represent this text.)
In my program I save it to a buffer
char string[1000]
and render string with ttf to SDL_Surface *surface
surface = TTF_RenderText_Blended(font, string, color);
/*(font is true type and support this text)*/
But it gives me not correct result:
I need some reputation points to post images
so I can only describe that ř,í,š,ž,ť,ů,ň,ď are not displayed correctly.
Is it possible to use ttf for rendering this sentence correctly?
(I tried also TTF_RenderUTF8_Blended, TTF_RenderUNICODE_Solid... with worse result.)
The docs for TTF_RenderText_Blended say that it takes a Latin-1 string (Windows-1252) - this will be why it isn't working.
You'll need to convert your input text to UTF-8 and use RenderUTF8, or to UTF-16 and use RenderUNICODE to ensure it is interpreted correctly.
How you do this depends on what platform your app is targeted to - if it is Windows, then the easiest way would be to use the MultiByteToWideChar Win32 API to convert it to UTF-16 and then use the TTF_RenderUNICODE_Blended to draw it.
My solution will be this:
Three input files. In first file there will be a set of symbols from czech alphabet.
Second file will be sprite bitmap file where graphic symbols will be sorted in the
same order as in first file. In my program symbols from third input file will be compared with symbols from first file and right section of sprite will be copied on sreen one by one.
I will leave out sdl_ttf. It has some advantages and disadvantages but I think it will work for my purposes.
Thanks for all responses
I am a mechanical engineer who has only limited knowledge in C programming. I wrote some code in order to make simulations, and I want to visualize the simulation results. At the moment I am using Dev-C for writing my codes. With fopen and fprintf commands I generate a .dat file which includes the results. Then I open GNUPLOT program and import my .dat file to plot the results. This takes time and I have to wait till the end of the simulation. Is there an easy way to connect my plotter with Dev-C, so my plotter starts plotting data during the simulation? Any library or etc. ?
Since you already know gnuplot, the simplest thing to do may be to just call gnuplot from your program and pipe the data to it:
FILE *gnuplot = popen("gnuplot", "w");
fprintf(gnuplot, "plot '-'\n");
for (i = 0; i < count; i++)
fprintf(gnuplot, "%g %g\n", x[i], y[i]);
fprintf(gnuplot, "e\n");
fflush(gnuplot);
I've been using PLPlot for plotting from C and have found it both effective and easy. It's cross platform, open source, and supports a rich array of plot capabilities. I'd recommend having a look at the examples to get started.
OK, one solution, as you are writing out to a file, would be to just make a system() call when you write out to the file, and call gnuplot.
But, that means you should change the filename each time, but I fear if you do that that it won't look correct, since you are sending small amounts of data each time.
http://www.gnu.org/software/libc/manual/html_node/System-Calls.html
I have never used gnuplot, but if you look at this page (http://gnuplot-tricks.blogspot.com/) you may find some tricks that would enable this to work well.
But, I think, unless you are going to plot everything yourself, and skip gnuplot, then you may just need to wait, as you are.
You may find the C interface to gnuplot may help you:
http://ndevilla.free.fr/gnuplot/
pbPlots is very easy to use and works with all C compilers.
Download pbPlots.c/h and supportLib.c/h from the github page and include them in your build.
Here is a complete example that will produce a plot in a PNG-file.
#include "pbPlots.h"
#include "supportLib.h"
int main(){
double x [] = {-1, 0, 1, 2, 3, 4, 5, 6};
double y [] = {-5, -4, -3, -2, 1, 0, 1, 2};
RGBABitmapImageReference *imageRef = CreateRGBABitmapImageReference();
DrawScatterPlot(imageRef, 600, 400, x, 8, y, 8);
size_t length;
double *pngData = ConvertToPNG(&length, imageRef->image);
WriteToFile(pngData, length, "plot.png");
return 0;
}
There are a lot more options available, these are described on the github page.
There is a extensive library called DISLIN for scientific purpose. Avaliable even in Fortran language.
You can check examples in official website.
You can obtain it freely in DISLIN Homepage
I had a wee look around to see what other people have done regarding real-time plotting in gnuplot, and found this:
http://users.softlab.ntua.gr/~ttsiod/gnuplotStreaming.html
There's a little Perl script that can drive the plotting, and you just pipe your information in.
Since your data is being written to file, you may want to tail -f yourdata.dat and pipe that into the real-time plotter.
Also, because you're using the stdio file calls, you'd need to flush regularly (by calling fflush)
Obviously your simulation would be running in the background or in another shell. That way you could break out of the plotting at any time without interrupting the simulation.
Hope that's of some use to you.
I'm a relatively decent Java programmer, but completely new to C. Thus some of these functions, pointers, etc are giving me some trouble...
I'm trying to create an archive file (I'm basically re-writing the ar sys call). I can fstat the files I want, store the necessary information into a struct I've defined. But now comes my trouble. I want to write the struct to the archive file. So I was thinking I could use sprintf() to put my struct into a buffer and then just write the buffer.
sprintf(stat_buffer, "%s", file_struct);
write(fd, stat_buffer, 60);
This doesn't appear to work. I can tell the size of the archive file is increasing by the desired 60 bytes, but if I cat the file, it prints nonsense.
Also, trying to write the actual contents of the file isn't working either...
while (iosize = read(fd2, text_buffer, 512) > 0) {
write(fd, text_buffer, iosize);
if (iosize == -1) {
perror("read");
exit(1);
}
}
I'm sure this is a relatively easy fix, just curious as to what it is!
Thanks!
%s is used to print string. So sprint will stop when it will meet a \0 character.
Instead, you could directly write your structure to your file. write(fd, &file_struct, sizeof(filestruct)); but you wont be able to read it with a cat call. You still can, from another unarchiver program, read the file content and store it to a structure read(fd, &filestruct, sizeof(filestruct));
This system is not perfect anyways, because it will store the structure using your computer endianess and wont be portable. If you want to do it right, check out the ar file format specification.
I want to write audio data to stdout, preferably using libsndfile. When I output WAV to /dev/stdout I manage to write the header, but then I get an error
Error : could not open file : /dev/stdout
System error : Illegal seek.
I assume this is related to http://www.mega-nerd.com/libsndfile/FAQ.html#Q017, some file formats cannot be written without seeks. However, when I try to output SF_FORMAT_AU | SF_FORMAT_PCM_16 instead, I still get the same Illegal seek error.
Are there any audio file formats that can be written completely without seeking?
I'm using Linux.
EDIT: It might be obvious, but RAW format works (without seeking). Unfortunately I need a format that has meta information like sample rate.
You should finish reading that FAQ... the link you give us has all the answers.
However, there is at least one file format (AU) which is specifically designed to be written to a pipe.
So use AU instead of WAV.
Also make sure that you open the SNDFILE object with sf_open_fd, and not sf_open_virtual (or sf_open):
SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo,
void *user_data) ;
If you use sf_open_fd, then libsndfile will use fstat to determine whether the file descriptor is a pipe or a regular file. If you use sf_open_virtual or sf_open, it will assume that the file is seekable. This appears to be a flaw in libsndfile, but you should be using sf_open_fd anyway.
Footnote: Don't open /dev/stdout to get standard output; it is already open and there is no need to open it again. Use file descriptor STDOUT_FILENO.
Ended outputting an "infinite" wav header, and then writing raw PCM data for as long as the audio lasts. Not really valid, but most players seem to understand anyway.
The wav header is here, in case anyone wants it: https://gist.github.com/1428176
You could write to a temp file (perhaps in /tmp), let the libsnd seek to modify the .wav(RIFF) header of the temp file, and then, after libsnd has closed the file, stream the temp file out to stdout.