
Originally Posted by
stampede
declare the function in header "generate_sine.h":
// generate_sine.h
#include something
extern void generate_sine( const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
// generate_sine.h
#include something
extern void generate_sine( const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
To copy to clipboard, switch view to plain text mode
and put the implementation in "generate_sine.cpp" (without the "static" keyword).
Add the sources to .pro file.
Then include "generate_sine.h" in "main.cpp" or wherever else you want to use the method.
Hi,
I tried this, it didn't work. Still getting the same error:
undefined reference to `wave::generate_sine(_snd_pcm_channel_area const*, unsigned long, int, double*)
undefined reference to `wave::generate_sine(_snd_pcm_channel_area const*, unsigned long, int, double*)
To copy to clipboard, switch view to plain text mode
generate_sine.cpp:
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <cstdlib>
#include <string.h>
#include <cstring>
#include <sched.h>
#include <errno.h>
#include <getopt.h>
#include <alsa/asoundlib.h>
#include <sys/time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
static const char *device = "plughw:0,0"; // playback device
static snd_pcm_format_t format = SND_PCM_FORMAT_S16; // sample format- change to 24-bit
static unsigned int rate = 96000; // stream rate
static unsigned int channels = 128; // count of channels
static unsigned int buffer_time = 500000; // ring buffer length in us
static unsigned int period_time = 100000; // period time in us
static double freq; // sinusoidal wave frequency in Hz
static int verbose = 0; // verbose flag
static int resample = 1; // enable alsa-lib resampling
static int period_event = 0; // produce poll event after each period
static snd_pcm_sframes_t buffer_size;
static snd_pcm_sframes_t period_size;
static snd_output_t *output = NULL;
static double ampl;
static snd_pcm_t *h;
static double amplitude;
int generate_sine(const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase)
{
static double max_phase = 2. * M_PI;
double phase = *_phase;
double step = max_phase*freq/(double)rate;
unsigned char *samples[channels];
int steps[channels];
unsigned int chn;
int format_bits = snd_pcm_format_width(format);
unsigned int maxval = (1 << (format_bits - 1)) - 1;
int bps = format_bits / 8; /* bytes per sample */
int phys_bps = snd_pcm_format_physical_width(format) / 8;
int big_endian = snd_pcm_format_big_endian(format) == 1;
int to_unsigned = snd_pcm_format_unsigned(format) == 1;
int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
format == SND_PCM_FORMAT_FLOAT_BE);
float amplitude_scale = amplitude/8.56;
/* verify and prepare the contents of areas */
for (chn = 0; chn < channels; chn++) {
if ((areas[chn].first % 8) != 0) {
printf("areas[%i].first == %i, aborting...\n", chn, areas[chn].first);
exit(EXIT_FAILURE);
}
samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
if ((areas[chn].step % 16) != 0) {
printf("areas[%i].step == %i, aborting...\n", chn, areas[chn].step);
exit(EXIT_FAILURE);
}
steps[chn] = areas[chn].step / 8;
samples[chn] += offset * steps[chn];
}
/* fill the channel areas */
while (count-- > 0) {
union {
float f;
int i;
} fval;
int res, i;
if (is_float) {
fval.f = amplitude_scale * sin(phase) * maxval;
res = fval.i;
} else
res = amplitude_scale * sin(phase) * maxval;
if (to_unsigned)
res ^= 1U << (format_bits - 1);
for (chn = 0; chn < channels; chn++) {
/* Generate data in native endian format */
if (big_endian) {
for (i = 0; i < bps; i++)
*(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
} else {
for (i = 0; i < bps; i++)
*(samples[chn] + i) = (res >> i * 8) & 0xff;
}
samples[chn] += steps[chn];
}
phase += step;
if (phase >= max_phase)
phase -= max_phase;
}
*_phase = phase;
}
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <cstdlib>
#include <string.h>
#include <cstring>
#include <sched.h>
#include <errno.h>
#include <getopt.h>
#include <alsa/asoundlib.h>
#include <sys/time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
static const char *device = "plughw:0,0"; // playback device
static snd_pcm_format_t format = SND_PCM_FORMAT_S16; // sample format- change to 24-bit
static unsigned int rate = 96000; // stream rate
static unsigned int channels = 128; // count of channels
static unsigned int buffer_time = 500000; // ring buffer length in us
static unsigned int period_time = 100000; // period time in us
static double freq; // sinusoidal wave frequency in Hz
static int verbose = 0; // verbose flag
static int resample = 1; // enable alsa-lib resampling
static int period_event = 0; // produce poll event after each period
static snd_pcm_sframes_t buffer_size;
static snd_pcm_sframes_t period_size;
static snd_output_t *output = NULL;
static double ampl;
static snd_pcm_t *h;
static double amplitude;
int generate_sine(const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase)
{
static double max_phase = 2. * M_PI;
double phase = *_phase;
double step = max_phase*freq/(double)rate;
unsigned char *samples[channels];
int steps[channels];
unsigned int chn;
int format_bits = snd_pcm_format_width(format);
unsigned int maxval = (1 << (format_bits - 1)) - 1;
int bps = format_bits / 8; /* bytes per sample */
int phys_bps = snd_pcm_format_physical_width(format) / 8;
int big_endian = snd_pcm_format_big_endian(format) == 1;
int to_unsigned = snd_pcm_format_unsigned(format) == 1;
int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
format == SND_PCM_FORMAT_FLOAT_BE);
float amplitude_scale = amplitude/8.56;
/* verify and prepare the contents of areas */
for (chn = 0; chn < channels; chn++) {
if ((areas[chn].first % 8) != 0) {
printf("areas[%i].first == %i, aborting...\n", chn, areas[chn].first);
exit(EXIT_FAILURE);
}
samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
if ((areas[chn].step % 16) != 0) {
printf("areas[%i].step == %i, aborting...\n", chn, areas[chn].step);
exit(EXIT_FAILURE);
}
steps[chn] = areas[chn].step / 8;
samples[chn] += offset * steps[chn];
}
/* fill the channel areas */
while (count-- > 0) {
union {
float f;
int i;
} fval;
int res, i;
if (is_float) {
fval.f = amplitude_scale * sin(phase) * maxval;
res = fval.i;
} else
res = amplitude_scale * sin(phase) * maxval;
if (to_unsigned)
res ^= 1U << (format_bits - 1);
for (chn = 0; chn < channels; chn++) {
/* Generate data in native endian format */
if (big_endian) {
for (i = 0; i < bps; i++)
*(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
} else {
for (i = 0; i < bps; i++)
*(samples[chn] + i) = (res >> i * 8) & 0xff;
}
samples[chn] += steps[chn];
}
phase += step;
if (phase >= max_phase)
phase -= max_phase;
}
*_phase = phase;
}
To copy to clipboard, switch view to plain text mode
generate_sine.h:
#ifndef GENERATE_SINE_H
#define GENERATE_SINE_H
#include <alsa/asoundlib.h>
#include <QMainWindow>
#include <QObject>
extern void generate_sine(const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
#endif // GENERATE_SINE_H
#ifndef GENERATE_SINE_H
#define GENERATE_SINE_H
#include <alsa/asoundlib.h>
#include <QMainWindow>
#include <QObject>
extern void generate_sine(const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
#endif // GENERATE_SINE_H
To copy to clipboard, switch view to plain text mode
wave.pro:
QT += core gui
TARGET = Wave
TEMPLATE = app
SOURCES += main.cpp\
wave.cpp \
generate_sine.cpp
HEADERS += wave.h \
generate_sine.h
LIBS += -lasound
FORMS += wave.ui
QT += core gui
TARGET = Wave
TEMPLATE = app
SOURCES += main.cpp\
wave.cpp \
generate_sine.cpp
HEADERS += wave.h \
generate_sine.h
LIBS += -lasound
FORMS += wave.ui
To copy to clipboard, switch view to plain text mode
Added after 20 minutes:

Originally Posted by
stampede
declare the function in header "generate_sine.h":
// generate_sine.h
#include something
extern void generate_sine( const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
// generate_sine.h
#include something
extern void generate_sine( const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase );
To copy to clipboard, switch view to plain text mode
and put the implementation in "generate_sine.cpp" (without the "static" keyword).
Add the sources to .pro file.
Then include "generate_sine.h" in "main.cpp" or wherever else you want to use the method.
Hey thanks for the reply. This does allow me to call it in other files, but it doesn't let me call it under the on_pushButton_clicked() function. It gives me the error:
undefined reference to `wave::generate_sine(_snd_pcm_channel_area const*, unsigned long, int, double*)
undefined reference to `wave::generate_sine(_snd_pcm_channel_area const*, unsigned long, int, double*)
To copy to clipboard, switch view to plain text mode
Bookmarks