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