leeeeeeeeess
leeeeeeeeess

Reputation: 19

Resampling function produces audio with noise

I have function for resampling one channel of audio (as a float array):

int resample_and_save(float *audio_input, int input_sample_rate, int output_sample_rate, int input_num_of_samples, const char *output_file) {
    AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MONO;
    SwrContext *swr_ctx = swr_alloc();
    uint8_t **resampled_data = NULL;
    float *audio_output = NULL;
    int ret = SUCCESS;

    if (!swr_ctx) {
        fprintf(stderr, "Could not allocate resampler context\n");
        return ERROR_NOTENOUGH_MEMORY;
    }

    av_opt_set_chlayout(swr_ctx, "in_chlayout", &ch_layout, 0);
    av_opt_set_int(swr_ctx, "in_sample_rate", input_sample_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);

    av_opt_set_chlayout(swr_ctx, "out_chlayout", &ch_layout, 0);
    av_opt_set_int(swr_ctx, "out_sample_rate", output_sample_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);

    if ((ret = swr_init(swr_ctx)) < 0) {
        ret = handle_av_error(ret);
        goto cleanup;
    }

    int output_samples_count = av_rescale_rnd(swr_get_delay(swr_ctx, input_sample_rate) + input_num_of_samples, output_sample_rate, input_sample_rate, AV_ROUND_UP);
    ret = av_samples_alloc_array_and_samples(&resampled_data, NULL, 1, output_samples_count, AV_SAMPLE_FMT_FLT, 0);
    if (ret < 0) {
        ret = handle_av_error(ret);
        goto cleanup;
    }

    const uint8_t *in_samples[1] = { (const uint8_t *)audio_input };
    int frame_count = swr_convert(swr_ctx, resampled_data, output_samples_count, in_samples, input_num_of_samples);
    if (frame_count < 0) {
        fprintf(stderr, "Error while resampling\n");
        ret = ERROR_UNKNOWN;
        goto cleanup;
    }

    while (1) {
        int frame_count_flush = swr_convert(swr_ctx, resampled_data, output_samples_count, NULL, 0);
        if (frame_count_flush <= 0) {
            break;
        }
        frame_count += frame_count_flush;
    }

    audio_output = (float *)malloc(frame_count * sizeof(float));
    if (!audio_output) {
        fprintf(stderr, "Could not allocate memory for output\n");
        ret = ERROR_NOTENOUGH_MEMORY;
        goto cleanup;
    }

    memcpy(audio_output, resampled_data[0], frame_count);
    ret = write_wav(output_file, audio_output, frame_count, output_sample_rate);

cleanup:
    if (resampled_data != NULL)
        av_freep(&resampled_data[0]);
    swr_free(&swr_ctx);
    if (audio_output != NULL)
        free(audio_output);
    return ret;
}

write_wav:

int write_wav(const char *filename, float *samples, int num_samples, int sample_rate) {
    FILE *file = fopen(filename, "wb");
    if (!file) {
        fprintf(stderr, "Unable to open file for writing\n");
        return ERROR_UNKNOWN;
    }

    unsigned char header[44] = {
        'R','I','F','F', // RIFF
        0,0,0,0, // Chunk size (to be filled later)
        'W','A','V','E', // WAVE
        'f','m','t',' ', // fmt
        16,0,0,0, // Subchunk1Size (16 for PCM)
        1,0, // AudioFormat (1 for PCM)
        1,0, // NumChannels (1 for mono)
        0,0,0,0, // SampleRate (to be filled later)
        0,0,0,0, // ByteRate (to be filled later)
        4,0, // BlockAlign (4 bytes per sample frame for float)
        32,0, // BitsPerSample (32 for float samples)
        'd','a','t','a', // Subchunk2ID
        0,0,0,0  // Subchunk2Size (to be filled later)
    };

    int byte_rate = sample_rate * 4;
    int subchunk2_size = num_samples * 4;
    int chunk_size = 36 + subchunk2_size;

    memcpy(header + 24, &sample_rate, 4);
    memcpy(header + 28, &byte_rate, 4);
    memcpy(header + 40, &subchunk2_size, 4);
    memcpy(header + 4, &chunk_size, 4);

    fwrite(header, sizeof(header), 1, file);

    fwrite(samples, sizeof(float), num_samples, file);

    fclose(file);
    return 0;
}

When I play the audio (even one-channel audio), there is a lot of noise on it, like there are missing samples. How can I fix it?

This is how original audio looks (24000 hz): enter image description here

And this is a resampled audio (48000 hz): enter image description here

Upvotes: 0

Views: 73

Answers (0)

Related Questions