I am trying to embed Chicken Scheme into a C program, to generate sounds to be played with SDL2's audio system. I would have liked to use the sdl2 egg, but it does not seem to support Audio yet (despite the documentation mentioning the 'audio flag for the init! function).
At first, I was using SDL_QueueAudio from C, passing it a buffer that I had allocated in C and then filled in Scheme. This worked fine, passing a Sint16 * and size_t into Scheme, then using pointer-s16-set! from Scheme to fill it and returning a size_t to note how many cells were filled.
Then, when I realised that using the callback api for generating the audio was much better suited to this, I tried switching to it (having already used it before in C), only for the Scheme function to never be entered. Logging something in the callback function before the Scheme call worked, but logging directly within the Scheme function, or after the Scheme call, never happened.
I can only imagine that this is due to SDL2's audio callback running on a separate thread, and that messing with calling through to Scheme somehow. With this in mind, I tried calling CHICKEN_run(C_toplevel); from within the callback function, the first time that it was called, but that only resulted in a bus error.
So my question is: is there a way of calling embedded Chicken Scheme from SDL2's audio callback?
I am on macOs 10.13.6 High Sierra, with SDL2 and chicken both installed and up-to-date through Homebrew.
I compile with (as I said, this works fine when using the queue audio api):
csc code.c codescm.scm -embedded -o code -L -lSDL2
My simplified code is below:
#include <chicken.h>
#include "SDL2/SDL.h"
extern size_t fill_sound_buffer(Sint16 *buffer, size_t buffer_length);
void fill_sound_callback(void *user_data, Uint8 *stream, int stream_length)
{
// Logging here prints to the console
fill_sound_buffer((Sint16 *)stream, stream_length / 2);
// Logging here does not print to the console
}
void play(void)
{
SDL_AudioSpec audio_want;
SDL_zero(audio_want);
audio_want.freq = 44100;
audio_want.format = AUDIO_S16SYS;
audio_want.channels = 1;
audio_want.samples = 2048;
audio_want.callback = fill_sound_callback;
SDL_AudioSpec audio_have;
SDL_AudioDeviceID audio_device = SDL_OpenAudioDevice(NULL, 0, &audio_want, &audio_have, 0);
SDL_PauseAudioDevice(audio_device, 0);
SDL_Delay(5000);
// Logging here shows up after 5 seconds, but the program then continues to wait
SDL_CloseAudioDevice(audio_device);
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_AUDIO);
CHICKEN_run(C_toplevel);
play();
SDL_Quit();
return 0;
}
(import (chicken format)
(chicken foreign)
(chicken memory)
(chicken platform))
(define-external (fill_sound_buffer ((c-pointer short) buffer) (size_t buffer_length)) size_t
; This never prints when using the callback api
(printf "In Scheme~%")
; Removed the code that calculates a sine wave and fills the buffer with it, which works
0)
(return-to-host)
Related
I'm using PortAudio's callback API for designing a signal processing loopback library.
I'd like to add a branch that depends on a flag inside the callback, so like
int pa_callback(const void *inputuffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
if (do_something_flag) {
do_something(inputBuffer, outputBuffer, frameCount);
} else {
do_something_else(inputBuffer, outputBuffer, frameCount);
}
return paContinue;
}
Where do_something_flag is set elsewhere in my program at regular intervals.
The PortAudio callback documentation states:
Before we begin, it's important to realize that the callback is a
delicate place. This is because some systems perform the callback in a
special thread, or interrupt handler, and it is rarely treated the
same as the rest of your code. For most modern systems, you won't be
able to cause crashes by making disallowed calls in the callback, but
if you want your code to produce glitch-free audio, you will have to
make sure you avoid function calls that may take an unbounded amount
of time to execute. Exactly what these are depend on your platform but
almost certainly include the following: memory
allocation/deallocation, I/O (including file I/O as well as console
I/O, such as printf()), context switching (such as exec() or yield()),
mutex operations, or anything else that might rely on the OS. If you
think short critical sections are safe please go read about priority
inversion.
I don't care about the atomicity of the do_something_flag. That is, I don't care how many cycles it takes to get a correct value (within reason).
According to the documentation, it looks like I can't use mutexes for setting/reading that variable.
1) What are my options?
2) If I make it global and set it in another part of my program (another thread), what is the absolute worst that will happen? Again, I mean in terms of corrupting data to the point of program failure/etc.
Is there a right way to do this?
I'm not totally sure what you're exactly trying to do but I'm guessing it's what your title is asking about - "Changing a variable elsewhere".
Let's take this example: you have a variable frequency that changes over time. How do you access this? Well you have a generic pointer in the callback called userData. This can point to anything - a data structure, array, etc. I don't really remember how often the callback function gets called (it's pretty often... I wouldn't worry about speed) but the userData allows you to have variables that can be changed in your main thread while the pointer in the audio thread allows you to access it directly in the memory... My knowledge on thread safety isn't the best and sorry if that isn't the best explanation but I can at least show you how to do it through code (below).
This is how i usually do it but you don't need to do it yourself; I set a structure at the top of my file like so:
typedef struct {
float freq;
float vol;
}paData;
Obviously you'll initialize this somewhere in your code (probably in your main function call) and open the audio stream as such (data is of type paData):
/* Open audio stream */
err = Pa_OpenStream(&(*stream),
&inputParameters,
&outputParameters,
SAMPLE_RATE, bufSize, paNoFlag,
paCallback, &data);
After opening it you can have your callback like this:
static int pa_callback(const void *inputBffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
// cast data so we can use it
paData *data = (paData *)userData;
// what's our frequency?
printf("%f\n", data->freq);
/* Do something with your code here */
return paContinue;
}
Hope that helps.
A while ago I wrote a script in C that used the Windows API functions EnumWindows, SetWindowPos and SetForegroundWindow to automatically arrange windows (by title) in a particular layout that I commonly wanted.
Are there Linux equivalents for these functions? I will be using Kubuntu, so KDE-specific and/or Ubuntu-specific solutions are fine.
The best way to do this is either in the window manager itself (if yours supports extensions) or with the protocols and hints designed to support "pagers" (pager = any non-window-manager process that does window organization or navigation things).
The EWMH spec includes a _NET_MOVERESIZE_WINDOW designed for use by pagers. http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2731465
Raw Xlib or Xcb is pretty rough but there's a library called libwnck specifically designed to do the kind of thing you're talking about. (I wrote the original library long ago but it's been maintained by others forever.) Even if you don't use it, read the code to see how to do stuff. KDE may have an equivalent with KDE-style APIs I'm not sure.
There should be no need to use anything KDE or GNOME or distribution specific since the needed stuff is all spelled out in EWMH. That said, for certain window managers doing this as an extension may be easier than writing a separate app.
Using old school X calls directly can certainly be made to work but there are lots of details to handle there that require significant expertise if you want to iron out all the bugs and corner cases, in my opinion, so using a WM extension API or pager library would be my advice.
#andrewdotn has a fine answer there but you can do this old school as well fairly simply by walking the tree starting at the root window of the display using XQueryTree and fetching the window name with XFetchName then moving it with XMoveWindow. Here is an example that will list all the windows and if any are called 'xeyes' they get moved to the top left. Like most X programs, there is more to it and this should probably be calling XGetWindowProperty to fetch the _NET_WM_NAME extended window manager property but the example works ok as a starter. Compile with gcc -Wall -g -o demo demo.c -lX11
#include <X11/Xlib.h>
#include <stdio.h>
#include <string.h>
static int
EnumWindows(Display *display, Window window, int depth)
{
Window parent, *children;
unsigned int count = 0;
int r = 1, n = 0;
char *name = NULL;
XFetchName(display, window, &name);
for (n = 0; n < depth; ++n) putchar(' ');
printf("%08x %s\n", (int)window, name?name:"(null)");
if (name && strcmp("xeyes", name) == 0) {
XMoveWindow(display, window, 5, 5);
}
if (name) XFree(name);
if (XQueryTree(display, window, &window, &parent, &children, &count) == 0) {
fprintf(stderr, "error: XQueryTree error\n");
return 0;
}
for (n = 0; r && n < count; ++n) {
r = EnumWindows(display, children[n], depth+1);
}
XFree(children);
return r;
}
int
main(int argc, char *const argv[])
{
Display *display = NULL;
if ((display = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "error: cannot connect to X server\n");
return 1;
}
EnumWindows(display, DefaultRootWindow(display), 0);
XCloseDisplay(display);
return 0;
}
Yes, you can do this using the X Windows protocol. It’s a very low-level protocol so it will take some work. You can use xcb_query_tree to find the window to operate on, and then move it with xcb_configure_window. This page gives some details on how to do it. There’s a basic tutorial on using the library those functions come from, but you’ll probably want to Google for a better one.
It may seem daunting, but it’s not too bad. Here’s a 50-line C program that will move all your xterms 10px to the right:
#include <stdio.h>
#include <string.h>
#include <xcb/xcb.h>
void handle(xcb_connection_t* connection, xcb_window_t window) {
xcb_query_tree_reply_t *tree = xcb_query_tree_reply(connection,
xcb_query_tree(connection, window), NULL);
xcb_window_t *children = xcb_query_tree_children(tree);
for (int i = 0; i < xcb_query_tree_children_length(tree); i++) {
xcb_get_property_reply_t *class_reply = xcb_get_property_reply(
connection,
xcb_get_property(connection, 0, children[i], XCB_ATOM_WM_CLASS,
XCB_ATOM_STRING, 0, 512), NULL);
char* class = (char*)xcb_get_property_value(class_reply);
class[xcb_get_property_value_length(class_reply)] = '\0';
if (!strcmp(class, "xterm")) {
/* Get geometry relative to parent window */
xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(
connection,
xcb_get_geometry(connection, window),
NULL);
/* Move 10 pixels right */
uint32_t values[] = {geom->x + 10};
xcb_configure_window(connection, children[i],
XCB_CONFIG_WINDOW_X, values);
}
/* Recurse down window tree */
handle(connection, children[i]);
}
}
int main() {
xcb_connection_t *connection;
const xcb_setup_t *setup;
connection = xcb_connect(NULL, NULL);
setup = xcb_get_setup(connection);
xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup);
handle(connection, screen.data->root);
return 0;
}
There’s no error-checking or memory management, and what it can do is pretty limited. But it should be straightforward to update into a program that does what you want, or to turn it into a general-purpose helper program by adding command-line options to specify which windows to operate on and which operations to perform on them.
As it seems you are not looking specifically for a solution in code, but rather in a desktop environment, you need to take a look at one of the window managers that handle the window placement in such a desktop environment.
KDE's KWin's Window Attributes
Compiz (GNOME) has "Window Rules" and "Place Windows" in the CompizConfig Settings Manager application. See e.g. here
Openbox seems a lot harder to get right, although they link to a GUI tool at the bottom of this page.
The problem with using X directly is that X in itself knows nothing about your desktop environment (panels, shortcuts, etc.) and you'll have to compensate manually.
After googling for this, I'm surprised KDE is the only one that has a simple way to do this.
I have an Arduino project where I read data from a webserver.
I have an EthernetClient that reads the data character by character in a callback function.
My working code looks like (only the relevant parts):
void setup() {
Serial.begin(9600);
...
}
void loop() {
char* processedData = processData(callback); // this is in a external lib
}
boolean callback(char* buffer, int& i) {
...
if (Client.available()) {
char c = client.read();
buffer[i++] = c;
Serial.print(c);
}
...
}
This works without any problems (reading and processing the data), but when I remove Serial.begin(9600); and Serial.print(c); it stops working and I don't know why? The only thing changed is that the char c is not printed. What could be the problem?
A common reason why callback functions change their behavior when seemingly unrelated code is altered, is optimizer-related bugs.
Many embedded compilers fail to understand that a callback function (or an interrupt service routine) will ever be called in the program. They see no explicit call to that function and then assumes it is never called.
When the compiler has made such an assumption, it will optimize variables that are changed by the callback function, because it fails to see that the variable is changed by the program, between the point of initialization and the point of access.
// Bad practice example:
int x;
void main (void)
{
x=5;
...
if(x == 0) /* this whole if statement will get optimized away,
the compiler assumes that x has never been changed. */
{
do_stuff();
}
}
void callback (void)
{
x = 0;
}
When this bug strikes, it is nearly impossible to find, it can cause any kind of weird symptoms.
The solution is to always declare all file scope ("global") variables shared between main() and an interrupt/callback/thread as volatile. This makes it impossible for the compiler to make incorrect optimizer assumptions.
(Please note that the volatile keyword cannot be used to achieve synchronization nor does it guarantee any memory barriers. This answer is not in the slightest related to such issues!)
A guess: Because without the serial driver started, there is no data to process, and therefore your callback is not hit.
What were you hoping the serial callback to be doing in the absence of data?
Providing more information about Client and processData may help.
Developing iOS application which uses CoreAudio framework, I am dealing with IMHO nonsense behavior of SDL reg. playing audio. SDL plays audio in loop, and only way how to trigger playback is to call SDL_PauseAudio(0), and the only way how to stop it (without other side effects, which I won't talk about here) is to call SDL_PauseAudio(1). As far as I know.
What is the problem for me in SDL here? Simply - next call to SDL_PauseAudio(1) actually RESUMES the playback, causing the framework to play some mess *before asking for new sound data*. This is because of the way how SDL_CoreAudio.c implements the playback loop.
It means, that SDL does not implement STOP, it implements just PAUSE/RESUME and incorrectly manages audio processing. It means, that if you play sampleA, and want to play sampleB later on, you will hear also fragments of sampleA while expecting just to hear playback of sampleB.
If am wrong, please correct me.
If not, here's my diff, that I used to implement also STOP behavior: as soon as I finish playing sampleA, I call SDL_PauseAudio(2) so that playback loop quits and next call to SDL_PauseAudio(0) starts it again, this time by playing no mess from sampleA, but correctly playing just data from smapleB.
Index: src/audio/coreaudio/SDL_coreaudio.c
===================================================================
--- src/audio/coreaudio/SDL_coreaudio.c
+++ src/audio/coreaudio/SDL_coreaudio.c
## -250,6 +250,12 ##
abuf = &ioData->mBuffers[i];
SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize);
}
+ if (2 == this->paused)
+ {
+ // this changes 'pause' behavior to 'stop' behavior - next
+ // plyaing starts from beginning, i.e. it won't resume
+ this->hidden->bufferOffset = this->hidden->bufferSize;
+ }
return 0;
}
I am shamed that I edited SDL code, but I have no connection to authors and haven't found any help around. Well, it is strange for me, that no one seems to need STOP behavior in SDL?
A way around your issue is for instance to better manage your audio device with SDL. Here is what I suggest :
void myAudioCallback(void *userdata, Uint8 *stream, int len) { ... }
SDL_AudioDeviceID audioDevice;
void startAudio()
{
// prepare the device
static SDL_AudioSpec audioSpec;
SDL_zero(audioSpec);
audioSpec.channels = 2;
audioSpec.freq = 44100;
audioSpec.format = AUDIO_S16SYS;
audioSpec.userdata = (void*)myDataLocation;
audioSpec.callback = myAudioCallback;
audioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, &audioSpec, 0);
// actually start playback
SDL_PauseAudioDevice(audioDevice, 0);
}
void stopAudio()
{
SDL_CloseAudioDevice(audioDevice);
}
This works for me, the callback is not called after stopAudio() and no garbage is sent to the speaker either.
I've started to dig into the GLib documentation and discovered that it also offers a unit testing framework.
But how could you do unit tests in a procedural language? Or does it require to program OO in C?
Unit testing only requires "cut-planes" or boundaries at which testing can be done. It is quite straightforward to test C functions which do not call other functions, or which call only other functions that are also tested. Some examples of this are functions which perform calculations or logic operations, and are functional in nature. Functional in the sense that the same input always results in the same output. Testing these functions can have a huge benefit, even though it is a small part of what is normally thought of as unit testing.
More sophisticated testing, such as the use of mocks or stubs is also possible, but it is not nearly as easy as it is in more dynamic languages, or even just object oriented languages such as C++. One way to approach this is to use #defines. One example of this is this article, Unit testing OpenGL applications, which shows how to mock out OpenGL calls. This allows you to test that valid sequences of OpenGL calls are made.
Another option is to take advantage of weak symbols. For example, all MPI API functions are weak symbols, so if you define the same symbol in your own application, your implementation overrides the weak implementation in the library. If the symbols in the library weren't weak, you would get duplicate symbol errors at link time. You can then implement what is effectively a mock of the entire MPI C API, which allows you to ensure that calls are matched up properly and that there aren't any extra calls that could cause deadlocks. It is also possible to load the library's weak symbols using dlopen() and dlsym(), and pass the call on if necessary. MPI actually provides the PMPI symbols, which are strong, so it is not necessary to use dlopen() and friends.
You can realize many of the benefits of unit testing for C. It is slightly harder, and it may not be possible to get the same level of coverage you might expect from something written in Ruby or Java, but it's definitely worth doing.
At the most basic level, unit tests are just bits of code that execute other bits of code and tell you if they worked as expected.
You could simply make a new console app, with a main() function, that executed a series of test functions. Each test would call a function in your app and return a 0 for success or another value for failure.
I'd give you some example code, but I'm really rusty with C. I'm sure there are some frameworks out there that would make this a little easier too.
You can use libtap which provides a number of functions which can provide diagnostics when a test fails. An example of its use:
#include <mystuff.h>
#include <tap.h>
int main () {
plan(3);
ok(foo(), "foo returns 1");
is(bar(), "bar", "bar returns the string bar");
cmp_ok(baz(), ">", foo(), "baz returns a higher number than foo");
done_testing;
}
Its similar to tap libraries in other languages.
Here's an example of how you would implement multiple tests in a single test program for a given function that might call a library function.
Suppose we want to test the following module:
#include <stdlib.h>
int my_div(int x, int y)
{
if (y==0) exit(2);
return x/y;
}
We then create the following test program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
// redefine assert to set a boolean flag
#ifdef assert
#undef assert
#endif
#define assert(x) (rslt = rslt && (x))
// the function to test
int my_div(int x, int y);
// main result return code used by redefined assert
static int rslt;
// variables controling stub functions
static int expected_code;
static int should_exit;
static jmp_buf jump_env;
// test suite main variables
static int done;
static int num_tests;
static int tests_passed;
// utility function
void TestStart(char *name)
{
num_tests++;
rslt = 1;
printf("-- Testing %s ... ",name);
}
// utility function
void TestEnd()
{
if (rslt) tests_passed++;
printf("%s\n", rslt ? "success" : "fail");
}
// stub function
void exit(int code)
{
if (!done)
{
assert(should_exit==1);
assert(expected_code==code);
longjmp(jump_env, 1);
}
else
{
_exit(code);
}
}
// test case
void test_normal()
{
int jmp_rval;
int r;
TestStart("test_normal");
should_exit = 0;
if (!(jmp_rval=setjmp(jump_env)))
{
r = my_div(12,3);
}
assert(jmp_rval==0);
assert(r==4);
TestEnd();
}
// test case
void test_div0()
{
int jmp_rval;
int r;
TestStart("test_div0");
should_exit = 1;
expected_code = 2;
if (!(jmp_rval=setjmp(jump_env)))
{
r = my_div(2,0);
}
assert(jmp_rval==1);
TestEnd();
}
int main()
{
num_tests = 0;
tests_passed = 0;
done = 0;
test_normal();
test_div0();
printf("Total tests passed: %d\n", tests_passed);
done = 1;
return !(tests_passed == num_tests);
}
By redefining assert to update a boolean variable, you can continue on if an assertion fails and run multiple tests, keeping track of how many succeeded and how many failed.
At the start of each test, set rslt (the variables used by the assert macro) to 1, and set any variables that control your stub functions. If one of your stubs gets called more than once, you can set up arrays of control variables so that the stubs can check for different conditions on different calls.
Since many library functions are weak symbols, they can be redefined in your test program so that they get called instead. Prior to calling the function to test, you can set a number of state variables to control the behavior of the stub function and check conditions on the function parameters.
In cases where you can't redefine like that, give the stub function a different name and redefine the symbol in the code to test. For example, if you want to stub fopen but find that it isn't a weak symbol, define your stub as my_fopen and compile the file to test with -Dfopen=my_fopen.
In this particular case, the function to be tested may call exit. This is tricky, since exit can't return to the function being tested. This is one of the rare times when it makes sense to use setjmp and longjmp. You use setjmp before entering the function to test, then in the stubbed exit you call longjmp to return directly back to your test case.
Also note that the redefined exit has a special variable that it checks to see if you actually want to exit the program and calls _exit to do so. If you don't do this, your test program may not quit cleanly.
This test suite also counts the number of attempted and failed tests and returns 0 if all tests passed and 1 otherwise. That way, make can check for test failures and act accordingly.
The above test code will output the following:
-- Testing test_normal ... success
-- Testing test_div0 ... success
Total tests passed: 2
And the return code will be 0.
There is nothing intrinsically object-oriented about testing small pieces of code in isolation. In procedural languages you test functions and collections thereof.
If you are desperate, and you'd have to be desperate, I banged together a little C preprocessor and gmake based framework. It started as a toy, and never really grew up, but I have used it to develop and test a couple of medium sized (10,000+ line) projects.
Dave's Unit Test is minimally intrusive yet it can do some tests I had originally thought would not be possible for a preprocessor based framework (you can demand that a certain stretch of code throw a segmentation fault under certain conditions, and it will test it for you).
It is also an example of why making heavy use of the preprocessor is hard to do safely.
The simplest way of doing a unit test is to build a simple driver code that gets linked with the other code, and call each function in each case...and assert the values of the results of the functions and build up bit by bit...that's how I do it anyway
int main(int argc, char **argv){
// call some function
int x = foo();
assert(x > 1);
// and so on....
}
Hope this helps.
With C it must go further than simply implementing a framework on top of existing code.
One thing I've always done is make a testing module (with a main) that you can run little tests from to test your code. This allows you to do very small increments between code and test cycles.
The bigger concern is writing your code to be testable. Focus on small, independent functions that do not rely on shared variables or state. Try writing in a "Functional" manner (without state), this will be easier to test. If you have a dependency that can't always be there or is slow (like a database), you may have to write an entire "mock" layer that can be substituted for your database during tests.
The principle unit testing goals still apply: ensure the code under test always resets to a given state, test constantly, etc...
When I wrote code in C (back before Windows) I had a batch file that would bring up an editor, then when I was done editing and exited, it would compile, link, execute tests and then bring up the editor with the build results, test results and the code in different windows. After my break (a minute to several hours depending on what was being compiled) I could just review results and go straight back to editing. I'm sure this process could be improved upon these days :)
I use assert. It's not really a framework though.
You can write a simple minimalistic test framework yourself:
// test_framework.h
#define BEGIN_TESTING int main(int argc, char **argv) {
#define END_TESTING return 0;}
#define TEST(TEST_NAME) if (run_test(TEST_NAME, argc, argv))
int run_test(const char* test_name, int argc, char **argv) {
// we run every test by default
if (argc == 1) { return 1; }
// else we run only the test specified as a command line argument
for (int i = 1; i < argc; i++) {
if (!strcmp(test_name, argv[i])) { return 0; }
}
return 0;
}
Now in the actual test file do this:
#include test_framework.h
BEGIN_TESTING
TEST("MyPassingTest") {
assert(1 == 1);
}
TEST("MyFailingTest") {
assert(1 == 2);
}
END_TESTING
If you want to run all tests, execute ./binary without command line arguments, if you want to run just a particular test, execute ./binary MyFailingTest