Examples of low level control (synthesis) of audio ? - speakers, HDMI audio

Dukc ajieskola at gmail.com
Sat Aug 24 07:03:01 UTC 2024


Stephen Tashiro kirjoitti 22.8.2024 klo 19.56:
> I visualize the final output as data that stores a waveform as a sequence of values that represent amplitudes.  Is that low level of representation necessary?

I have dabbled a bit with this idea with SDL. You can write 16-bit 
integers generated with a sine function to a raw SDL_mixer audio chunk 
and your speaker will really output exactly that waveform as a sound, at 
least on Linux. This program will loop a sound resembling throttling and 
de-throttling combustion engine:

```D
import bindbc.sdl;

int main()
{ import std;
   auto err = initialize;
   if(err.length)
   { writeln(err);
     return 1;
   }

   auto chunk = makeCombustionEngine();
   writeln("press enter to continue");
   Mix_PlayChannel(0, &chunk, -1);
   readln; // waits for keypress

   return 0;
}

auto makeCombustionEngine()
{ import std;

   auto chunk = Mix_Chunk(0, new ubyte[0x20000].ptr, 0x20000, 255);
   // 32 Ki samples
   iota(0u, 0x8000u)
   .map!(to!double)
   .cumulativeFold!((prev, b) => (prev + (2.0 + sin(b * PI * 2 / 
0x8000)) / 0x800 * PI) % (PI*2))(0.0)
   // In the map predicate argument, we
   // convert the sound samples to uints, multiplexed into
   // two 16-bit channels that both have the original sample.
   // One for the left stereo, one for the right one.
   .map!(x => (y => (y << 16) + y)(cast(ushort)(sin(x)*0xFFFF)))
   .copy(cast(uint[])chunk.abuf[0 .. 0x20000]);

   return chunk;
}

string initialize()
{ import std;
   static import bindbc.loader.sharedlib;

   switch(loadSDL)
   { case sdlSupport: break;

     case SDLSupport.badLibrary:
     return "SDL2 library (.so or .dll) only partially loaded. Most 
probably too old version of it.";

     default:
     return "Could not find SDL2 library! (.so or .dll)";

   }

   switch(loadSDLMixer)
   { case SDLMixerSupport.noLibrary:
     return "Could not find SDL2 library! (.so or .dll)";

     case SDLMixerSupport.badLibrary:
     return "SDL2 library (.so or .dll) only partially loaded. Most 
probably too old version of it.";

     default: break;

   }

   if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)
   { return text("Error: failed to init SDL: ", SDL_GetError().fromStringz);
   }

   if( Mix_OpenAudio( 11025, MIX_DEFAULT_FORMAT, 2, 2048 ) < 0 )
   { return text( "SDL_mixer could not initialize! SDL_mixer Error: ", 
Mix_GetError() );
   }

   return "";
}
```



More information about the Digitalmars-d mailing list