Giter Club home page Giter Club logo

sig-gen's Introduction

Logo Signal Generator .github/workflows/main.yml Release

Get it on F-Droid

A signal generator for Android. The app can be downloaded from F-Droid and here.

  • Frequency range 0.1Hz - 25KHz
  • Level range 0dB - -80dB
  • Set exact frequency
  • Frequency bookmarks
  • Square wave duty cycle
  • Shortcut
  • External control

Using

The frequency knob responds to finger twirling. The duty cycle, fine frequency and level sliders allow for adjustments of square wave duty cycle, fine frequency and output level. The frequency knob is also adjustable using the left and right arrow buttons above. The two bookmark buttons below the frequency knob show if there are bookmarks, and will go to the next lower or higher bookmark if it exists.

The toolbar items are, from left to right:

  • Exact - Prompt for an exact frequency
  • Bookmark - Save the current frequency as a bookmark
  • Sleep - Prevent the device from sleeping

To remove a bookmark, go to it and touch the toolbar bookmark button.

Shortcut

A shortcut may be created to set the parameters shown below. Empty frequency, duty cycle and level values and unchecked waveform values will not be included. The mute value will always be included. The name of the shortcut will be composed from the set values if the name field is empty.

External Control

The app may be started, the frequency, level, duty cycle, waveform and mute set externally by sending a suitable Intent from an automation app. The app package/activity is org.billthefarmer.siggen/org.billthefarmer.siggen.Main. The parameters may be:

Parameter Action/Category/Extra Type Value
Action android.intent.action.MAIN
android.intent.action.DEFAULT
Category android.intent.category.LAUNCHER
android.intent.category.DEFAULT
Extras org.billthefarmer.siggen.SET_FREQ int, float 0.1 – 25000
org.billthefarmer.siggen.SET_LEVEL int, float -80 – 0
org.billthefarmer.siggen.SET_DUTY int, float 0 – 100
org.billthefarmer.siggen.SET_WAVE int 0 = Sine
1 = Square
2 = Sawtooth
org.billthefarmer.siggen.SET_MUTE boolean true, false

Any combination of extras or none may be sent. Subsequent intents sent will update the values from the included extras.

This may be tested using the Android Debug Bridge.

$ adb shell am start --ef org.billthefarmer.siggen.SET_FREQ 257.3 --ef org.billthefarmer.siggen.SET_LEVEL -25.2 org.billthefarmer.siggen/.Main
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=org.billthefarmer.siggen/.Main (has extras) }
$ adb shell am start --ez org.billthefarmer.siggen.SET_MUTE true org.billthefarmer.siggen/.Main
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=org.billthefarmer.siggen/.Main (has extras) }
Warning: Activity not started, its current task has been brought to the front

sig-gen's People

Contributors

adiloguz avatar afmachado avatar billthefarmer avatar tacothedank avatar wh201906 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sig-gen's Issues

Change number of steps for volume slider to a multiple of 80

The volume slider has a range from -80dB to 0dB, which is currently devided into 100 steps -> 0.8dB per step.
I think it would be nicer to have a multiple of 80 for the number of steps,
e.g. 160 which would give 0.5dB steps or 240 for 1/3dB steps.

missing documentations

missing documentations for setting up a development environment

This will sound idiotic but I'm trying to fork this app for an custom project and I can't get it to build.

when I just open the project in a text editor of choice (vscode) intellisense and Linting does not work because

Main.java is not on the classpath of project sig-gen, only syntax errors are reported

When I try to run the gradlew.bat script I get this error:

Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Caused by: java.lang.ClassNotFoundException: org.gradle.wrapper.GradleWrapperMain

I know of the Android Studio from Google and installed it and opened the project in it. Besides it being ridiculously cpu expensive I could not figure out how to get it build or even just error highlighting (Linting) to work.
I'm kinda lost.
How do you build this thing?

missing documentations for code and variables.

the Main.java is of most interest to me so I'll take an example from there. more specific the processAudio method at the very end.

duty, t, K, f, level, q, l
what are the number ranges for these variables?
what do they represent?
why is there so much Pi involved?
what is the purpose of these cryptic one letter variables?
if f stands for frequency, what does frequency stand for? poor naming and no meaningful comments!

If I'd design this code I'd assume I get

  • a buffersize
  • a sampling rate
  • audio volume level as a float ranging from 0 to 1
  • the frequency as a float ranging from 0.1 to 25000
  • and the duty cycle as a float ranging from 0 to 1

Then I iterate over the buffersize. using the sampling rate I can calculate the time step between each iteration and increment a global ms variable each time by that amount. that variable I then can use to calculate the waveforms.
The output audio samples are a float ranging from 0 to 1

I would greatly appreciate comments that describe the valid number range and purpose so that I don't have to reverse engineer the whole app (if I could get it to build in the first place) just to make a few tweaks.

Allow entering exact frequency with on-screen keyboard ?

I wanted to try a 440Hz but could not get there, the closer I could get was 440.05.
This is on a smartphone, so maybe with a tablet it's easier, anyway I've been hoping I could tap on the frequency indicator to enter a number with the on-screen keyboard. Just a feature request.

I love what you're making for music players, thank you !

Russian translation src/main/res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="pref_theme_entries">
        <item>Светлая</item>
        <item>Тёмная</item>
        <item>Системная</item>
    </string-array>
    <string-array name="pref_theme_entry_values">
        <item>0</item>
        <item>1</item>
        <item>2</item>
    </string-array>
</resources>

buttons covering "mute" button

after the latest update, instead of the tuning buttons floating near the "mute" button, they now directly cover it up

Tone starts playing immediately upon opening

It's very jarring to have the tone start playing immediately and can annoy people around. I think it should be muted by default or not play a tone until the frequency is changed.

Android phone play fixed frequency of square wave

Can't play square wave。It is a fixed frequency of square wave, playing on the phone. According to your project, I extract the code.

As follows:

protected class Audio implements Runnable
{
protected static final int SINE = 0;
protected static final int SQUARE = 1;
protected static final int SAWTOOTH = 2;

protected int waveform ;
protected boolean mute;

protected double frequency;
protected double level;

protected Thread thread;

private AudioTrack audioTrack;

protected Audio()
{
    frequency = 270.0;
    level = 16384;
}

// Start
protected void start()
{
    thread = new Thread(this, "Audio");
    thread.start();
}

// Stop
protected void stop()
{
    Thread t = thread;
    thread = null;

    // Wait for the thread to exit
    while (t != null && t.isAlive())
        Thread.yield();
}

public void run()
{
    processAudio();
}

// Process audio
protected void processAudio()
{
    short buffer[];

    int rate =
            AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
    int minSize =
            AudioTrack.getMinBufferSize(rate, AudioFormat.CHANNEL_OUT_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

    // Find a suitable buffer size
    int sizes[] = {1024, 2048, 4096, 8192, 16384, 32768};
    int size = 0;

    for (int s : sizes)
    {
        if (s > minSize)
        {
            size = s;
            break;
        }
    }

    final double K = 2.0 * Math.PI / rate;

    // Create the audio track
    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate,
            AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            size, AudioTrack.MODE_STREAM);
    // Check audiotrack
    if (audioTrack == null)
        return;

    // Check state
    int state = audioTrack.getState();

    if (state != AudioTrack.STATE_INITIALIZED)
    {
        audioTrack.release();
        return;
    }

    audioTrack.play();

    // Create the buffer
    buffer = new short[size];

    // Initialise the generator variables
    double f = frequency;
    double l = 0.0;
    double q = 0.0;

    while (thread != null)
    {
        // Fill the current buffer
        for (int i = 0; i < buffer.length; i++)
        {
            f += (frequency - f) / 4096.0;
             l += ((mute ? 0.0 : level) * 16384.0 - l) / 4096.0;
             q += (q < Math.PI) ? f * K : (f * K) - (2.0 * Math.PI);

           switch (waveform)
            {
                case SINE:
                    buffer[i] = (short) Math.round(Math.sin(q) * l);
                    break;

                case SQUARE:
                    buffer[i] = (short) ((q > 0.0) ? l : -l);
                break;

                case SAWTOOTH:
                    buffer[i] = (short) Math.round((q / Math.PI) * l);
                    break;
            }
        }

        audioTrack.write(buffer, 0, buffer.length);
    }

    audioTrack.stop();
    audioTrack.release();
}

}
Direct calls in the project:

@OverRide
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

        audio = new Audio();
        audio.start();
        if (audio != null)
            audio.waveform = Audio.SQUARE;
    }
}

The sound of the play is not like the sound of square wave. I don't know where there's a mistake.
And the sound of the play is not always there, and it stops for a moment.

Russian translation src/main/res/values-ru/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <string name="app_name">Генератор сигналов</string>
  <string name="copyright">Владелец \u00A9 2017 <a href="https://billthefarmer.github.io">Билл Фармер</a>
  </string>
  <string name="licence">Лицензия <a href="https://www.gnu.org/licenses/gpl.txt">GNU GPLv3</a>
  </string>
  <string name="built">Сборка %s</string>

  <string name="settings">Настройки</string>
  <string name="help">Справка</string>
  <string name="sleep">Без сна</string>
  <string name="exact">Указать точнее</string>
  <string name="bookmark">В закладку</string>
  <string name="name">Имя</string>
  <string name="frequency">Частота</string>
  <string name="level">Уровень сигнала</string>
  <string name="duty">Рабочий цикл</string>
  <string name="enter">Введите частоту</string>
  <string name="cancel">Отмена</string>
  <string name="create">Создать</string>
  <string name="clear">Очистить</string>
  <string name="ok">OK</string>

  <string name="bookmark_added">Закладка добавлена %1.2f</string>
  <string name="bookmark_removed">Закладка удалена %1.2f</string>

  <string name="sine">Синусоидальная волна</string>
  <string name="sin">Синус</string>
  <string name="s">S</string>
  <string name="square">Квадратная волна</string>
  <string name="squ">Квадрат</string>
  <string name="q">Q</string>
  <string name="sawtooth">Пилообразная волна</string>
  <string name="saw">Пила</string>
  <string name="w">W</string>

  <string name="mute">Тишина</string>

  <string name="pref_about">О программе</string>
  <string name="pref_about_summ">Генератор сигналов <a href="https://github.com/billthefarmer/sig-gen/releases/latest">версии %s</a></string>

  <string name="pref_theme">Тема</string>
  <string translatable="false" name="pref_theme_summ">%s</string>

</resources>

the problem is in the interface

my interface is not very nicely shown. the buttons overlap each other. the numbers are superimposed.

Signal Generator 1.22 (122) F-Droid
Andrion 9.0
Xiaomi Redmi Note 7

bug

Fine Adjustment setting does nothing

There are some buttons which I assume have a connection to the setting but the setting doesn't change anything and no matter what I chose, it turns out deactivated if I return to the main screen and go back to the settings.

Android 12 volume trouble

I have Android 12 and it works well on Android 11 but breaks up and loses volume on Android 12.
Great app.

Interface broken after upgrade

Hi. I just upgraded to the latest version via f-droid and now the interface is broken, making the app pretty much unusable. See screenshot. I am running cyanogenmod ob a samsung galaxy S3. Let me know if there's any other relevant info you need 🙂
screenshot_20170305-195126

possible virus in sig-gen

Malwarebytes 2.1.1.6 (for Android) with the latest database is reporting that Signal Generator 1.10 has a virus (see screen below). I assume that is a "false positive" but can you look into this? I downloaded Signal Generator 1.10 from f-droid.org .

screenshot_2017-04-21-06-41-36

Feature request: PWM

Hi Bill

Been using your app for a while. Thanks for the dial knob interface.

Do you think you can implement pulse width modulation with adjustable duty cycle.

Typical use case to test an electric motor with a headphone jack plugging into the motor driver.

Pwm duty cycle from as close to 1% to 100% with a slider of dial, if doable.

Will keep tracking your app.

Frequency bookmarks

I've been asked by trumpet teacher to buzz a target note, tuning to something.
Signal generator would be great for this, but I don't know note frequencies by heart so I thought it would be great to have "bookmarks" for easily jump to preferred frequencies.

Bookmarks would probably be the most flexible way to deal with it, so there's no enforcement of any scale of tuning..

Interference Of the Signal Generator App

Expected Behavior

The app should stop it's noise when making or receiving a Call. It should also stop making its noise when opening a media file.

Actual Behavior

It keeps making its noise irrespective of incoming or outgoing calls. It also interferes on audio and music

*Test Tools

  • Operating system : Android 6.0
  • Phone : Infinix hot s
  • Signal Generator App version 1.15

How to produce the bug

Open the app, Select any audible frequency, minimise the app and place a call. It would stop its noise for few seconds and start again to interfere with the call

Recording of the bug is shown below......

https://youtu.be/ZaIL2WbldQM



Posted on Utopian.io - Rewarding Open Source Contributors

Awesome frequency range feature lost after upgrade

Hi Bill,

Congratulations for this excellent app! It's the only one I could find that changes pitch in real time; also logarithmically, and without artifacts.

One awesome accidental feature that worked up til version 1.06 was the possibility to extend the frequency range beyond the limits of the rotary knob by using the left and right arrow buttons above it.

This was very useful for temporal and rhythmic applications by using the squ and saw tones which click like a metronome at very low frequencies. Also excellent for hearing the transition between the temporal and spectral characteristics of sound. Unfortunately, this feature was lost (or fixed) after version 1.06.

How about extending the frequency range down to around 1 BPM = 0,01667 Hz, the slowest tempo which, according to some, can hold human attention? Maybe make this into an option in the Settings menu which will activate both the frequency knob and arrow buttons?

Thank you in advance!
Bo C-sen

Hi! 🤝 Bill ~~Gates~~(Farmer) ;) Russian translation src/main/res/raw-ru/help.html

<h2>Генератор сигнала</h2>
<p>
  Генератор сигнала для Android. Скачать приложение можно
  из <a href="https://f-droid.org/packages/org.billthefarmer.siggen">F-Droid</a>
  или <a href="https://github.com/billthefarmer/sig-gen/releases">отсюда</a>.
</p>
&nbsp; &bullet;&nbsp; Диапазон частот: 0,1 Гц &ndash; 25 КГц<br>
&nbsp; &bullet;&nbsp; Диапазон уровней: 0 дБ &ndash; -80 дБ<br>
&nbsp; &bullet;&nbsp; Указать точную частоту<br>
&nbsp; &bullet;&nbsp; Закладки частоты<br>
&nbsp; &bullet;&nbsp; Рабочий цикл квадратной волны<br>
&nbsp; &bullet;&nbsp; Быстрый доступ<br>
&nbsp; &bullet;&nbsp; Управление извне<br>
<h3>Руководство</h3>
<p>
  Шайба частоты реагирует на вращение пальца. Ползунки рабочего цикла, точной частоты и уровня позволяют регулировать рабочий цикл квадратной волны, точную частоту и уровень выходного сигнала. Шайба частоты также регулируется с помощью кнопок со стрелками влево и вправо выше. Две кнопки закладок под шайбой частоты покажут, есть ли закладки, и перейдут к другой, более низкой или более высокой закладке, если она есть..
</p>
<p>
  Панель с кнопками слева направо:
</p>
&nbsp; &bullet;&nbsp; <strong>Указать точнее</strong> - запрос на точную частоту<br>
&nbsp; &bullet;&nbsp; <strong>В закладку</strong> - сохранить текущую частоту в закладку<br>
&nbsp; &bullet;&nbsp; <strong>Без сна</strong> - запретить устройству спать<br>
<p>
  Для удаления закладки коснитесь той же кнопки (В закладку).
</p>
<h3>Быстрый доступ</h3>
<p>
  Можно создать быстрый доступ для установки указанных параметров ниже. Пустые значения частоты, рабочего цикла и уровня, а также не отмеченные значения формы волны не будут включены. Значение тишина всегда будет включено. Имя быстрого доступа будет составлено из заданных значений, если поле с именем пустое.
</p>
<h3>Управление извне</h3>
<p>
  Возможно запустить приложение, задать частоту, уровень, рабочий цикл, форму волны и тишину извне, подав
  <a href="https://developer.android.com/reference/android/content/Intent">запрос</a>
  из приложения автоматизации. Пакет приложения/activity в
  org.billthefarmer.siggen/org.billthefarmer.siggen.Main. Параметры можно увидеть в таблице в файле <a href="https://github.com/billthefarmer/sig-gen#external-control">README</a>.
</p>
<p>
  Любая комбинация дополнений или их отсутствие может быть отправлена. Последующие запросы, отправленные, обновят значения для включённых дополнений.
</p>
<p>
  Возможно проверить этим <a href="https://developer.android.com/studio/command-line/adb#am">Android
  Debug Bridge</a>.
</p>

Blank

The app doesn't show any controls. It's blank.

img_14.jpg

Fix frequency aliasing

Attempting to play waveforms containing harmonics with frequencies above the Nyquist rate results in aliasing. The output will lose it's intended form.

To reproduce, choose a waveform other than sine, set the frequency to around 10Khz, and slowly increase it via the knob. You will will hear weird sounds being produced due to this phenomenon.

One possible solution would be to band-limit the generated waveform before handing the signal to the system, using a low pass filter.

tapping on frequency should ask for frequency

I've gotten used to the idiosyncratic interface of sig-gen, but after trying to show it to another person, I think it could use some improvement.

Currently tapping on the displayed frequency does nothing. It should pop up the dialog asking to enter the frequency directly.

Also, there is a hollow rectangle icon which confuses people. They think it is a glyph representing a phone screen. I suggest removing the rectangle icon once tapping on the frequency works.

Power usage

siggen-power-usage

Using Signal Generator 1.30 (via FDroid) I noticed quite severe power usage -- see the attached screenshot.

Watching videos for 10 hours takes ~5% of the battery, but 2 mins of sig-gen 23%? I guess there's something amiss.
Do you re-calculate the waveform a million times a second or so?

Presets do not work 10Hz or less apart

I created bookmarks for 30 and 40 Hz. I expected that I could use the left and right arrows to move between them, the same as with any other bookmark. Left arrow works. However, when I am at 30, the right arrow does nothing and the frequency stays at 30.

Likewise, with a bookmark at 25 Hz, I cannot use the right arrow to go from 25 to 30 Hz.

The problem does not occur for bookmarks over 10 Hz apart. (For example, 29.99 to 40 Hz).


Thank you for this extremely handy tool! Just the other day I found a new use for it: teaching a young nephling the difference between audio waveforms.

phase

hi bill,
thanks for your signal generator. i am sorry this is more a feature request, since i din't kjnow how to contact you. i would like to play around with it a bit to try reduce my tinnitus with it. as i understand it therefore it would be necessary to change/revert the phase of the sinus signal. maybe you are interested in that. regards!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.