Потребовалось использовать в программе на Vala некоторые функции небезызвестной библиотеки для вычисления быстрого преобразования Фурье fftw3. Для чего был написан простенький vapi-файл. В силу своего, прямо скажем, мизерного пока еще опыта использования Vala, не рекомендую брать данный vapi за эталон, тем не менее выкладываю его на случай, если кому-то он окажется полезен. В vapi прописаны лишь некоторые функции, типы и константы и лишь для работы с float-значениями, однако, думаю, при необходимости не составит никакого труда файл необходимым образом дополнить по аналогии. fftw_complex было принято решение не использовать, не заворачивать в класс, а по-простому работать напрямую с float-массивами (поэтому осторожней с выделением-освобождением памяти).

Сам vapi-файл:

[CCode (cprefix = "fftwf_", cheader_filename = "fftw3.h")]
namespace Fftwf
{
    [CCode(cprefix = "FFTW_")]
    enum Sign
    {
        FORWARD = -1,
        BACKWARD = 1
    }

    [CCode(cprefix = "FFTW_")]
    enum Flag
    {
        MEASURE         = (0U),
        DESTROY_INPUT   = (1U << 0),
        UNALIGNED       = (1U << 1),
        CONSERVE_MEMORY = (1U << 2),
        EXHAUSTIVE      = (1U << 3),
        PRESERVE_INPUT  = (1U << 4),
        PATIENT         = (1U << 5),
        ESTIMATE        = (1U << 6)
    }


    [CCode(cname = "fftwf_plan")]
    public struct Plan : int { } // fake int


    void    destroy_plan(Plan p);
    void    execute(Plan p);
    void    free(float *p);
    float*  malloc(size_t n);
    Plan    plan_dft_1d(int n, float* in_ptr, float* out_ptr, Sign sign, Flag flags);
}


Пример использования:

{
float input[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

float *data;
float *fft_result;
float *ifft_result;
Fftwf.Plan plan_forward, plan_backward;
int i;

data        = Fftwf.malloc( 2 * sizeof(float) * input.length );
fft_result  = Fftwf.malloc( 2 * sizeof(float) * input.length );
ifft_result = Fftwf.malloc( 2 * sizeof(float) * input.length );

plan_forward  = Fftwf.plan_dft_1d( input.length, (void*)data, (void*)fft_result, Fftwf.Sign.FORWARD, Fftwf.Flag.ESTIMATE );
plan_backward = Fftwf.plan_dft_1d( input.length, (void*)fft_result, (void*)ifft_result, Fftwf.Sign.BACKWARD, Fftwf.Flag.ESTIMATE );

/* populate input data */
for(i = 0 ; i < input.length ; i++)
{
    data[2 * i + 0] = input[i];
    data[2 * i + 1] = 0.0f;
}

/* print initial data */
for( i = 0 ; i < input.length ; i++ )
{
    print("data[%d] = { %2.2f, %2.2f }\n",
        i, data[2 * i + 0], data[2 * i + 1] );
}

Fftwf.execute( plan_forward );

/* print fft result */
for(i = 0 ; i < input.length ; i++)
{
    print("fft_result[%d] = { %2.2f, %2.2f }\n",
        i, fft_result[2 * i + 0], fft_result[2 * i + 1] );
}

Fftwf.execute( plan_backward );

/* print ifft result */
for( i = 0 ; i < input.length ; i++ )
{
    print("ifft_result[%d] = { %2.2f, %2.2f }\n",
        i, ifft_result[2 * i + 0] / input.length, ifft_result[2 * i + 1] / input.length );
}

/* free memory */
Fftwf.destroy_plan( plan_forward );
Fftwf.destroy_plan( plan_backward );

Fftwf.free(data);
Fftwf.free(fft_result);
Fftwf.free(ifft_result);
}

В заключение хочу порекомендовать отличное how-to по написанию vapi к не-GObject-библиотекам.

"Хозяйке на заметку": прочитать данные (переменные, целые, с плавающей точкой и т.п.) из бинарного файла на Vala можно и нужно с помощью GVariant, например так:


{
    uint8[] buf = new uint8[sizeof(uint32) + sizeof(uint32) +
        sizeof(double) + sizeof(double)];

    {
        var data_stream = new DataInputStream(file.read());
        data_stream.read(buf);
    }

    Variant variant = Variant.new_from_data<uint8>(
        new VariantType("(uudd)"), buf, true);

    uint32 int1 = variant.get_child_value(0).get_uint32();
    uint32 int2 = variant.get_child_value(1).get_uint32();
    double double1 = variant.get_child_value(2).get_double();
    double double2 = variant.get_child_value(3).get_double();

    stdout.printf("int 1 = %u\n", int1);
    stdout.printf("int 2 = %u\n", int2);
    stdout.printf("double 1 = %f\n", double1);
    stdout.printf("double 2 = %f\n", double2);
}



 

Copyright © 2007 DamnSmallBlog. Content is licensed under Creative Commons Attribution-Noncommercial.

Design: GeckoandFly and Blogcrowds.