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");
Related
I am using Matlab to generate a large matrix, and I want to use it in C.
How can I read Matlab's .mat file in C?
If it is possible, please answer how?
Supposedly Matlab provides its own API to access such files from C:
Read and write MAT files. I haven't used it myself, so I don't know how straightforward this is.
If you really want to access the binary data, a search engine came up with this PDF file, matfile_format.pdf, which describes the entire format. This is definitely not an easy solution.
You can easily read such files in Python however, see this topic. Reading a file this way and writing it again in a format that's easy for you to use in C seems like a good solution.
matOpen (C)
C Syntax
#include "mat.h"
MATFile *matOpen(const char *filename, const char *mode);
filename
Name of file to open.
mode
File opening mode.
Here there are examples and explanations.
Here there are all the link for MAT-file API.
I recommend to read and study the examples.
If just text is enough...
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *pf;
pf = fopen("something.m", "r");
int buffer;
while (buffer != EOF)
{
buffer = getc(pf);
printf("%c", buffer);
}
}
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);
}
I have read many, many threads about streaming images over IP in OpenCV 2.3.1, but I still cannot get my program to work.
I downloaded IP Webcam for Android from https://market.android.com/details?id=com.pas.webcam&hl=en, and recently learned OpenCV to retrieve images from my Android phone camera.
Its built-in manual said that the image from the phone camera can be located at http://the.phone.ip.address:8080/shot.jpg. I have opened it from browser several times and it always looks fine. I also built OpenCV manually, with FFmpeg support.
So far I've tried
CvCapture* webcam = cvCaptureFromFile("http://192.168.1.220:8080/shot.jpg");
but it returns NULL and outputs
[image2 # 0xd701e0]Could not find codec parameters (Video: mjpeg, yuv420p)
I also tried replacing http with rtsp, but it still doesn't work. I also tried to replace the url with some other image url (one direct link to random image from Google Images, and one from localhost) and it always kills with a segfault.
Here's my full source
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char* argv[])
{
CvCapture* webcam = cvCaptureFromFile("http://192.168.1.220:8080/shot.jpg");
if(!webcam)
{
fprintf(stderr, "cannot open webcam\n");
return 1;
}
IplImage* img = cvQueryFrame(webcam);
if(!img)
{
fprintf(stderr, "cannot get image\n");
return 1;
}
cvNamedWindow("test", CV_WINDOW_AUTOSIZE);
cvShowImage("test", img);
cvWaitKey(0);
cvReleaseImage(&img);
/**/ cvReleaseCapture(&webcam); /**/
cvDestroyWindow("test");
return 0;
}
Can OpenCV really read images over IP, or am I missing something?
I'm not specifically familiar with openCV, but having spent a minute looking at the docs, two things jump out at me:-
First off, your're not dealing with a true video stream here: your android app just makes the current JPEG capture available and you have to continually re-sample it. Because it's an Image, not a Video, you should use cvLoadImage() instead.
Second, you're passing a URL, not a filename. You'll need a way to use HTTP to fetch the image to a local file before you try opening it with openCV.
I'd suggest you save a snapshot of the JPEG file locally from your browser, and then try getting your code working with that. Once you have it working from a local file, try adding the HTTP fetching stuff.
While it would be /awesome/ if that was supported, it doesn't appear to be. Note that OSes handle opening files differently from URLs (obviously) so it's not something that would be supported by default - you can't fopen() a URL. If OpenCV specifically did support it, it would be possible, but I have some evidence that they do not:
Read image from URL into OpenCV states it is not possible, and solves the problem by using an HTTP stream
This forum post from 2010 also suggests that it is not supported
This email from 2005 has a response that says the same thing.
Here's what you can do:
Download the image some other way - perhaps by using a system() call to wget, perhaps by using a library to download the file into memory
At least one source says you may use Processing's loadImage() to load from a URL.
Further searching on Roddy answer makes that I've made things work for me.
Unfortunatelly it's not nice and windows only solution. But only way to get jpg from this application is to fetch http in some way. There are many libs which can help for example libcurl, boost::asio.
I've used urlmon.lib to make things work for me:
#inlcude <opencv2\opencv.hpp>
#include <UrlMon.h>
#include <tchar.h>
#pragma comment(lib,"urlmon.lib")
int main()
{
for(;;)
{
HRESULT hr = URLDownloadToFile(NULL,_T("http://192.168.1.104:8080/shot.jpg"),
_T("D:/test.jpg"),0,NULL);
IplImage *test = cvLoadImage("D:/test.jpg");
cvShowImage("test",test);
cvWaitKey(30);
}
}
This application can also stream mjpg as I've suggested in comments. OpenCV VideoStream seems to have option to read from it as suggested Stream live video in openCv from localHost port (http://192.168.1.1:8080) and OpenCV with Network Cameras .
I've tried also this solution but get mp3 header missing. I hope that someone provide some answer with using videofeed from this application.
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.
This might seem like a simple question.
But I have been looking for an XML parser to use in one of my applications that is running on Linux.
I am using Expat and have parsed my XML file by reading one in. However, the output is the same as the input.
This is my file I am reading in:
<?xml version="1.0" encoding="utf-8"?>
<books>
<book>
<id>1</id>
<name>Hello, world!</name>
</book>
</books>
However, after I have passed this, I get exactly the same as the output. It makes me wonder what the parser is for?
Just one more thing. I am using Expat. Which seems quite difficult to use. My code is below: This reads in a file. But my application will have to parse a buffer that will be received by a socket, and not from a file. Is there any samples of this that anyone has?
int parse_xml(char *buff)
{
FILE *fp;
fp = fopen("mybook.xml", "r");
if(fp == NULL)
{
printf("Failed to open file\n");
return 1;
}
/* Obtain the file size. */
fseek (fp, 0, SEEK_END);
size_t file_size = ftell(fp);
rewind(fp);
XML_Parser parser = XML_ParserCreate(NULL);
int done;
memset(buff, 0, sizeof(buff));
do
{
size_t len = fread(buff, 1, file_size, fp);
done = len < sizeof(buff);
if(XML_Parse(parser, buff, len, done) == XML_STATUS_ERROR)
{
printf("%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
return 1;
}
}
while(!done);
fclose(fp);
XML_ParserFree(parser);
return 0;
}
Expat is an even-driven parser. You have to write code to deal with tags, attributes etc. and then register the code with the parser. There is an article here which describes how to do this.
Regarding reading from a socket, depending on your platform you may be able to treat the socket like like a file handle. Otherwise, you need to do your own reading from the socket and then pass the data to expat explicitly. There is an API to do this. However, I'd try to get it working with ordinary files first.
It took a while to wrap my head around XML parsing (though I do it in Perl, not C). Basically, you register callback functions. The parser will ping your callback for each node and pass in a data structure containing all kinds of juicy bits (like plaintext, any attributes, children nodes, etc). You have to maintain some kind of state information--like a hash tree you plug stuff into, or a string that contains all the guts, but none of the XML.
Just remember that XML is not linear and it doesn't make much sense to parse it like a long hunk of text. Instead, you parse it like a tree. Good luck.
Instead of expat, you might want to have a look at libxml2, which is probably already included in your distribution. It's a lot more powerful than expat, and gives you all sorts of goodies: DOM (tree mode), SAX (streaming mode), XPath (indispensable to do anything complex with XML IMHO) and more. It's not as lightweight as expat, but it's a lot easier to use.
Well, you chose the most complicated XML parser (event-driven parsers are more difficult to handle). Why Expat and not libxml?