www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems using rawWrite in an experiment with WAVs in D

reply tososdk <elcahivo gmail.com> writes:
I was recreating some code from C++ to D:
```
import std.stdio;
import std.file;
import std.string;
import std.math;

struct WavHeader {
     char[4] riff;
     int flength;
     char[4] wave;
     char[4] fmt;
     int chunk_size;
     short format_tag;
     short num_chans;
     int sample_rate;
     int bytes_per_second;
     short bytes_per_sample;
     short bits_per_sample;
     char[4] data;
     int dlength;
}

void main() {
     WavHeader wahv;

     wahv.riff[] = "RIFF".dup;
     wahv.wave[] = "WAVE".dup;
     wahv.fmt[] = "fmt ".dup;
     wahv.data[] = "data".dup;

     wahv.chunk_size = 16;
     wahv.format_tag = 1;
     wahv.num_chans = 1;
     wahv.sample_rate = 8000;
     wahv.bits_per_sample = 16;
     wahv.bytes_per_sample = cast(short)((wahv.bits_per_sample / 
8) * wahv.num_chans);
     wahv.bytes_per_second = wahv.sample_rate * 
wahv.bytes_per_sample;

     const int duration_seconds = 10;
     const int buffer_size = wahv.sample_rate * duration_seconds;
     wahv.dlength = buffer_size * wahv.bytes_per_sample;
     wahv.flength = wahv.dlength + 44;

     short[] buffer = new short[buffer_size];

     foreach (i; 0 .. buffer_size) {
         buffer[i] = cast(short)(cos((2.0 * PI * 256.0 * i) / 
wahv.sample_rate) * 1000);
     }

   // Corrected file handling
   auto file = File("test.wav", "r");
   file.rawWrite(wahv);

   // Writing the audio data as raw bytes
   file.rawWrite(cast(ubyte[])buffer);

   file.close();
}

```
But since I am somewhat new to these topics and even more so to 
Dlang, I don't understand very well. The problem occurs in the 
creation of the .wav, regarding rawWrite, I'm not really sure 
what to do in that specific part. Maybe I'm ignorant, but I'm not 
very good at these topics, plus it's for experimentation.
Dec 27 2023
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Because WaveHeader has no pointers in it, only raw memory, assuming it 
is all in the cpu endianesss and with ``align(1)`` you can slice that 
block of stack memory and write from that.

```d
file.rawWrite((cast(ubyte*)&wahv)[0 .. WaveHeader.sizeof]);
```

However I would recommend doing it field by field.

A lot more work, but allows you to handle endianness issues and remove 
alignment concerns. Also changing of field sizes if required.

Same principles as the code above.
Dec 27 2023
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 27 December 2023 at 20:20:23 UTC, tososdk wrote:
 I was recreating some code from C++ to D:
[...]
 But since I am somewhat new to these topics and even more so to 
 Dlang, I don't understand very well. The problem occurs in the 
 creation of the .wav, regarding rawWrite, I'm not really sure 
 what to do in that specific part. Maybe I'm ignorant, but I'm 
 not very good at these topics, plus it's for experimentation.
Here's the error message I got when I tried to compile your code: ``` Error: template `std.stdio.File.rawWrite` is not callable using argument types `!()(WavHeader)` /dlang/dmd/linux/bin64/../../src/phobos/std/stdio.d(1273): Candidate is: `rawWrite(T)(in T[] buffer)` ``` What this message is saying is that you tried to pass a `WavHeader` to `rawWrite`, but `rawWrite` expects a slice (`T[]`, where `T` can be any type) as an argument. The easiest way to fix this is to use [pointer slicing][1] to create a temporary slice that points to `wavh`: ```d file.rawWrite((&wahv)[0 .. 1]); ``` [1]: https://dlang.org/spec/expression.html#slice_expressions
Dec 27 2023