rd_kafka_offsets_for_times() returns error -186 (Local: Invalid argument or configuration.) - librdkafka

I'm trying to get the offset (high watermark offset) for a partition using rd_kafka_offsets_for_times().
Here is a code snippet:
rd_kafka_topic_partition_t* pt0 = rd_kafka_topic_partition_new(topic, 0);
pt0->offset = 0;
pt0->metadata = 0;
pt0->metadata_size = 0;
pt0->opaque = 0;
pt0->err = 0;
pt0->_private = 0;
rd_kafka_topic_partition_list_t* partition_list = rd_kafka_topic_partition_list_new(1);
partition_list->elems = pt0;
rd_kafka_resp_err_t offsets_err = rd_kafka_offsets_for_times(rk, partition_list, 5000);
if (offsets_err != RD_KAFKA_RESP_ERR_NO_ERROR)
{
printf("ERROR: Failed to get offsets: %d: %s.\n", offsets_err,
rd_kafka_err2str(offsets_err));
}
else
{
printf("Successfully got offset.\n");
}
When I run it, I get this error:
ERROR: Failed to get offsets: -186: Local: Invalid argument or configuration.
How do I correct my code to be able to get the offset for the partition?

Need to use rd_kafka_topic_partition_list_add to add a topic partition to the topic partition list. For example:
rd_kafka_topic_partition_list_t* partition_list = rd_kafka_topic_partition_list_new(1);
rd_kafka_topic_partition_t* pt0 = rd_kafka_topic_partition_list_add(partition_list, topic, 0);
pt0->offset = ~0; // set to max integer value
rd_kafka_resp_err_t offsets_err = rd_kafka_offsets_for_times(rk, partition_list, 10000);
if (offsets_err != RD_KAFKA_RESP_ERR_NO_ERROR)
{
printf("ERROR: Failed to get offsets: %d: %s.\n", offsets_err, rd_kafka_err2str(offsets_err));
}
else
{
printf("Successfully got high watermark offset %d.\n", pt0->offset);
}

Related

FFmpeg filter config with aecho fails to configure all the links and formats - avfilter_graph_config

I am following the official tutorial of FFMpeg to create a filter chain. This tutorial shows how to pass data through a chain as:
The filter chain it uses is: * (input) -> abuffer -> volume ->
aformat -> abuffersink -> (output)
Here is my code - sorry for boiler code, it is just ffmpeg way :(
frame = av_frame_alloc();
filterGraph = avfilter_graph_alloc();
if (!frame) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not allocate memory for frame");
return;
}
if (!filterGraph) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor FXProcessor! %s", av_err2str(AVERROR(ENOMEM)));
return;
}
const AVFilter *abuffer;
const AVFilter *abuffersink;
AVFilterContext *aformat_ctx;
const AVFilter *aformat;
AVFilterContext *choisen_beat_fx_ctx;
const AVFilter *choisen_beat_fx;
/* Create the abuffer filter;
* it will be used for feeding the data into the graph. */
abuffer = avfilter_get_by_name("abuffer");
if (!abuffer) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not find the abuffer filter!");
return;
}
abuffer_ctx = avfilter_graph_alloc_filter(filterGraph, abuffer, "src");
if (!abuffer_ctx) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not allocate the abuffer_ctx instance! %s",
av_err2str(AVERROR(ENOMEM)));
return;
}
char ch_layout[64];
/* Set the filter options through the AVOptions API. */
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, AV_CH_LAYOUT_STEREO);
av_opt_set(abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
av_opt_set(abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(AV_SAMPLE_FMT_FLT),
AV_OPT_SEARCH_CHILDREN);
av_opt_set_q(abuffer_ctx, "time_base", (AVRational) {1, defaultSampleRate},
AV_OPT_SEARCH_CHILDREN);
av_opt_set_int(abuffer_ctx, "sample_rate", defaultSampleRate, AV_OPT_SEARCH_CHILDREN);
/* Now initialize the filter; we pass NULL options, since we have already
* set all the options above. */
if (avfilter_init_str(abuffer_ctx, nullptr) < 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not initialize the abuffer filter!");
return;
}
// TODO: select FX's dynamically
/* Create aecho filter. */
if (true) {
choisen_beat_fx = avfilter_get_by_name("volume");
if (!choisen_beat_fx) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not find the aecho filter!");
return;
}
choisen_beat_fx_ctx = avfilter_graph_alloc_filter(filterGraph, choisen_beat_fx, "echo");
if (!choisen_beat_fx_ctx) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not allocate the choisen_beat_fx_ctx instance! %s",
av_err2str(AVERROR(ENOMEM)));
return;
}
av_opt_set (choisen_beat_fx_ctx, "volume", AV_STRINGIFY(0.5), AV_OPT_SEARCH_CHILDREN);
if (avfilter_init_str(choisen_beat_fx_ctx, nullptr) < 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not initialize the choisen_beat_fx_ctx filter!");
return;
}
}
/* Create the aformat filter;
* it ensures that the output is of the format we want. */
aformat = avfilter_get_by_name("aformat");
if (!aformat) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not find the aformat filter!");
return;
}
aformat_ctx = avfilter_graph_alloc_filter(filterGraph, aformat, "aformat");
if (!aformat_ctx) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not allocate the aformat instance!");
return;
}
av_opt_set(aformat_ctx, "sample_fmts", av_get_sample_fmt_name(AV_SAMPLE_FMT_FLT),
AV_OPT_SEARCH_CHILDREN);
av_opt_set_int(aformat_ctx, "sample_rates", defaultSampleRate, AV_OPT_SEARCH_CHILDREN);
av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, AV_CH_LAYOUT_STEREO);
av_opt_set(aformat_ctx, "channel_layouts", ch_layout, AV_OPT_SEARCH_CHILDREN);
if (avfilter_init_str(aformat_ctx, nullptr) < 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not initialize the aformat filter!");
return;
}
/* Finally create the abuffersink filter;
* it will be used to get the filtered data out of the graph. */
abuffersink = avfilter_get_by_name("abuffersink");
if (!abuffersink) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not find the abuffersink filter!");
return;
}
abuffersink_ctx = avfilter_graph_alloc_filter(filterGraph, abuffersink, "sink");
if (!abuffersink_ctx) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not allocate the abuffersink instance!");
return;
}
/* This filter takes no options. */
if (avfilter_init_str(abuffersink_ctx, nullptr) < 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Could not initialize the abuffersink instance.!");
return;
}
/* Connect the filters;
* in this simple case the filters just form a linear chain. */
if (avfilter_link(abuffer_ctx, 0, choisen_beat_fx_ctx, 0) != 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Error connecting filters.!");
return;
}
if (avfilter_link(choisen_beat_fx_ctx, 0, aformat_ctx, 0) != 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Error connecting filters.!");
return;
}
if (avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0) != 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Error connecting filters.!");
return;
}
/* Configure the graph. */
if (avfilter_graph_config(filterGraph, nullptr) < 0) {
*mediaLoadPointer = FAILED_TO_LOAD;
LOGE("FXProcessor::FXProcessor Error configuring the filter graph!");
return;
}
This code works fine when the chain is
(input) -> abuffer -> aecho-> aformat -> abuffersink -> (output)
However, I would like to use adelay instead of volume filter. So I want:
The filter chain it uses is: * (input) -> abuffer -> volume ->
aformat -> abuffersink -> (output)
I changed the code at
choisen_beat_fx = avfilter_get_by_name("volume");
to
choisen_beat_fx = avfilter_get_by_name("aecho");
and removed the line
av_opt_set (choisen_beat_fx_ctx, "volume", AV_STRINGIFY(0.5), AV_OPT_SEARCH_CHILDREN);
everything goes smooth until the last line.
avfilter_graph_config fails and returns negative value. Functions document:
avfilter_graph_config: Check validity and configure all the links and
formats in the graph.
So my guess is I need extra links to insert aecho to my chain? How can I insert aecho into my filter chain?
Okay the problem was, I needed to compile with aresample filter for this to work. I recompiled and magically it works now.
Here is how I found out the problem. Create a general log callback:
void ffmpegErrorCallback(void *ptr, int level, const char *fmt, va_list vargs) {
LOGE("ffmpegErrorCallback Error Occurred! Err: %s", fmt);
}
av_log_set_level(AV_LOG_ERROR);
av_log_set_callback(ffmpegErrorCallback);
FFmpeg will now log the errors as a human readable message. It told me that it couldnt find aresample filter. Thats how I solved the issue.

Create task in macOS alwise return kern error

This is my code:
task_t child;
kern_return_t kr;
ledger_t ledgers = (ledger_t)0;
boolean_t inheret = FALSE;
ledger_array_t ledger_array = &ledgers;
mach_msg_type_number_t count = 1;
kr = task_create(mach_task_self(), ledger_array, count, inheret, &child);
if ( kr != KERN_SUCCESS)
{
printf("We failed getting the task\n");
mach_error("task created: ", kr);
exit(1);
}
I always get: "task created: (os/kern) failure" (I tried to run this as normal use and as root - always get the error).
What do I do rung?

MySQL Trouble transitioning from Injection to Paramterization

I have the following code here that executes a query. Originally, I used SQL Injection to return row results. Hearing I should use parametrization, I rearranged my code and read the MySQL docs on how to do so. I'm using MySQL's C library in a C++ application.
However, it's not returning the results.
I know my SQL statement is 100% fine. It has been tested. The only thing I changed was changing %d (injection) to ?, which accepts the player's ID.
This returns -1. It's a SELECT statement though, so maybe it's normal?
// Get the number of affected rows
affected_rows = mysql_stmt_affected_rows(m_stmt);
This returns 2. This is correct. I have two fields being returned.
// Store the field count
m_fieldCount = mysql_field_count(&m_conn);
This returns 0 (success)
if (mysql_stmt_store_result(m_stmt))
Finally, this returns null.
m_result = mysql_store_result(&m_conn);
I need m_result so I can read the rows. "mysql_stmt_store_result" sounds similar, but doesn't return MYSQL_RESULT.
m_result = mysql_store_result(&m_conn);
/// <summary>
/// Executes a query.
/// </summary>
/// <param name="query">The query to execute.</param>
/// <returns>Returns true on success, else false.</returns>
bool SQLConnection::executeQuery_New(const char *query)
{
int param_count = 0;
int affected_rows = 0;
// Validate connection.
if (!m_connected)
return false;
// Initialize the statement
m_stmt = mysql_stmt_init(&m_conn);
if (!m_stmt) {
fprintf(stderr, " mysql_stmt_init(), out of memory\n");
return false;
}
// Prepare the statement
if (mysql_stmt_prepare(m_stmt, query, strlen(query))) {
fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(m_stmt));
return false;
}
// Get the parameter count from the statement
param_count = mysql_stmt_param_count(m_stmt);
if (param_count != m_bind.size()) {
fprintf(stderr, " invalid parameter count returned by MySQL\n");
return false;
}
// Bind buffers
// The parameter binds are stored in std::vector<MYSQL_BIND>
// I need to convert std::vector<MYSQL_BIND> m_bind to MYSQL_BIND *bnd
MYSQL_BIND *bind = new MYSQL_BIND[m_bind.size() + 1];
memset(bind, 0, sizeof(bind) * m_bind.size());
for (int i = 0; i < param_count; i++)
bind[i] = m_bind[i];
if (mysql_stmt_bind_param(m_stmt, &bind[0]))
{
fprintf(stderr, " mysql_stmt_bind_param() failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(m_stmt));
return false;
}
// Execute the query
if (mysql_stmt_execute(m_stmt)) {
fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(m_stmt));
return false;
}
// Get the number of affected rows
affected_rows = mysql_stmt_affected_rows(m_stmt);
//if (affected_rows == -1) {
// fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
// fprintf(stderr, " %s\n", mysql_stmt_error(m_stmt));
// return false;
//}
// Store the field count
m_fieldCount = mysql_field_count(&m_conn);
// Store the result
if (mysql_stmt_store_result(m_stmt))
{
fprintf(stderr, " failed retrieving result\n");
fprintf(stderr, " %s\n", mysql_error(&m_conn));
int d = mysql_errno(&m_conn);
return false;
}
// This looks similar to the last above statement, but I need m_result. I used mysql_store_result earlier when using injection and it worked fine, but here in this case it returns null.
m_result = mysql_store_result(&m_conn);
// Close the statement
if (mysql_stmt_close(m_stmt)) {
/* mysql_stmt_close() invalidates stmt, so call */
/* mysql_error(mysql) rather than mysql_stmt_error(stmt) */
fprintf(stderr, " failed while closing the statement\n");
fprintf(stderr, " %s\n", mysql_error(&m_conn));
return false;
}
// Delete bind array
if (bind) {
delete[] bind;
bind = NULL;
}
return true;
}
How I'm adding an int parameter (player's id):
void SQLConnection::addParam(int buffer, enum_field_types type, unsigned long length)
{
MYSQL_BIND bind;
memset(&bind, 0, sizeof(bind));
bind.buffer = (char *)&buffer;
bind.buffer_type = type;
bind.is_null = 0;
bind.length = &length;
m_bind.push_back(bind);
}
My variables and their types:
class SQLConnection
{
private:
MYSQL m_conn;
MYSQL_ROW m_row;
MYSQL_RES *m_result;
char m_errorMessage[ERROR_MSG_MAX];
bool m_connected;
MYSQL_STMT *m_stmt;
std::vector<MYSQL_BIND> m_bind;
int m_fieldCount;
// ...
And finally its calling function at the end of the SQL statement:
...WHERE player_id = ?;");
conn.addParam(m_id, MYSQL_TYPE_LONGLONG, 0);
if (!conn.executeQuery_New(buffer)) {
conn.close();
return "";
}
// Close the connection.
conn.close();
std::string s = conn.getField("max_value_column_name");
The error code I get is 2014:
https://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html
Just for the sake of interest, this is a prior function I used. This worked fine for injection. Using the new function above with parameterization is the one causing the issues.
bool SQLConnection::executeQuery(const char *query)
{
// Validate connection.
if (!m_connected)
return false;
// Execute the query
int status = mysql_query(&m_conn, query);
if (status != 0) {
sprintf(m_errorMessage, "Error: %s", mysql_error(&m_conn));
return false;
}
// Store the result
m_result = mysql_store_result(&m_conn);
return true;
}
After I started having language religious wars in my head about using C# over C++, I thought I'd give one last attempt here. Any help is appreciated.
Edit:
This is how I read in column names prior to parameterization (maybe this code needs to be updated after calling mysql_stmt_store_result(m_stmt)?
std::string SQLConnection::getField(const char *fieldName)
{
MYSQL_FIELD *field = NULL;
unsigned int name_field = 0;
mysql_stmt_data_seek(m_stmt, 0);
mysql_stmt_fetch_column(m_stmt, &bind, 0, 0);
//mysql_data_seek(m_result, 0);
//mysql_field_seek(m_result, 0);
const unsigned int num_fields = mysql_stmt_field_count(m_stmt);
// const unsigned int num_fields = mysql_num_fields(m_result);
std::vector<char *> headers(num_fields);
for (unsigned int i = 0; (field = mysql_fetch_field(m_result)); i++)
{
headers[i] = field->name;
if (strcmp(fieldName, headers[i]) == 0)
name_field = i;
}
while ((m_row = mysql_fetch_row(m_result))) {
return std::string(m_row[name_field]);
}
return "";
}
Edit:
What I'm finding is in this last function there are equivalent functions for statements, like mysql_num_fields() is mysql_stmt_field_count(). I'm thinking these need to be updated because it's using m_stmt and not m_result anymore, which gives reason to update the functions so m_stmt is used. It's not very apparent how to update the second half of the function though.
You may need a better understanding of how stmt works.You can't get the final results by mysql_store_result() when you're using stmt.
You shoud bind several buffers for the statement you're using to accept the result set. You can finish this by mysql_stmt_bind_result(), just like mysql_stmt_bind_param().
Then you can use the buffers bound by mysql_stmt_bind_result() to return row data. You can finish this by mysql_stmt_fetch().
Do the fetch method repeatedly, so you can get the whole result set row by row.
The basic sequence of calls:
mysql_stmt_init
mysql_stmt_prepare
mysql_stmt_bind_param
mysql_stmt_execute
mysql_stmt_bind_result
mysql_stmt_store_result
mysql_stmt_fetch (repeatedly, row by row)
mysql_stmt_free_result
It works for me.
It's a long time since I finished this part of my project, you'd better read the manual carefully and find more examples of stmt.
Sorry for my poor English. Good luck!

vp9 encoder returns a null packet

i using this code to encode video stream using vp8 and i decided to give vp9 a try so i changed every thing with starts with vp_* from 8 to 9.
but the vp9 encoder always return a null packet although the encoder doesn't return any error.
here is the code i'am using for configuring.
vpx_codec_err_t error = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &enc_cfg, 0);
if(error != VPX_CODEC_OK)
return error;
enc_cfg.g_timebase.den = fps;
enc_cfg.rc_undershoot_pct = 95;
enc_cfg.rc_target_bitrate = bitrate;
enc_cfg.g_error_resilient = 1;
enc_cfg.kf_max_dist = 999999;
enc_cfg.rc_buf_initial_sz = 4000;
enc_cfg.rc_buf_sz = 6000;
enc_cfg.rc_buf_optimal_sz = 5000;
enc_cfg.rc_end_usage = VPX_CBR;
enc_cfg.g_h = height;
enc_cfg.g_w = width;
enc_cfg.rc_min_quantizer = 4;
enc_cfg.rc_max_quantizer = 56;
enc_cfg.g_threads = 4;
enc_cfg.g_pass = VPX_RC_ONE_PASS;
error = vpx_codec_enc_init(&codec, vpx_codec_vp9_cx(), &enc_cfg, 0);
if(error != VPX_CODEC_OK)
return error;
vpx_img_alloc(&vpx_image,VPX_IMG_FMT_I420 , width, height, 1);
configured = true;
return VPX_CODEC_OK;
and the code for the encoding
libyuv::RAWToI420(frame, vpx_image.d_w * 3, vpx_image.planes[VPX_PLANE_Y],vpx_image.stride[VPX_PLANE_Y],
vpx_image.planes[VPX_PLANE_U], vpx_image.stride[VPX_PLANE_U], vpx_image.planes[VPX_PLANE_V],
vpx_image.stride[VPX_PLANE_V], vpx_image.d_w, vpx_image.d_h);
const vpx_codec_cx_pkt_t *pkt;
vpx_codec_err_t error = vpx_codec_encode(&codec, &vpx_image, 0, 1, 0, VPX_DL_GOOD_QUALITY);
if(error != VPX_CODEC_OK)
return vector<byte>();
vpx_codec_iter_t iter = NULL;
if((pkt = vpx_codec_get_cx_data(&codec, &iter)))//always return null ?
{
if(pkt->kind == VPX_CODEC_CX_FRAME_PKT)
{
int length = pkt->data.frame.sz;
byte* buf = (byte*) pkt->data.frame.buf;
vector<byte> data(buf, buf + length);
return data;
}
return vector<byte>();
}
return vector<byte>();
the code is fully working if i'am using vp8 instead of 9, any help is welcomed
Just came across this post because I faced the same problem. Just for other to know: I solved it with setting
enc_cfg.g_lag_in_frames = 0;
This basically disallows the encoder to consume up to default 25 frames until it produces any output.

playing created Audio-Data has noise and periodical clicking in sound

I write an application, which plays a sound getting from Hardware (like a ring buffer filled with a sinus wave with certain frequency). Everything works fine, and I can playback the created sound correctly except a periodical clicking (maybe at the end of buffer?) and noise.
I initialize and run the Buffer:
void Audiooutput::InitializeAudioParameters()
{
Audio_DataWritten = 0;
Audio_fragments = 4;
Audio_channels = 2;
Audio_BufferSize = 256;
Audio_Samplerate = 8000;
Audio_ResamplingFactor = 1;
Audio_Framesize = 2;
// (SND_PCM_FORMAT_S16_LE / 8);
Audio_frames = Audio_BufferSize / Audio_Framesize * Audio_fragments;
snd_pcm_uframes_t size;
err = snd_pcm_hw_params_any(pcmPlaybackHandle, hw_params);
err = snd_pcm_hw_params_set_rate_resample(pcmPlaybackHandle, hw_params, 1);
// qDebug()<<a1.sprintf(" % d \t snd_pcm_hw_params_set_rate: %s",Audio_Samplerate,snd_strerror(err));
err =
snd_pcm_hw_params_set_format(pcmPlaybackHandle, hw_params,
SND_PCM_FORMAT_S16_LE);
err =
snd_pcm_hw_params_set_channels(pcmPlaybackHandle, hw_params,
Audio_channels);
err = snd_pcm_hw_params_set_rate_near(pcmPlaybackHandle, hw_params, &Audio_Samplerate, 0);
// qDebug()<<a1.sprintf(" % d \t snd_pcm_hw_params_set_rate: %s",Audio_Samplerate,snd_strerror(err));
if ((err =
snd_pcm_hw_params_set_periods_near(pcmPlaybackHandle, hw_params,
&Audio_fragments, 0)) < 0) {
qDebug() << a1.sprintf("Error setting # fragments to %d: %s\n",
Audio_fragments, snd_strerror(err));
} else
qDebug() << a1.sprintf("setting # fragments to %d: %s\n",
Audio_fragments, snd_strerror(err));
err = snd_pcm_hw_params_get_buffer_size(hw_params, &size);
if ((err =
snd_pcm_hw_params_set_buffer_size_near(pcmPlaybackHandle,
hw_params,
&Audio_frames)) < 0) {
qDebug() << a1.
sprintf("Error setting buffer_size %d frames: %s",
Audio_frames, snd_strerror(err));
} else
qDebug() << a1.sprintf("setting Buffersize to %d --> %d: %s\n",
Audio_BufferSize, Audio_frames,
snd_strerror(err));
Audio_BufferSize = Audio_frames;
if ((err = snd_pcm_hw_params(pcmPlaybackHandle, hw_params)) < 0) {
qDebug() << a1.sprintf("Error setting HW params: %s",
snd_strerror(err));
}
Q_ASSERT(err >= 0);
}
void Audiooutput::ProduceAudioOutput(int n, int mmodes, int totalMModeGates,
short *sinusValue, short *cosinusValue)
{
for (int audioSample = 0; audioSample < n;
audioSample += Audio_ResamplingFactor) {
currentposition =
(int)(m_Audio.generalPos % (Audio_BufferSize / 2));
if (currentposition == 0) {
QueueAudioBuffer();
m_Audio.currentPos = 0;
}
m_Audio.generalPos++;
AudioData[currentposition * 2] =
(short)(sinusValue[audioSample]);
AudioData[currentposition * 2 + 1] =
(short)(cosinusValue[audioSample]);
}
}
void Audiooutput::QueueAudioBuffer()
{
snd_pcm_prepare(pcmPlaybackHandle);
Audio_DataWritten +=
snd_pcm_writei(pcmPlaybackHandle, AudioData, Audio_BufferSize);
}
Changing the audiobuffer size or fragments changes also the clicking period.
Can anyone help me with this issue ?
I checked also the first and Last Values. Thy are always difference.
OS: Ubuntu 11
more detail.
the count of received data is dynamically, and changes depend of different parameters. But I play always a certain part e.g. 128 values or 256 or 512....
// I get the Audiodata from a hardware (in a Timerloop)
audiobuffersize = 256;
short *AudioData = new short[256];
int generalAudioSample = 0;
void CollectDataFromHw()
{
...
int n = 0;
n = GetData(buf1,buf2);//buf1 = new short[MAX_SHRT]
if(n > 0)
FillAudioBuffer(n,buf1,buf2)
...
}
-------------------------------------------
void FillAudioBuffer(int n, short*buf1, short*buf2)
{
for(int audioSample = 0;audioSample < n; audioSample++){
iCurrentAudioSample = (int)(generalAudioSample % (audiobuffersize/2));
if(iCurrentAudioSample == 0) {
snd_pcm_writei(pcmPlaybackHandle,AudioData,audiobuffersize );
memset(AudioData,0x00,audiobuffersize*sizeof(short));
}
generalAudioSample++;
AudioData[iCurrentAudioSample * 2] = (short)(buf1[audioSample];
AudioData[iCurrentAudioSample * 2 +1] = (short)(buf2[audioSample];
}
}
I changed the audiobuffersize also. If I set it to a bigger size, I have some Echo additional to clicks.
any Idea ?
//-----------------------
the Problem is
snd_pcm_prepare(pcmPlaybackHandle);
every call of this function produce a click in sound !
Can't test the source code, but I think that the high-frequency clicks you hear are discontinuities in the sound wave. You have to assure that looping period (or, buffer size) is multiple of wave period.
Check if first and last value of buffer are almost the same (+/- 1, for example). Their distance determines the amplitude of the unwanted click.
solved
buffer has been played several times before it was filled with the data.
stupid error in the code.missing a parantez --> audio_buffersize/2 <--
and therefore the result was very often if(iCurrentAudioSample == 0) true !!!!!
iCurrentAudioSample = (int)(generalAudioSample % (audio_buffersize/2));
if(iCurrentAudioSample == 0)
{
writetoaudioStream(audiobuffer);
}