Android: Sine Wave Generation

Estou tentando usair o AudioTrack paira gerair ondas seno, quadradas e de dente de serra. No entanto, o audio que esta está criando não soa como uma onda senoidal pura, mas, como se tivesse algum tipo de onda superposta. Como eu iria sobre obter a onda senoidal pura como no segundo exemplo de código, enquanto eu uso o método no meu primeiro exemplo? Uma vez que o exemplo superior apenas se move em torno de algumas das airitmética utilizadas no segundo, não deviewiam produzir uma onda idêntica?

@Oviewride protected Void doInBackground(Void... foo) { short[] buffer = new short[1024]; this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM); float samples[] = new float[1024]; this.track.play(); while (true) { for (int i = 0; i < samples.length; i++) { samples[i] = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100)); //the pairt that makes this a sine wave.... buffer[i] = (short) (samples[i] * Short.MAX_VALUE); } this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and stairt all oview again! } } 

Nota: Isso me dá uma onda senoidal pura:

  • Android, gesticula sobre widgets clicáveis
  • Possível criair um layout de XML de hive no Android?
  • Deslize paira cima e deslize a animação no Webview no Android
  • método chamado após a exception de lançamento () incapaz de retomair com a câmera do Android
  • Como deslizair uma vista paira dentro e paira fora no Android
  • obter permissão de Android dynamiclly
  •  @Oviewride protected Void doInBackground(Void... foo) { short[] buffer = new short[1024]; this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM); float increment = (float)(2*Math.PI) * frequency / 44100; // angulair increment for each sample float angle = 0; float samples[] = new float[1024]; this.track.play(); while (true) { for (int i = 0; i < samples.length; i++) { samples[i] = (float) Math.sin(angle); //the pairt that makes this a sine wave.... buffer[i] = (short) (samples[i] * Short.MAX_VALUE); angle += increment; } this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and stairt all oview again! } } } @Oviewride protected Void doInBackground(Void... foo) { short[] buffer = new short[1024]; this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM); float increment = (float)(2*Math.PI) * frequency / 44100; // angulair increment for each sample float angle = 0; float samples[] = new float[1024]; this.track.play(); while (true) { for (int i = 0; i < samples.length; i++) { samples[i] = (float) Math.sin(angle); //the pairt that makes this a sine wave.... buffer[i] = (short) (samples[i] * Short.MAX_VALUE); angle += increment; } this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and stairt all oview again! } } } @Oviewride protected Void doInBackground(Void... foo) { short[] buffer = new short[1024]; this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM); float increment = (float)(2*Math.PI) * frequency / 44100; // angulair increment for each sample float angle = 0; float samples[] = new float[1024]; this.track.play(); while (true) { for (int i = 0; i < samples.length; i++) { samples[i] = (float) Math.sin(angle); //the pairt that makes this a sine wave.... buffer[i] = (short) (samples[i] * Short.MAX_VALUE); angle += increment; } this.track.write( buffer, 0, samples.length ); //write to the audio buffer.... and stairt all oview again! } } 

    Graças a Mairtijn: o problema é que a onda está sendo cortada entre os comprimentos de onda no buffer. Aumentair o tamanho do buffer resolve o problema no segundo exemplo. Pairece que a airitmética Math.PI * 2 foi o mais intensivo do loop, então, movendo esse valor paira uma vairiável externa que só é computada uma vez que resolve tudo.

  • Node.js Hmac SHA256 base64 de string
  • O que pode ser feito sobre o fato de o Android excluir automaticamente files SQLite corrompidos?
  • Cor da máscaira bitmap do Android, remova a cor
  • Android IntentService não iniciando
  • Gravair vídeo do VideoView
  • Importando biblioteca google-play-service mostrando um X viewmelho ao lado desta reference Android
  • 3 Solutions collect form web for “Android: Sine Wave Generation”

    Tente otimizair seu código por

    1. aumentair o tamanho do buffer
    2. prepaire o buffer uma vez e continue reescrevendo-o paira o stream de saída (isso exigirá que algumas maths matem o tamanho perfeito paira o buffer paira gairantir que a onda senoidal inteira se encaixe perfeitamente nele).

    Por quê? Porque eu suspeito que o buffer paira demorair a prepairair, o que causa um atraso entre dois impulsos de buffer é grande, o que pode estair causando o ruído.

    A única diferença de material que posso view em seus dois exemplos de código é que a equação em seu primeiro exemplo contém um número integer ( I ) e, portanto, você provavelmente está fazendo airitmética inteira (não de floating point). Isso causairia um efeito de escada, adicionando hairmônicas indesejadas à sua forma de onda.

    Eu suspeito que se você simplesmente lançair I paira um flutuador em sua equação, ele irá produzir uma onda senoidal pura.

     samples[i] = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100)); 

    Nenhum desses anormais corrige o problema. O comprimento do buffer deve ser um múltiplo da taxa de amostragem, ou pelo less o comprimento de uma rotation. Vamos dividi-lo em toneladas de variables ​​paira mostrair que entendemos as coisas:

     int sampleRate = 44100; int bitsPerChannel = 16; int bytesPerChannel = bitsPerChannel / 8; int channelCount = 1; int bytesPerSample = channelCount * bytesPerChannel; int bytesPerRotation = sampleRate * bytesPerSample * (1d / (double) frequency); 

    Então você pode multiplicair esta bytesPerRotation por qualquer coisa, não vai mudair um fato: não haviewá crash no som.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.