<commit_before>// Tests for gheap.
//
// Pass -DGHEAP_CPP11 to compiler for gheap_cpp11.hpp tests,
// otherwise gheap_cpp03.hpp will be tested.

#ifdef GHEAP_CPP11
#  include "gheap_cpp11.hpp"
#else
#  include "gheap_cpp03.hpp"
#endif

#include <cstdlib>    // for srand(), rand()
#include <iostream>   // for cout
#include <vector>

using namespace std;

namespace {

// Verifies correctness of parent and child index calculations.
template <size_t Fanout, size_t PageChunks>
void test_parent_child(const size_t start_index, const size_t n)
{
  assert(start_index > 0);
  assert(start_index <= SIZE_MAX - n);

  typedef gheap<Fanout, PageChunks> heap;

  for (size_t i = 0; i < n; ++i) {
    const size_t u = start_index + i;
    size_t v = heap::get_child_index(u);
    if (v < SIZE_MAX) {
      assert(v > u);
      v = heap::get_parent_index(v);
      assert(v == u);
    }

    v = heap::get_parent_index(u);
    assert(v < u);
    v = heap::get_child_index(v);
    assert(v <= u && u - v < Fanout);
  }

  cout << "test_parent_child(start_index=" << start_index << ", n=" << n <<
      ", Fanout=" << Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies is_heap_until() and is_heap() correctness.
template <size_t Fanout, size_t PageChunks>
void test_is_heap(const size_t n)
{
  assert(n > 0);

  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;

  // Verify that ascending sorted array creates one-item heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(i);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.begin() + 1);
  assert(heap::is_heap(a.begin(), a.begin() + 1));
  if (n > 1) {
    assert(!heap::is_heap(a.begin(), a.end()));
  }

  // Verify that descending sorted array creates valid heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(n - i);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.end());
  assert(heap::is_heap(a.begin(), a.end()));

  // Verify that array containing identical items creates valid heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(n);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.end());
  assert(heap::is_heap(a.begin(), a.end()));
}

// Fills the given array with n random integers.
void init_array(vector<int> *const a, const size_t n)
{
  a->clear();
  a->reserve(n);

  srand(0);
  for (size_t i = 0; i < n; ++i) {
    a->push_back(rand());
  }
}

// Verifies that items in the given range are sorted in ascending order.
template <class RandomAccessIterator>
void assert_sorted_asc(const RandomAccessIterator &first,
    const RandomAccessIterator &last)
{
  assert(last > first);

  const size_t size = last - first;
  for (size_t i = 1; i < size; ++i) {
    assert(first[i] >= first[i - 1]);
  }
}

// Verifies that items in the given range are sorted in descending order.
template <class RandomAccessIterator>
void assert_sorted_desc(const RandomAccessIterator &first,
    const RandomAccessIterator &last)
{
  assert(last > first);

  const size_t size = last - first;
  for (size_t i = 1; i < size; ++i) {
    assert(first[i] <= first[i - 1]);
  }
}

bool inverse_less_comparer(const int a, const int b)
{
  return (b < a);
}

// Verifies correctness of heapsort built on top of "make_heap(); build_heap()".
template <size_t Fanout, size_t PageChunks>
void test_heapsort(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;

  // Verify ascending sorting with default less_comparer.
  init_array(&a, n);
  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  heap::sort_heap(a.begin(), a.end());
  assert_sorted_asc(a.begin(), a.end());

  // Verify descending sorting with custom less_comparer.
  init_array(&a, n);
  heap::make_heap(a.begin(), a.end(), inverse_less_comparer);
  assert(heap::is_heap(a.begin(), a.end(), inverse_less_comparer));
  heap::sort_heap(a.begin(), a.end(), inverse_less_comparer);
  assert_sorted_desc(a.begin(), a.end());

  cout << "test_heapsort(n=" << n << ", Fanout=" << Fanout << ", PageChunks=" <<
      PageChunks << ") OK" << endl;
}

// Verifies push_heap() correctness.
template <size_t Fanout, size_t PageChunks>
void test_push_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  for (size_t i = 0; i < n; ++i) {
    heap::push_heap(a.begin(), a.begin() + i + 1);
  }
  assert(heap::is_heap(a.begin(), a.end()));

  cout << "test_push_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

template <size_t Fanout, size_t PageChunks>
void test_pop_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    heap::pop_heap(a.begin(), a.end() - i);
  }
  assert_sorted_asc(a.begin(), a.end());

  cout << "test_pop_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies restore_heap_after_item_increase() correctness.
template <size_t Fanout, size_t PageChunks>
void test_restore_heap_after_item_increase(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % n;
    const int old_item = a[item_index];

    // Don't allow integer overflow.
    size_t fade = SIZE_MAX;
    do {
      // Division by zero is impossible here.
      a[item_index] = old_item + rand() % fade;
      fade /= 2;
    } while (a[item_index] < old_item);
    heap::restore_heap_after_item_increase(a.begin(), a.begin() + item_index);
    assert(heap::is_heap(a.begin(), a.end()));
  }

  cout << "test_restore_heap_after_item_increase(n=" << n << ", Fanout=" <<
      Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies restore_heap_after_item_decrease() correctness.
template <size_t Fanout, size_t PageChunks>
void test_restore_heap_after_item_decrease(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % n;
    const int old_item = a[item_index];

    // Don't allow integer underflow.
    size_t fade = SIZE_MAX;
    do {
      // Division by zero is impossible here.
      a[item_index] = old_item - rand() % fade;
      fade /= 2;
    } while (a[item_index] > old_item);
    heap::restore_heap_after_item_decrease(a.begin(), a.begin() + item_index,
        a.end());
    assert(heap::is_heap(a.begin(), a.end()));
  }

  cout << "test_restore_heap_after_item_decrease(n=" << n << ", Fanout=" <<
      Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

template <size_t Fanout, size_t PageChunks>
void test_remove_from_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % (n - i);
    heap::remove_from_heap(a.begin(), a.begin() + item_index, a.end() - i);
    assert(heap::is_heap(a.begin(), a.end() - i - 1));
  }

  cout << "test_remove_from_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Runs all tests for the given Fanout and PageChunks.
template <size_t Fanout, size_t PageChunks>
void test_all()
{
  // Verify parent-child calculations for indexes close to zero and
  // indexes close to SIZE_MAX.
  static const size_t n = 1000000;
  test_parent_child<Fanout, PageChunks>(1, n);
  test_parent_child<Fanout, PageChunks>(SIZE_MAX - n, n);

  test_is_heap<Fanout, PageChunks>(1);
  test_is_heap<Fanout, PageChunks>(2);
  test_is_heap<Fanout, PageChunks>(3);
  test_is_heap<Fanout, PageChunks>(1000);

  test_heapsort<Fanout, PageChunks>(1);
  test_heapsort<Fanout, PageChunks>(2);
  test_heapsort<Fanout, PageChunks>(3);
  // heapsort for Fanout = 1 is slow, so sort less items.
  test_heapsort<Fanout, PageChunks>(Fanout > 1 ? 100000 : 1000);

  test_push_heap<Fanout, PageChunks>(1);
  test_push_heap<Fanout, PageChunks>(2);
  test_push_heap<Fanout, PageChunks>(3);
  test_push_heap<Fanout, PageChunks>(1000);

  test_pop_heap<Fanout, PageChunks>(1);
  test_pop_heap<Fanout, PageChunks>(2);
  test_pop_heap<Fanout, PageChunks>(3);
  test_pop_heap<Fanout, PageChunks>(1000);

  test_restore_heap_after_item_increase<Fanout, PageChunks>(1);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(2);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(3);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(1000);

  test_restore_heap_after_item_decrease<Fanout, PageChunks>(1);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(2);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(3);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(1000);

  test_remove_from_heap<Fanout, PageChunks>(1);
  test_remove_from_heap<Fanout, PageChunks>(2);
  test_remove_from_heap<Fanout, PageChunks>(3);
  test_remove_from_heap<Fanout, PageChunks>(1000);
}

}  // End of anonymous namespace.

int main()
{
  test_all<1, 1>();
  test_all<2, 1>();
  test_all<3, 1>();
  test_all<4, 1>();
  test_all<101, 1>();

  test_all<1, 2>();
  test_all<2, 2>();
  test_all<3, 2>();
  test_all<4, 2>();
  test_all<101, 2>();

  test_all<1, 3>();
  test_all<2, 3>();
  test_all<3, 3>();
  test_all<4, 3>();
  test_all<101, 3>();

  test_all<1, 4>();
  test_all<2, 4>();
  test_all<3, 4>();
  test_all<4, 4>();
  test_all<101, 4>();

  test_all<1, 101>();
  test_all<2, 101>();
  test_all<3, 101>();
  test_all<4, 101>();
  test_all<101, 101>();
}
<commit_msg>added indicator for 'all tests done'<commit_after>// Tests for gheap.
//
// Pass -DGHEAP_CPP11 to compiler for gheap_cpp11.hpp tests,
// otherwise gheap_cpp03.hpp will be tested.

#ifdef GHEAP_CPP11
#  include "gheap_cpp11.hpp"
#else
#  include "gheap_cpp03.hpp"
#endif

#include <cstdlib>    // for srand(), rand()
#include <iostream>   // for cout
#include <vector>

using namespace std;

namespace {

// Verifies correctness of parent and child index calculations.
template <size_t Fanout, size_t PageChunks>
void test_parent_child(const size_t start_index, const size_t n)
{
  assert(start_index > 0);
  assert(start_index <= SIZE_MAX - n);

  typedef gheap<Fanout, PageChunks> heap;

  for (size_t i = 0; i < n; ++i) {
    const size_t u = start_index + i;
    size_t v = heap::get_child_index(u);
    if (v < SIZE_MAX) {
      assert(v > u);
      v = heap::get_parent_index(v);
      assert(v == u);
    }

    v = heap::get_parent_index(u);
    assert(v < u);
    v = heap::get_child_index(v);
    assert(v <= u && u - v < Fanout);
  }

  cout << "test_parent_child(start_index=" << start_index << ", n=" << n <<
      ", Fanout=" << Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies is_heap_until() and is_heap() correctness.
template <size_t Fanout, size_t PageChunks>
void test_is_heap(const size_t n)
{
  assert(n > 0);

  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;

  // Verify that ascending sorted array creates one-item heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(i);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.begin() + 1);
  assert(heap::is_heap(a.begin(), a.begin() + 1));
  if (n > 1) {
    assert(!heap::is_heap(a.begin(), a.end()));
  }

  // Verify that descending sorted array creates valid heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(n - i);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.end());
  assert(heap::is_heap(a.begin(), a.end()));

  // Verify that array containing identical items creates valid heap.
  a.clear();
  for (size_t i = 0; i < n; ++i) {
    a.push_back(n);
  }
  assert(heap::is_heap_until(a.begin(), a.end()) == a.end());
  assert(heap::is_heap(a.begin(), a.end()));
}

// Fills the given array with n random integers.
void init_array(vector<int> *const a, const size_t n)
{
  a->clear();
  a->reserve(n);

  srand(0);
  for (size_t i = 0; i < n; ++i) {
    a->push_back(rand());
  }
}

// Verifies that items in the given range are sorted in ascending order.
template <class RandomAccessIterator>
void assert_sorted_asc(const RandomAccessIterator &first,
    const RandomAccessIterator &last)
{
  assert(last > first);

  const size_t size = last - first;
  for (size_t i = 1; i < size; ++i) {
    assert(first[i] >= first[i - 1]);
  }
}

// Verifies that items in the given range are sorted in descending order.
template <class RandomAccessIterator>
void assert_sorted_desc(const RandomAccessIterator &first,
    const RandomAccessIterator &last)
{
  assert(last > first);

  const size_t size = last - first;
  for (size_t i = 1; i < size; ++i) {
    assert(first[i] <= first[i - 1]);
  }
}

bool inverse_less_comparer(const int a, const int b)
{
  return (b < a);
}

// Verifies correctness of heapsort built on top of "make_heap(); build_heap()".
template <size_t Fanout, size_t PageChunks>
void test_heapsort(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;

  // Verify ascending sorting with default less_comparer.
  init_array(&a, n);
  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  heap::sort_heap(a.begin(), a.end());
  assert_sorted_asc(a.begin(), a.end());

  // Verify descending sorting with custom less_comparer.
  init_array(&a, n);
  heap::make_heap(a.begin(), a.end(), inverse_less_comparer);
  assert(heap::is_heap(a.begin(), a.end(), inverse_less_comparer));
  heap::sort_heap(a.begin(), a.end(), inverse_less_comparer);
  assert_sorted_desc(a.begin(), a.end());

  cout << "test_heapsort(n=" << n << ", Fanout=" << Fanout << ", PageChunks=" <<
      PageChunks << ") OK" << endl;
}

// Verifies push_heap() correctness.
template <size_t Fanout, size_t PageChunks>
void test_push_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  for (size_t i = 0; i < n; ++i) {
    heap::push_heap(a.begin(), a.begin() + i + 1);
  }
  assert(heap::is_heap(a.begin(), a.end()));

  cout << "test_push_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

template <size_t Fanout, size_t PageChunks>
void test_pop_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    heap::pop_heap(a.begin(), a.end() - i);
  }
  assert_sorted_asc(a.begin(), a.end());

  cout << "test_pop_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies restore_heap_after_item_increase() correctness.
template <size_t Fanout, size_t PageChunks>
void test_restore_heap_after_item_increase(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % n;
    const int old_item = a[item_index];

    // Don't allow integer overflow.
    size_t fade = SIZE_MAX;
    do {
      // Division by zero is impossible here.
      a[item_index] = old_item + rand() % fade;
      fade /= 2;
    } while (a[item_index] < old_item);
    heap::restore_heap_after_item_increase(a.begin(), a.begin() + item_index);
    assert(heap::is_heap(a.begin(), a.end()));
  }

  cout << "test_restore_heap_after_item_increase(n=" << n << ", Fanout=" <<
      Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Verifies restore_heap_after_item_decrease() correctness.
template <size_t Fanout, size_t PageChunks>
void test_restore_heap_after_item_decrease(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % n;
    const int old_item = a[item_index];

    // Don't allow integer underflow.
    size_t fade = SIZE_MAX;
    do {
      // Division by zero is impossible here.
      a[item_index] = old_item - rand() % fade;
      fade /= 2;
    } while (a[item_index] > old_item);
    heap::restore_heap_after_item_decrease(a.begin(), a.begin() + item_index,
        a.end());
    assert(heap::is_heap(a.begin(), a.end()));
  }

  cout << "test_restore_heap_after_item_decrease(n=" << n << ", Fanout=" <<
      Fanout << ", PageChunks=" << PageChunks << ") OK" << endl;
}

template <size_t Fanout, size_t PageChunks>
void test_remove_from_heap(const size_t n)
{
  typedef gheap<Fanout, PageChunks> heap;

  vector<int> a;
  init_array(&a, n);

  heap::make_heap(a.begin(), a.end());
  assert(heap::is_heap(a.begin(), a.end()));
  for (size_t i = 0; i < n; ++i) {
    const size_t item_index = rand() % (n - i);
    heap::remove_from_heap(a.begin(), a.begin() + item_index, a.end() - i);
    assert(heap::is_heap(a.begin(), a.end() - i - 1));
  }

  cout << "test_remove_from_heap(n=" << n << ", Fanout=" << Fanout <<
      ", PageChunks=" << PageChunks << ") OK" << endl;
}

// Runs all tests for the given Fanout and PageChunks.
template <size_t Fanout, size_t PageChunks>
void test_all()
{
  // Verify parent-child calculations for indexes close to zero and
  // indexes close to SIZE_MAX.
  static const size_t n = 1000000;
  test_parent_child<Fanout, PageChunks>(1, n);
  test_parent_child<Fanout, PageChunks>(SIZE_MAX - n, n);

  test_is_heap<Fanout, PageChunks>(1);
  test_is_heap<Fanout, PageChunks>(2);
  test_is_heap<Fanout, PageChunks>(3);
  test_is_heap<Fanout, PageChunks>(1000);

  test_heapsort<Fanout, PageChunks>(1);
  test_heapsort<Fanout, PageChunks>(2);
  test_heapsort<Fanout, PageChunks>(3);
  // heapsort for Fanout = 1 is slow, so sort less items.
  test_heapsort<Fanout, PageChunks>(Fanout > 1 ? 100000 : 1000);

  test_push_heap<Fanout, PageChunks>(1);
  test_push_heap<Fanout, PageChunks>(2);
  test_push_heap<Fanout, PageChunks>(3);
  test_push_heap<Fanout, PageChunks>(1000);

  test_pop_heap<Fanout, PageChunks>(1);
  test_pop_heap<Fanout, PageChunks>(2);
  test_pop_heap<Fanout, PageChunks>(3);
  test_pop_heap<Fanout, PageChunks>(1000);

  test_restore_heap_after_item_increase<Fanout, PageChunks>(1);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(2);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(3);
  test_restore_heap_after_item_increase<Fanout, PageChunks>(1000);

  test_restore_heap_after_item_decrease<Fanout, PageChunks>(1);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(2);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(3);
  test_restore_heap_after_item_decrease<Fanout, PageChunks>(1000);

  test_remove_from_heap<Fanout, PageChunks>(1);
  test_remove_from_heap<Fanout, PageChunks>(2);
  test_remove_from_heap<Fanout, PageChunks>(3);
  test_remove_from_heap<Fanout, PageChunks>(1000);
}

}  // End of anonymous namespace.

int main()
{
  test_all<1, 1>();
  test_all<2, 1>();
  test_all<3, 1>();
  test_all<4, 1>();
  test_all<101, 1>();

  test_all<1, 2>();
  test_all<2, 2>();
  test_all<3, 2>();
  test_all<4, 2>();
  test_all<101, 2>();

  test_all<1, 3>();
  test_all<2, 3>();
  test_all<3, 3>();
  test_all<4, 3>();
  test_all<101, 3>();

  test_all<1, 4>();
  test_all<2, 4>();
  test_all<3, 4>();
  test_all<4, 4>();
  test_all<101, 4>();

  test_all<1, 101>();
  test_all<2, 101>();
  test_all<3, 101>();
  test_all<4, 101>();
  test_all<101, 101>();

  cout << "All tests DONE" << endl;
}
<|endoftext|>


<commit_before>/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "LFParticleSystemNode.h"

// Custom Shader
static const GLchar* shaderVert = R"(
attribute vec4 a_position;
attribute vec4 a_color;
attribute float a_size;

#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
#else
varying vec4 v_fragmentColor;
#endif
void main()
{
    gl_Position = CC_PMatrix * CC_MVMatrix * a_position;
    gl_PointSize = CC_MVMatrix[0][0] * a_size;
    v_fragmentColor = a_color;
}
)";

static const GLchar* shaderFrag = R"(

#ifdef GL_ES
precision lowp float;
#endif
uniform sampler2D CC_Texture0;

varying vec4 v_fragmentColor;
void main()
{
    gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, gl_PointCoord);
}
)";

using namespace cocos2d;

LFParticleSystemNode* LFParticleSystemNode::create(b2ParticleSystem* particleSystem, float ratio)
{
    auto node = new LFParticleSystemNode;
    node->init(particleSystem, ratio);
    node->autorelease();

    return node;
}

bool LFParticleSystemNode::init(b2ParticleSystem* particleSystem, float ratio)
{
    _particleSystem = particleSystem;
    kmMat4Scaling(&_ratioTransform, ratio, ratio, 1);
    _ratio = ratio;

    // own shader
    GLProgram *p = new GLProgram;
    p->initWithByteArrays(shaderVert, shaderFrag);
    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
//    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
    p->bindAttribLocation("a_size", 3);

    p->link();
    p->updateUniforms();

    this->setShaderProgram(p);
    p->release();

    setupVBO();

    auto textureCache = Director::getInstance()->getTextureCache();
    _texture = textureCache->addImage("Images/fire.png");

    _blendFunc = BlendFunc::ADDITIVE;

    return true;
}

void LFParticleSystemNode::setupVBO()
{
    glGenBuffers(3, &_buffersVBO[0]);

    // 5000 particles
    _sizeVBO = 5000;

    // positions (point only)
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
    glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(b2Vec2), NULL, GL_DYNAMIC_DRAW);

    // colors
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[1]);
    glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(b2ParticleColor), NULL, GL_DYNAMIC_DRAW);

    // point sprite position
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[2]);
    glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(float), NULL, GL_DYNAMIC_DRAW);
    float *size = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    for(int i=0; i<_sizeVBO; i++) {
        float s = _particleSystem->GetRadius() * 2;
        size[i] = s + CCRANDOM_0_1() * s;
    }
    glUnmapBuffer(GL_ARRAY_BUFFER);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    CHECK_GL_ERROR_DEBUG();
}

// draw

void LFParticleSystemNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(LFParticleSystemNode::onDraw, this, transform, transformUpdated);
    renderer->addCommand(&_customCommand);
}

void LFParticleSystemNode::onDraw(const kmMat4 &transform, bool transformUpdated)
{
    // transform everything to PTM_RATIO
    kmMat4 newMV;
    kmMat4Multiply(&newMV, &_modelViewTransform, &_ratioTransform);
    getShaderProgram()->use();
    getShaderProgram()->setUniformsForBuiltins(newMV);

//    GL::blendFunc(_blendFunc.src, _blendFunc.dst);
    GL::bindTexture2D(_texture->getName());
    GL::blendFunc(_blendFunc.src, _blendFunc.dst);

    int totalParticles = _particleSystem->GetParticleCount();
    CCASSERT(totalParticles<_sizeVBO, "too many particles, increase VBO size");

    GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);

    // Update Positions
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
    b2Vec2 *positions = (b2Vec2*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    b2Vec2* posBuffer = _particleSystem->GetPositionBuffer();
    memcpy(positions, posBuffer, sizeof(positions[0]) * totalParticles);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(b2Vec2), NULL);

    // Colors
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[1]);
    b2ParticleColor *colors = (b2ParticleColor*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    b2ParticleColor* colorsBuffer = _particleSystem->GetColorBuffer();
    memcpy(colors, colorsBuffer, sizeof(colors[0]) * totalParticles);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(b2ParticleColor), NULL);

    // sizes
    glEnableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[2]);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(float), NULL);

    glDrawArrays(GL_POINTS, 0, totalParticles);
    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,totalParticles);

    // cleanup
    glDisableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    CHECK_GL_ERROR_DEBUG();
}

// Blend Interface

/// blendFunc getter
const BlendFunc& LFParticleSystemNode::getBlendFunc() const
{
    return _blendFunc;
}
/// blendFunc setter
void LFParticleSystemNode::setBlendFunc(const BlendFunc &var)
{
    _blendFunc = var;
}

<commit_msg>issue #4692: add condition to update the VBO.<commit_after>/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "LFParticleSystemNode.h"

// Custom Shader
static const GLchar* shaderVert = R"(
attribute vec4 a_position;
attribute vec4 a_color;
attribute float a_size;

#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
#else
varying vec4 v_fragmentColor;
#endif
void main()
{
    gl_Position = CC_PMatrix * CC_MVMatrix * a_position;
    gl_PointSize = CC_MVMatrix[0][0] * a_size;
    v_fragmentColor = a_color;
}
)";

static const GLchar* shaderFrag = R"(

#ifdef GL_ES
precision lowp float;
#endif
uniform sampler2D CC_Texture0;

varying vec4 v_fragmentColor;
void main()
{
    gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, gl_PointCoord);
}
)";

using namespace cocos2d;

LFParticleSystemNode* LFParticleSystemNode::create(b2ParticleSystem* particleSystem, float ratio)
{
    auto node = new LFParticleSystemNode;
    node->init(particleSystem, ratio);
    node->autorelease();

    return node;
}

bool LFParticleSystemNode::init(b2ParticleSystem* particleSystem, float ratio)
{
    _particleSystem = particleSystem;
    kmMat4Scaling(&_ratioTransform, ratio, ratio, 1);
    _ratio = ratio;

    // own shader
    GLProgram *p = new GLProgram;
    p->initWithByteArrays(shaderVert, shaderFrag);
    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
//    p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
    p->bindAttribLocation("a_size", 3);

    p->link();
    p->updateUniforms();

    this->setShaderProgram(p);
    p->release();

    setupVBO();

    auto textureCache = Director::getInstance()->getTextureCache();
    _texture = textureCache->addImage("Images/fire.png");

    _blendFunc = BlendFunc::ADDITIVE;

    return true;
}

void LFParticleSystemNode::setupVBO()
{
    glGenBuffers(3, &_buffersVBO[0]);

    // 5000 particles
    _sizeVBO = 5000;

    // positions (point only)
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
    glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(b2Vec2), NULL, GL_DYNAMIC_DRAW);

    // colors
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[1]);
    glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(b2ParticleColor), NULL, GL_DYNAMIC_DRAW);

    // point sprite position
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[2]);

    if (Configuration::getInstance()->supportsShareableVAO())
    {
        glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(float), NULL, GL_DYNAMIC_DRAW);
        float *size = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        for(int i=0; i<_sizeVBO; i++) {
            float s = _particleSystem->GetRadius() * 2;
            size[i] = s + CCRANDOM_0_1() * s;
        }
        glUnmapBuffer(GL_ARRAY_BUFFER);
    }
    else
    {
        float* size = (float*)malloc(_sizeVBO*sizeof(float));
        for(int i=0; i<_sizeVBO; i++) {
            float s = _particleSystem->GetRadius() * 2;
            size[i] = s + CCRANDOM_0_1() * s;
        }

        glBufferData(GL_ARRAY_BUFFER, _sizeVBO * sizeof(float), size, GL_DYNAMIC_DRAW);
        free(size);
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    CHECK_GL_ERROR_DEBUG();
}

// draw

void LFParticleSystemNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(LFParticleSystemNode::onDraw, this, transform, transformUpdated);
    renderer->addCommand(&_customCommand);
}

void LFParticleSystemNode::onDraw(const kmMat4 &transform, bool transformUpdated)
{
    // transform everything to PTM_RATIO
    kmMat4 newMV;
    kmMat4Multiply(&newMV, &_modelViewTransform, &_ratioTransform);
    getShaderProgram()->use();
    getShaderProgram()->setUniformsForBuiltins(newMV);

//    GL::blendFunc(_blendFunc.src, _blendFunc.dst);
    GL::bindTexture2D(_texture->getName());
    GL::blendFunc(_blendFunc.src, _blendFunc.dst);

    int totalParticles = _particleSystem->GetParticleCount();
    CCASSERT(totalParticles<_sizeVBO, "too many particles, increase VBO size");

    GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);

    if (Configuration::getInstance()->supportsShareableVAO())
    {
        // Update Positions
        glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
        b2Vec2 *positions = (b2Vec2*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        b2Vec2* posBuffer = _particleSystem->GetPositionBuffer();
        memcpy(positions, posBuffer, sizeof(positions[0]) * totalParticles);
        glUnmapBuffer(GL_ARRAY_BUFFER);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(b2Vec2), NULL);

        // Colors
        glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[1]);
        b2ParticleColor *colors = (b2ParticleColor*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        b2ParticleColor* colorsBuffer = _particleSystem->GetColorBuffer();
        memcpy(colors, colorsBuffer, sizeof(colors[0]) * totalParticles);
        glUnmapBuffer(GL_ARRAY_BUFFER);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(b2ParticleColor), NULL);
    }
    else
    {
        // Update Positions
        glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
        b2Vec2* posBuffer = _particleSystem->GetPositionBuffer();
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(posBuffer[0]) * totalParticles , posBuffer );
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(b2Vec2), NULL);

        // Colors
        glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[1]);
        b2ParticleColor* colorsBuffer = _particleSystem->GetColorBuffer();
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(colorsBuffer[0]) * totalParticles , colorsBuffer );
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(b2ParticleColor), NULL);
    }

    // sizes
    glEnableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[2]);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(float), NULL);

    glDrawArrays(GL_POINTS, 0, totalParticles);
    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,totalParticles);

    // cleanup
    glDisableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    CHECK_GL_ERROR_DEBUG();
}

// Blend Interface

/// blendFunc getter
const BlendFunc& LFParticleSystemNode::getBlendFunc() const
{
    return _blendFunc;
}
/// blendFunc setter
void LFParticleSystemNode::setBlendFunc(const BlendFunc &var)
{
    _blendFunc = var;
}

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/agc2/rnn_vad/lp_residual.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <numeric>

#include "rtc_base/checks.h"

namespace webrtc {
namespace rnn_vad {
namespace {

// Computes cross-correlation coefficients between |x| and |y| and writes them
// in |x_corr|. The lag values are in {0, ..., max_lag - 1}, where max_lag
// equals the size of |x_corr|.
// The |x| and |y| sub-arrays used to compute a cross-correlation coefficients
// for a lag l have both size "size of |x| - l" - i.e., the longest sub-array is
// used. |x| and |y| must have the same size.
void ComputeCrossCorrelation(
    rtc::ArrayView<const float> x,
    rtc::ArrayView<const float> y,
    rtc::ArrayView<float, kNumLpcCoefficients> x_corr) {
  constexpr size_t max_lag = x_corr.size();
  RTC_DCHECK_EQ(x.size(), y.size());
  RTC_DCHECK_LT(max_lag, x.size());
  for (size_t lag = 0; lag < max_lag; ++lag) {
    x_corr[lag] =
        std::inner_product(x.begin(), x.end() - lag, y.begin() + lag, 0.f);
  }
}

// Applies denoising to the auto-correlation coefficients.
void DenoiseAutoCorrelation(
    rtc::ArrayView<float, kNumLpcCoefficients> auto_corr) {
  // Assume -40 dB white noise floor.
  auto_corr[0] *= 1.0001f;
  for (size_t i = 1; i < kNumLpcCoefficients; ++i) {
    auto_corr[i] -= auto_corr[i] * (0.008f * i) * (0.008f * i);
  }
}

// Computes the initial inverse filter coefficients given the auto-correlation
// coefficients of an input frame.
void ComputeInitialInverseFilterCoefficients(
    rtc::ArrayView<const float, kNumLpcCoefficients> auto_corr,
    rtc::ArrayView<float, kNumLpcCoefficients - 1> lpc_coeffs) {
  float error = auto_corr[0];
  for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) {
    float reflection_coeff = 0.f;
    for (size_t j = 0; j < i; ++j) {
      reflection_coeff += lpc_coeffs[j] * auto_corr[i - j];
    }
    reflection_coeff += auto_corr[i + 1];

    // Avoid division by numbers close to zero.
    constexpr float kMinErrorMagnitude = 1e-6f;
    if (std::fabs(error) < kMinErrorMagnitude) {
      error = std::copysign(kMinErrorMagnitude, error);
    }

    reflection_coeff /= -error;
    // Update LPC coefficients and total error.
    lpc_coeffs[i] = reflection_coeff;
    for (size_t j = 0; j<(i + 1)>> 1; ++j) {
      const float tmp1 = lpc_coeffs[j];
      const float tmp2 = lpc_coeffs[i - 1 - j];
      lpc_coeffs[j] = tmp1 + reflection_coeff * tmp2;
      lpc_coeffs[i - 1 - j] = tmp2 + reflection_coeff * tmp1;
    }
    error -= reflection_coeff * reflection_coeff * error;
    if (error < 0.001f * auto_corr[0]) {
      break;
    }
  }
}

}  // namespace

void ComputeAndPostProcessLpcCoefficients(
    rtc::ArrayView<const float> x,
    rtc::ArrayView<float, kNumLpcCoefficients> lpc_coeffs) {
  std::array<float, kNumLpcCoefficients> auto_corr;
  ComputeCrossCorrelation(x, x, {auto_corr.data(), auto_corr.size()});
  if (auto_corr[0] == 0.f) {  // Empty frame.
    std::fill(lpc_coeffs.begin(), lpc_coeffs.end(), 0);
    return;
  }
  DenoiseAutoCorrelation({auto_corr.data(), auto_corr.size()});
  std::array<float, kNumLpcCoefficients - 1> lpc_coeffs_pre{};
  ComputeInitialInverseFilterCoefficients(auto_corr, lpc_coeffs_pre);
  // LPC coefficients post-processing.
  // TODO(bugs.webrtc.org/9076): Consider removing these steps.
  float c1 = 1.f;
  for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) {
    c1 *= 0.9f;
    lpc_coeffs_pre[i] *= c1;
  }
  const float c2 = 0.8f;
  lpc_coeffs[0] = lpc_coeffs_pre[0] + c2;
  lpc_coeffs[1] = lpc_coeffs_pre[1] + c2 * lpc_coeffs_pre[0];
  lpc_coeffs[2] = lpc_coeffs_pre[2] + c2 * lpc_coeffs_pre[1];
  lpc_coeffs[3] = lpc_coeffs_pre[3] + c2 * lpc_coeffs_pre[2];
  lpc_coeffs[4] = c2 * lpc_coeffs_pre[3];
}

void ComputeLpResidual(
    rtc::ArrayView<const float, kNumLpcCoefficients> lpc_coeffs,
    rtc::ArrayView<const float> x,
    rtc::ArrayView<float> y) {
  RTC_DCHECK_LT(kNumLpcCoefficients, x.size());
  RTC_DCHECK_EQ(x.size(), y.size());
  std::array<float, kNumLpcCoefficients> input_chunk;
  input_chunk.fill(0.f);
  for (size_t i = 0; i < y.size(); ++i) {
    const float sum = std::inner_product(input_chunk.begin(), input_chunk.end(),
                                         lpc_coeffs.begin(), x[i]);
    // Circular shift and add a new sample.
    for (size_t j = kNumLpcCoefficients - 1; j > 0; --j)
      input_chunk[j] = input_chunk[j - 1];
    input_chunk[0] = x[i];
    // Copy result.
    y[i] = sum;
  }
}

}  // namespace rnn_vad
}  // namespace webrtc
<commit_msg>fixed build on android<commit_after>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/agc2/rnn_vad/lp_residual.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <numeric>

#include "rtc_base/checks.h"

namespace webrtc {
namespace rnn_vad {
namespace {

// Computes cross-correlation coefficients between |x| and |y| and writes them
// in |x_corr|. The lag values are in {0, ..., max_lag - 1}, where max_lag
// equals the size of |x_corr|.
// The |x| and |y| sub-arrays used to compute a cross-correlation coefficients
// for a lag l have both size "size of |x| - l" - i.e., the longest sub-array is
// used. |x| and |y| must have the same size.
void ComputeCrossCorrelation(
    rtc::ArrayView<const float> x,
    rtc::ArrayView<const float> y,
    rtc::ArrayView<float, kNumLpcCoefficients> x_corr) {
  constexpr size_t max_lag = x_corr.size();
  RTC_DCHECK_EQ(x.size(), y.size());
  RTC_DCHECK_LT(max_lag, x.size());
  for (size_t lag = 0; lag < max_lag; ++lag) {
    x_corr[lag] =
        std::inner_product(x.begin(), x.end() - lag, y.begin() + lag, 0.f);
  }
}

// Applies denoising to the auto-correlation coefficients.
void DenoiseAutoCorrelation(
    rtc::ArrayView<float, kNumLpcCoefficients> auto_corr) {
  // Assume -40 dB white noise floor.
  auto_corr[0] *= 1.0001f;
  for (size_t i = 1; i < kNumLpcCoefficients; ++i) {
    auto_corr[i] -= auto_corr[i] * (0.008f * i) * (0.008f * i);
  }
}

// Computes the initial inverse filter coefficients given the auto-correlation
// coefficients of an input frame.
void ComputeInitialInverseFilterCoefficients(
    rtc::ArrayView<const float, kNumLpcCoefficients> auto_corr,
    rtc::ArrayView<float, kNumLpcCoefficients - 1> lpc_coeffs) {
  float error = auto_corr[0];
  for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) {
    float reflection_coeff = 0.f;
    for (size_t j = 0; j < i; ++j) {
      reflection_coeff += lpc_coeffs[j] * auto_corr[i - j];
    }
    reflection_coeff += auto_corr[i + 1];

    // Avoid division by numbers close to zero.
    constexpr float kMinErrorMagnitude = 1e-6f;
    if (std::fabs(error) < kMinErrorMagnitude) {
      error =static_cast<float>(copysign(kMinErrorMagnitude, error));
    }

    reflection_coeff /= -error;
    // Update LPC coefficients and total error.
    lpc_coeffs[i] = reflection_coeff;
    for (size_t j = 0; j<(i + 1)>> 1; ++j) {
      const float tmp1 = lpc_coeffs[j];
      const float tmp2 = lpc_coeffs[i - 1 - j];
      lpc_coeffs[j] = tmp1 + reflection_coeff * tmp2;
      lpc_coeffs[i - 1 - j] = tmp2 + reflection_coeff * tmp1;
    }
    error -= reflection_coeff * reflection_coeff * error;
    if (error < 0.001f * auto_corr[0]) {
      break;
    }
  }
}

}  // namespace

void ComputeAndPostProcessLpcCoefficients(
    rtc::ArrayView<const float> x,
    rtc::ArrayView<float, kNumLpcCoefficients> lpc_coeffs) {
  std::array<float, kNumLpcCoefficients> auto_corr;
  ComputeCrossCorrelation(x, x, {auto_corr.data(), auto_corr.size()});
  if (auto_corr[0] == 0.f) {  // Empty frame.
    std::fill(lpc_coeffs.begin(), lpc_coeffs.end(), 0);
    return;
  }
  DenoiseAutoCorrelation({auto_corr.data(), auto_corr.size()});
  std::array<float, kNumLpcCoefficients - 1> lpc_coeffs_pre{};
  ComputeInitialInverseFilterCoefficients(auto_corr, lpc_coeffs_pre);
  // LPC coefficients post-processing.
  // TODO(bugs.webrtc.org/9076): Consider removing these steps.
  float c1 = 1.f;
  for (size_t i = 0; i < kNumLpcCoefficients - 1; ++i) {
    c1 *= 0.9f;
    lpc_coeffs_pre[i] *= c1;
  }
  const float c2 = 0.8f;
  lpc_coeffs[0] = lpc_coeffs_pre[0] + c2;
  lpc_coeffs[1] = lpc_coeffs_pre[1] + c2 * lpc_coeffs_pre[0];
  lpc_coeffs[2] = lpc_coeffs_pre[2] + c2 * lpc_coeffs_pre[1];
  lpc_coeffs[3] = lpc_coeffs_pre[3] + c2 * lpc_coeffs_pre[2];
  lpc_coeffs[4] = c2 * lpc_coeffs_pre[3];
}

void ComputeLpResidual(
    rtc::ArrayView<const float, kNumLpcCoefficients> lpc_coeffs,
    rtc::ArrayView<const float> x,
    rtc::ArrayView<float> y) {
  RTC_DCHECK_LT(kNumLpcCoefficients, x.size());
  RTC_DCHECK_EQ(x.size(), y.size());
  std::array<float, kNumLpcCoefficients> input_chunk;
  input_chunk.fill(0.f);
  for (size_t i = 0; i < y.size(); ++i) {
    const float sum = std::inner_product(input_chunk.begin(), input_chunk.end(),
                                         lpc_coeffs.begin(), x[i]);
    // Circular shift and add a new sample.
    for (size_t j = kNumLpcCoefficients - 1; j > 0; --j)
      input_chunk[j] = input_chunk[j - 1];
    input_chunk[0] = x[i];
    // Copy result.
    y[i] = sum;
  }
}

}  // namespace rnn_vad
}  // namespace webrtc
<|endoftext|>


<commit_before>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are
    permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this list of
    conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright notice, this list
    of conditions and the following disclaimer in the documentation and/or other materials
    provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY JOE HERMASZEWSKI "AS IS" AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOE HERMASZEWSKI OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#include "declaration.hpp"

#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <parser/effect_factory.hpp>
#include <parser/parser.hpp>
#include <parser/terminal_types.hpp>
#include <parser/tokens/definition.hpp>
#include <parser/tokens/token.hpp>

namespace JoeLang
{
namespace Parser
{

//------------------------------------------------------------------------------
// DeclarationBase
//------------------------------------------------------------------------------

DeclarationBase::~DeclarationBase()
{
}

void DeclarationBase::Accept( EffectFactory& e )
{
}

bool DeclarationBase::Parse( Parser& parser, std::unique_ptr<DeclarationBase>& token )
{
    std::unique_ptr<Token> t;
    if( !ExpectAnyOf< TechniqueDeclaration,
                      PassDeclaration,
                      EmptyDeclaration>( parser, t ) )
        return false;

    Token* p = t.release();
    token.reset( dynamic_cast<DeclarationBase*>( p ) );
    if( !token )
    {
        delete p;
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
// EmptyDeclaration
//------------------------------------------------------------------------------

EmptyDeclaration::EmptyDeclaration()
{
}

EmptyDeclaration::~EmptyDeclaration()
{
}

void EmptyDeclaration::Print(int depth) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";
    std::cout << "Empty Declaration\n";
}

bool EmptyDeclaration::Parse( Parser& parser, std::unique_ptr<EmptyDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::SEMICOLON ) )
        return false;

    token.reset( new EmptyDeclaration );
    return true;
}

//------------------------------------------------------------------------------
// PassDeclaration
//------------------------------------------------------------------------------

PassDeclaration::PassDeclaration( std::string name, std::shared_ptr<PassDefinition> definition )
    :m_name( std::move( name ) )
    ,m_definition( std::move( definition ) )
{
}

PassDeclaration::~PassDeclaration()
{
}

const std::shared_ptr<PassDefinition>& PassDeclaration::GetDefinition() const
{
    return m_definition;
}

void PassDeclaration::Print( int depth ) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";

    std::cout << "Pass: " << ( m_name.size() ? m_name : "Unnamed" ) << "\n";
    if( m_definition )
    {
        m_definition->Print( depth + 1);
    }
    else
    {
        for( int i = 0; i < depth * 4; ++i )
            std::cout << " ";
        std::cout << "No definition\n";
    }
}

bool PassDeclaration::Parse( Parser& parser, std::unique_ptr<PassDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::PASS ) )
        return false;

    std::string name;
    if( !parser.ExpectTerminal( Lexer::IDENTIFIER, name ) )
        return false;

    if( parser.ExpectTerminal( Lexer::SEMICOLON ) )
    {
        //
        // This is a regular declaration
        // TODO: Look up the name in a table and create links and things
        //
        token.reset( new PassDeclaration( name, nullptr ) );
        return true;
    }
    CHECK_PARSER;

    //
    // This declaration is also has a definition
    //
    std::unique_ptr< PassDefinition > definition;

    if( !Expect<PassDefinition>( parser, definition ) )
        return false;

    definition->SetName( name );

    token.reset( new PassDeclaration( std::move(name),
                                      std::move(definition) ) );
    return true;
}

//------------------------------------------------------------------------------
// TechniqueDeclaration
//------------------------------------------------------------------------------

TechniqueDeclaration::TechniqueDeclaration( std::string name, std::shared_ptr<TechniqueDefinition> definition )
    :m_name( std::move( name ) )
    ,m_definition( std::move( definition ) )
{
}

TechniqueDeclaration::~TechniqueDeclaration()
{
}

void TechniqueDeclaration::Accept( EffectFactory& e )
{
    e.Visit( *this );
}

const std::shared_ptr<TechniqueDefinition>& TechniqueDeclaration::GetDefinition() const
{
    return m_definition;
}

void TechniqueDeclaration::Print( int depth ) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";

    std::cout << "Technique: " << ( m_name.size() ? m_name : "Unnamed" ) << "\n";
    if( m_definition )
    {
        m_definition->Print( depth + 1);
    }
    else
    {
        for( int i = 0; i < depth * 4 + 4; ++i )
            std::cout << " ";
        std::cout << "No definition\n";
    }
}

bool TechniqueDeclaration::Parse( Parser& parser, std::unique_ptr<TechniqueDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::TECHNIQUE ) )
        return false;

    std::string name;
    if( !parser.ExpectTerminal( Lexer::IDENTIFIER, name ) )
        return false;

    if( parser.ExpectTerminal( Lexer::SEMICOLON ) )
    {
        //
        // This is a regular declaration
        // TODO: Look up the name in a table and create links and things
        //
        token.reset( new TechniqueDeclaration( name, nullptr ) );
        return true;
    }
    CHECK_PARSER;

    //
    // This declaration is also a definition
    //
    std::unique_ptr< TechniqueDefinition > definition;

    if( !Expect<TechniqueDefinition>( parser, definition ) )
        return false;

    token.reset( new TechniqueDeclaration( std::move(name),
                                           std::move(definition) ) );
    return true;
}

} // namespace Parser
} // namespace JoeLang
<commit_msg>[+] Setting TechniqueDefinition name<commit_after>/*
    Copyright 2011 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are
    permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this list of
    conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright notice, this list
    of conditions and the following disclaimer in the documentation and/or other materials
    provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY JOE HERMASZEWSKI "AS IS" AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOE HERMASZEWSKI OR
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    The views and conclusions contained in the software and documentation are those of the
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Joe Hermaszewski.
*/

#include "declaration.hpp"

#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <parser/effect_factory.hpp>
#include <parser/parser.hpp>
#include <parser/terminal_types.hpp>
#include <parser/tokens/definition.hpp>
#include <parser/tokens/token.hpp>

namespace JoeLang
{
namespace Parser
{

//------------------------------------------------------------------------------
// DeclarationBase
//------------------------------------------------------------------------------

DeclarationBase::~DeclarationBase()
{
}

void DeclarationBase::Accept( EffectFactory& e )
{
}

bool DeclarationBase::Parse( Parser& parser, std::unique_ptr<DeclarationBase>& token )
{
    std::unique_ptr<Token> t;
    if( !ExpectAnyOf< TechniqueDeclaration,
                      PassDeclaration,
                      EmptyDeclaration>( parser, t ) )
        return false;

    Token* p = t.release();
    token.reset( dynamic_cast<DeclarationBase*>( p ) );
    if( !token )
    {
        delete p;
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
// EmptyDeclaration
//------------------------------------------------------------------------------

EmptyDeclaration::EmptyDeclaration()
{
}

EmptyDeclaration::~EmptyDeclaration()
{
}

void EmptyDeclaration::Print(int depth) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";
    std::cout << "Empty Declaration\n";
}

bool EmptyDeclaration::Parse( Parser& parser, std::unique_ptr<EmptyDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::SEMICOLON ) )
        return false;

    token.reset( new EmptyDeclaration );
    return true;
}

//------------------------------------------------------------------------------
// PassDeclaration
//------------------------------------------------------------------------------

PassDeclaration::PassDeclaration( std::string name, std::shared_ptr<PassDefinition> definition )
    :m_name( std::move( name ) )
    ,m_definition( std::move( definition ) )
{
}

PassDeclaration::~PassDeclaration()
{
}

const std::shared_ptr<PassDefinition>& PassDeclaration::GetDefinition() const
{
    return m_definition;
}

void PassDeclaration::Print( int depth ) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";

    std::cout << "Pass: " << ( m_name.size() ? m_name : "Unnamed" ) << "\n";
    if( m_definition )
    {
        m_definition->Print( depth + 1);
    }
    else
    {
        for( int i = 0; i < depth * 4; ++i )
            std::cout << " ";
        std::cout << "No definition\n";
    }
}

bool PassDeclaration::Parse( Parser& parser, std::unique_ptr<PassDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::PASS ) )
        return false;

    std::string name;
    if( !parser.ExpectTerminal( Lexer::IDENTIFIER, name ) )
        return false;

    if( parser.ExpectTerminal( Lexer::SEMICOLON ) )
    {
        //
        // This is a regular declaration
        // TODO: Look up the name in a table and create links and things
        //
        token.reset( new PassDeclaration( name, nullptr ) );
        return true;
    }
    CHECK_PARSER;

    //
    // This declaration is also has a definition
    //
    std::unique_ptr< PassDefinition > definition;

    if( !Expect<PassDefinition>( parser, definition ) )
        return false;

    definition->SetName( name );

    token.reset( new PassDeclaration( std::move(name),
                                      std::move(definition) ) );
    return true;
}

//------------------------------------------------------------------------------
// TechniqueDeclaration
//------------------------------------------------------------------------------

TechniqueDeclaration::TechniqueDeclaration( std::string name, std::shared_ptr<TechniqueDefinition> definition )
    :m_name( std::move( name ) )
    ,m_definition( std::move( definition ) )
{
}

TechniqueDeclaration::~TechniqueDeclaration()
{
}

void TechniqueDeclaration::Accept( EffectFactory& e )
{
    e.Visit( *this );
}

const std::shared_ptr<TechniqueDefinition>& TechniqueDeclaration::GetDefinition() const
{
    return m_definition;
}

void TechniqueDeclaration::Print( int depth ) const
{
    for( int i = 0; i < depth * 4; ++i )
        std::cout << " ";

    std::cout << "Technique: " << ( m_name.size() ? m_name : "Unnamed" ) << "\n";
    if( m_definition )
    {
        m_definition->Print( depth + 1);
    }
    else
    {
        for( int i = 0; i < depth * 4 + 4; ++i )
            std::cout << " ";
        std::cout << "No definition\n";
    }
}

bool TechniqueDeclaration::Parse( Parser& parser, std::unique_ptr<TechniqueDeclaration>& token )
{
    if( !parser.ExpectTerminal( Lexer::TECHNIQUE ) )
        return false;

    std::string name;
    if( !parser.ExpectTerminal( Lexer::IDENTIFIER, name ) )
        return false;

    if( parser.ExpectTerminal( Lexer::SEMICOLON ) )
    {
        //
        // This is a regular declaration
        // TODO: Look up the name in a table and create links and things
        //
        token.reset( new TechniqueDeclaration( name, nullptr ) );
        return true;
    }
    CHECK_PARSER;

    //
    // This declaration is also a definition
    //
    std::unique_ptr< TechniqueDefinition > definition;

    if( !Expect<TechniqueDefinition>( parser, definition ) )
        return false;

    definition->SetName( name );

    token.reset( new TechniqueDeclaration( std::move(name),
                                           std::move(definition) ) );
    return true;
}

} // namespace Parser
} // namespace JoeLang
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "ui_TaskPatternRectangularParameters.h"
#include "TaskPatternRectangularParameters.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>

using namespace PartDesignGui;
using namespace Gui;

/* TRANSLATOR PartDesignGui::TaskPatternRectangularParameters */

TaskPatternRectangularParameters::TaskPatternRectangularParameters(QWidget *parent)
    : TaskBox(Gui::BitmapFactory().pixmap("document-new"),tr("TaskPatternRectangularParameters"),true, parent)
{
    // we need a separate container widget to add all controls to
    proxy = new QWidget(this);
    ui = new Ui_TaskPatternRectangularParameters();
    ui->setupUi(proxy);
    QMetaObject::connectSlotsByName(this);

    this->groupLayout()->addWidget(proxy);

    Gui::Selection().Attach(this);
}

TaskPatternRectangularParameters::~TaskPatternRectangularParameters()
{
    delete ui;
    Gui::Selection().Detach(this);
}

void TaskPatternRectangularParameters::changeEvent(QEvent *e)
{
    TaskBox::changeEvent(e);
    if (e->type() == QEvent::LanguageChange) {
        ui->retranslateUi(proxy);
    }
}

/// @cond DOXERR
void TaskPatternRectangularParameters::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
                              Gui::SelectionSingleton::MessageType Reason)
{
    if (Reason.Type == SelectionChanges::AddSelection ||
        Reason.Type == SelectionChanges::RmvSelection ||
        Reason.Type == SelectionChanges::SetSelection ||
        Reason.Type == SelectionChanges::ClrSelection) {
    }
}
/// @endcond

//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

TaskDlgPatternRectangularParameters::TaskDlgPatternRectangularParameters(ViewProviderPatternRectangular *PatternRectangularView)
    : TaskDialog(),PatternRectangularView(PatternRectangularView)
{
    assert(PatternRectangularView);
    parameter  = new TaskPatternRectangularParameters();

    Content.push_back(parameter);
}

TaskDlgPatternRectangularParameters::~TaskDlgPatternRectangularParameters()
{

}

//==== calls from the TaskView ===============================================================

void TaskDlgPatternRectangularParameters::open()
{

}

void TaskDlgPatternRectangularParameters::clicked(int)
{

}

bool TaskDlgPatternRectangularParameters::accept()
{
    return true;
}

bool TaskDlgPatternRectangularParameters::reject()
{
    Gui::Command::openCommand("PatternRectangular changed");
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
    Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
    Gui::Command::commitCommand();

    return true;
}

void TaskDlgPatternRectangularParameters::helpRequested()
{

}

#include "moc_TaskPatternRectangularParameters.cpp"
<commit_msg>Fix title is task panel for rectangular pattern<commit_after>/***************************************************************************
 *   Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "ui_TaskPatternRectangularParameters.h"
#include "TaskPatternRectangularParameters.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>

using namespace PartDesignGui;
using namespace Gui;

/* TRANSLATOR PartDesignGui::TaskPatternRectangularParameters */

TaskPatternRectangularParameters::TaskPatternRectangularParameters(QWidget *parent)
    : TaskBox(Gui::BitmapFactory().pixmap("document-new"),tr("Parameters rectangular pattern"),true, parent)
{
    // we need a separate container widget to add all controls to
    proxy = new QWidget(this);
    ui = new Ui_TaskPatternRectangularParameters();
    ui->setupUi(proxy);
    QMetaObject::connectSlotsByName(this);

    this->groupLayout()->addWidget(proxy);

    Gui::Selection().Attach(this);
}

TaskPatternRectangularParameters::~TaskPatternRectangularParameters()
{
    delete ui;
    Gui::Selection().Detach(this);
}

void TaskPatternRectangularParameters::changeEvent(QEvent *e)
{
    TaskBox::changeEvent(e);
    if (e->type() == QEvent::LanguageChange) {
        ui->retranslateUi(proxy);
    }
}

/// @cond DOXERR
void TaskPatternRectangularParameters::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
                              Gui::SelectionSingleton::MessageType Reason)
{
    if (Reason.Type == SelectionChanges::AddSelection ||
        Reason.Type == SelectionChanges::RmvSelection ||
        Reason.Type == SelectionChanges::SetSelection ||
        Reason.Type == SelectionChanges::ClrSelection) {
    }
}
/// @endcond

//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

TaskDlgPatternRectangularParameters::TaskDlgPatternRectangularParameters(ViewProviderPatternRectangular *PatternRectangularView)
    : TaskDialog(),PatternRectangularView(PatternRectangularView)
{
    assert(PatternRectangularView);
    parameter  = new TaskPatternRectangularParameters();

    Content.push_back(parameter);
}

TaskDlgPatternRectangularParameters::~TaskDlgPatternRectangularParameters()
{

}

//==== calls from the TaskView ===============================================================

void TaskDlgPatternRectangularParameters::open()
{

}

void TaskDlgPatternRectangularParameters::clicked(int)
{

}

bool TaskDlgPatternRectangularParameters::accept()
{
    return true;
}

bool TaskDlgPatternRectangularParameters::reject()
{
    Gui::Command::openCommand("PatternRectangular changed");
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
    Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
    Gui::Command::commitCommand();

    return true;
}

void TaskDlgPatternRectangularParameters::helpRequested()
{

}

#include "moc_TaskPatternRectangularParameters.cpp"
<|endoftext|>


<commit_before>#include "AlertHandlerWormhole.h"
#include "XPathExtractor.h"
#include <string.h>
#include <libwatcher/labelMessage.h>
#include <libwatcher/edgeMessage.h>

using namespace HierarchyAPI;
using namespace SpartaIssoSrdXmlAPI;
using namespace watcher;
using namespace watcher::event;

INIT_LOGGER(AlertHandlerWormhole, "AlertHandler.AlertHandlerWormhole");

AlertHandlerWormhole::AlertHandlerWormhole()
{
	// noop
}

//virtual
AlertHandlerWormhole::~AlertHandlerWormhole()
{
	// noop
}

bool AlertHandlerWormhole::handleAlert(const xmlDoc* alertMessage, watcher::ClientPtr client)
{
	TRACE_ENTER();

	string* attacker1AddrStr=XPathExtractor::extractFromDocUsing(alertMessage, "/IDMEF-Message/Alert/Source[1]/Node/Address[@category='ipv4-addr']/address");
	string* attacker2AddrStr=XPathExtractor::extractFromDocUsing(alertMessage, "/IDMEF-Message/Alert/Source[2]/Node/Address[@category='ipv4-addr']/address");

	if(attacker1AddrStr && attacker2AddrStr)
	{
	    LOG_DEBUG("Marking " << *attacker1AddrStr << " and " << *attacker2AddrStr << " as ends of the wormhole");

        const string layer("Alerts");
        LabelMessagePtr lm(new LabelMessage("Detected Wormhole"));
        lm->layer=layer;

        EdgeMessagePtr em(new EdgeMessage(NodeIdentifier::from_string(*attacker1AddrStr), NodeIdentifier::from_string(*attacker2AddrStr), layer));
        em->expiration=m_alertLabelTimeout*1000;
        em->middleLabel=(LabelMessagePtr(new LabelMessage("Wormhole")));

        std::vector<event::MessagePtr> messages;
        messages.push_back(lm);
        messages.push_back(em);
        if (!client->sendMessages(messages))
            LOG_WARN("Error sending wormhole alert messages to the watcher");
	}

	if(attacker1AddrStr)
        delete attacker1AddrStr;
	if(attacker2AddrStr)
        delete attacker2AddrStr;

	TRACE_EXIT();
	return true;
}

<commit_msg>label expiration was not being set when handling WH alerts.<commit_after>#include "AlertHandlerWormhole.h"
#include "XPathExtractor.h"
#include <string.h>
#include <libwatcher/labelMessage.h>
#include <libwatcher/edgeMessage.h>

using namespace HierarchyAPI;
using namespace SpartaIssoSrdXmlAPI;
using namespace watcher;
using namespace watcher::event;

INIT_LOGGER(AlertHandlerWormhole, "AlertHandler.AlertHandlerWormhole");

AlertHandlerWormhole::AlertHandlerWormhole()
{
	// noop
}

//virtual
AlertHandlerWormhole::~AlertHandlerWormhole()
{
	// noop
}

bool AlertHandlerWormhole::handleAlert(const xmlDoc* alertMessage, watcher::ClientPtr client)
{
	TRACE_ENTER();

	string* attacker1AddrStr=XPathExtractor::extractFromDocUsing(alertMessage, "/IDMEF-Message/Alert/Source[1]/Node/Address[@category='ipv4-addr']/address");
	string* attacker2AddrStr=XPathExtractor::extractFromDocUsing(alertMessage, "/IDMEF-Message/Alert/Source[2]/Node/Address[@category='ipv4-addr']/address");

	if(attacker1AddrStr && attacker2AddrStr)
	{
	    LOG_DEBUG("Marking " << *attacker1AddrStr << " and " << *attacker2AddrStr << " as ends of the wormhole");

        const string layer("Alerts");
        LabelMessagePtr lm(new LabelMessage("Detected Wormhole"));
        lm->expiration=m_alertLabelTimeout*1000;
        lm->layer=layer;

        EdgeMessagePtr em(new EdgeMessage(NodeIdentifier::from_string(*attacker1AddrStr), NodeIdentifier::from_string(*attacker2AddrStr), layer));
        em->expiration=m_alertLabelTimeout*1000;
        em->middleLabel=(LabelMessagePtr(new LabelMessage("Wormhole")));

        std::vector<event::MessagePtr> messages;
        messages.push_back(lm);
        messages.push_back(em);
        if (!client->sendMessages(messages))
            LOG_WARN("Error sending wormhole alert messages to the watcher");
	}

	if(attacker1AddrStr)
        delete attacker1AddrStr;
	if(attacker2AddrStr)
        delete attacker2AddrStr;

	TRACE_EXIT();
	return true;
}

<|endoftext|>