tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_tone.cpp (3332B)


      1 /*
      2 * Copyright © 2011 Mozilla Foundation
      3 *
      4 * This program is made available under an ISC-style license.  See the
      5 * accompanying file LICENSE for details.
      6 */
      7 
      8 /* libcubeb api/function test. Plays a simple tone. */
      9 #include "gtest/gtest.h"
     10 #if !defined(_XOPEN_SOURCE)
     11 #define _XOPEN_SOURCE 600
     12 #endif
     13 #include "cubeb/cubeb.h"
     14 #include <atomic>
     15 #include <limits.h>
     16 #include <math.h>
     17 #include <memory>
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 
     21 // #define ENABLE_NORMAL_LOG
     22 // #define ENABLE_VERBOSE_LOG
     23 #include "common.h"
     24 
     25 #define SAMPLE_FREQUENCY 48000
     26 #define STREAM_FORMAT CUBEB_SAMPLE_S16LE
     27 
     28 /* store the phase of the generated waveform */
     29 struct cb_user_data {
     30  std::atomic<long> position;
     31 };
     32 
     33 long
     34 data_cb_tone(cubeb_stream * stream, void * user, const void * /*inputbuffer*/,
     35             void * outputbuffer, long nframes)
     36 {
     37  struct cb_user_data * u = (struct cb_user_data *)user;
     38  short * b = (short *)outputbuffer;
     39  float t1, t2;
     40  int i;
     41 
     42  if (stream == NULL || u == NULL)
     43    return CUBEB_ERROR;
     44 
     45  /* generate our test tone on the fly */
     46  for (i = 0; i < nframes; i++) {
     47    /* North American dial tone */
     48    t1 = sin(2 * M_PI * (i + u->position) * 350 / SAMPLE_FREQUENCY);
     49    t2 = sin(2 * M_PI * (i + u->position) * 440 / SAMPLE_FREQUENCY);
     50    b[i] = (SHRT_MAX / 2) * t1;
     51    b[i] += (SHRT_MAX / 2) * t2;
     52    /* European dial tone */
     53    /*
     54    t1 = sin(2*M_PI*(i + u->position)*425/SAMPLE_FREQUENCY);
     55    b[i]  = SHRT_MAX * t1;
     56    */
     57  }
     58  /* remember our phase to avoid clicking on buffer transitions */
     59  /* we'll still click if position overflows */
     60  u->position += nframes;
     61 
     62  return nframes;
     63 }
     64 
     65 void
     66 state_cb_tone(cubeb_stream * stream, void * user, cubeb_state state)
     67 {
     68  struct cb_user_data * u = (struct cb_user_data *)user;
     69 
     70  if (stream == NULL || u == NULL)
     71    return;
     72 
     73  switch (state) {
     74  case CUBEB_STATE_STARTED:
     75    fprintf(stderr, "stream started\n");
     76    break;
     77  case CUBEB_STATE_STOPPED:
     78    fprintf(stderr, "stream stopped\n");
     79    break;
     80  case CUBEB_STATE_DRAINED:
     81    fprintf(stderr, "stream drained\n");
     82    break;
     83  default:
     84    fprintf(stderr, "unknown stream state %d\n", state);
     85  }
     86 
     87  return;
     88 }
     89 
     90 TEST(cubeb, tone)
     91 {
     92  cubeb * ctx;
     93  cubeb_stream * stream;
     94  cubeb_stream_params params;
     95  int r;
     96 
     97  r = common_init(&ctx, "Cubeb tone example");
     98  ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb library";
     99 
    100  std::unique_ptr<cubeb, decltype(&cubeb_destroy)> cleanup_cubeb_at_exit(
    101      ctx, cubeb_destroy);
    102 
    103  params.format = STREAM_FORMAT;
    104  params.rate = SAMPLE_FREQUENCY;
    105  params.channels = 1;
    106  params.layout = CUBEB_LAYOUT_MONO;
    107  params.prefs = CUBEB_STREAM_PREF_NONE;
    108 
    109  std::unique_ptr<cb_user_data> user_data(new cb_user_data());
    110  ASSERT_TRUE(!!user_data) << "Error allocating user data";
    111 
    112  user_data->position = 0;
    113 
    114  r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", NULL, NULL, NULL,
    115                        &params, 4096, data_cb_tone, state_cb_tone,
    116                        user_data.get());
    117  ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream";
    118 
    119  std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)>
    120      cleanup_stream_at_exit(stream, cubeb_stream_destroy);
    121 
    122  cubeb_stream_start(stream);
    123  delay(5000);
    124  cubeb_stream_stop(stream);
    125 
    126  ASSERT_TRUE(user_data->position.load());
    127 }
    128 
    129 #undef SAMPLE_FREQUENCY
    130 #undef STREAM_FORMAT