EN VI

gcc error: a function-definition is not allowed here before ‘{’ token?

2024-03-10 15:00:04
gcc error: a function-definition is not allowed here before ‘{’ token

No, I can't figure out what's wrong. At least when I've tried to take the function out of main and paste it before main, I get more errors then before.

I get the error:

error: a function-definition is not allowed here before ‘{’ token void draw_spectrum(Display *display, Window window, double *magnitudes) {

With this code:

 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <alsa/asoundlib.h>  // For audio capture
#include <X11/Xlib.h>       // For X11 graphics
#include "kiss_fft.h"       // For FFT calculations


int main(int argc, char*argv[]) {

/// Initialize audio capture and X11 display:

// Open audio device
snd_pcm_t *pcm_handle;
snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0);
// Set audio parameters (sample rate, channels, etc.)
snd_pcm_set_params(pcm_handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 48000, 1, 500000);

// Open X11 display
Display *display = XOpenDisplay(NULL);
Window window = XCreateSimpleWindow(display, window, 100, 100, 800, 600, 1, BlackPixel(display, DefaultScreen(display)), WhitePixel(display, DefaultScreen(display))); //finish later...display, parent, x, y, width, height, border_width, border, background
XMapWindow(display, window);

/// Create buffers for audio samples and FFT output:

#define FFT_SIZE 1024  // Adjust as needed
kiss_fft_cfg cfg = kiss_fft_alloc(FFT_SIZE, 0, 0, 0);
kiss_fft_cpx in[FFT_SIZE];
kiss_fft_cpx out[FFT_SIZE];


    // Map magnitudes to visual representation (lines and bars)
void draw_spectrum(Display *display, Window window, double *magnitudes) {
  // Get window dimensions
  int width, height;
  XWindowAttributes wa;
  XGetWindowAttributes(display, window, &wa);
  width = wa.width;
  height = wa.height;

  // Calculate bar width and spacing
  int bar_width = width / (FFT_SIZE / 2 + 1);
  int bar_spacing = 1; // Adjust spacing as needed

  GC gc = XCreateGC(display, window, 0, NULL); // Create a graphics context

  // Clear the window (optional)
  XSetForeground(display, gc, WhitePixel(display, DefaultScreen(display)));
  XFillRectangle(display, window, gc, 0, 0, width, height);

  // Set drawing color for the bars
  XSetForeground(display, gc, BlackPixel(display, DefaultScreen(display)));

  // Draw bars for each magnitude value
  for (int i = 0; i < FFT_SIZE / 2 + 1; i++) {
    int bar_height = (int) (magnitudes[i] * height / 256); // Scale magnitude to screen height
    XFillRectangle(display, window, gc,
                   i * (bar_width + bar_spacing), height - bar_height,
                   bar_width, bar_height);
  }

  XFreeGC(display, gc); // Release the graphics context
}


    // Handle events and refresh display
    XNextEvent(display, ...);
    XFlush(display);
}


/// Main loop:

while (1) {
    // Capture audio samples
    snd_pcm_readi(pcm_handle, in, FFT_SIZE);

    // Apply window function (Hann window)
    for (int i = 0; i < FFT_SIZE; i++) {
        in[i].r *= 0.5 * (1 - cos(2 * M_PI * i / (FFT_SIZE - 1)));
    }

    // Perform FFT
    kiss_fft(cfg, in, out);

    // Calculate magnitudes
    double magnitudes[FFT_SIZE / 2 + 1];
    for (int i = 0; i < FFT_SIZE / 2 + 1; i++) {
        magnitudes[i] = sqrt(out[i].r * out[i].r + out[i].i * out[i].i);
    }

    // Map magnitudes to visual representation (lines and bars)
    draw_spectrum(display, window, magnitudes);

/// Clean up:

// Close audio device
snd_pcm_close(pcm_handle);

// Close X11 display
XDestroyWindow(display, window);
XCloseDisplay(display);

return 0;
}

How do I solve this?

Solution:

The standard C doesn't allow to put function definition inside function definition (nesting function definition).

In this case, no local variables of the function main is referenced from the function draw_spectrum, so you can fix this by moving the definition of draw_spectrum before main.

Also there looks an extra } in the function draw_spectrum and a } is missing around the Main loop. You should apply proper indentation to your code to make it easier to find this kind of mistake.

Another point is that using ... in function call like XNextEvent(display, ...); doesn't look valid. You should replace this with proper thing.

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login