Hi all,
I'm a newbie with C or C++. I have a raw PCM file 16-bit (like a wav file but no header). I need to build a console application that can read the file, store data in an array, modify it (ex: add 100 to each value of the data array), then play it in sound (with a known frequency sampling, ex Fs = 16000 Hz).
It would be very nice if someone can explain to me how to do that.
Thank you very much.

Dani AI

Generated

Salem is right that this breaks into three parts: load, process, play. And Ancient Dragon’s portability note is spot on: do not assume sizeof(short)==2. Treat the raw file as 16-bit signed little-endian and use int16_t. A simple, robust approach is to wrap your raw samples in a minimal WAV header, write a temp .wav, then play it with the OS.

#include <cstdint>
#include <vector>
#include <fstream>

// Write little-endian helpers
static void u32le(std::ofstream& o, uint32_t v){ unsigned char b[4]={ (unsigned)v, (unsigned)(v>>8), (unsigned)(v>>16), (unsigned)(v>>24) }; o.write((char*)b,4); }
static void u16le(std::ofstream& o, uint16_t v){ unsigned char b[2]={ (unsigned)v, (unsigned)(v>>8) }; o.write((char*)b,2); }

// Write a 16-bit PCM WAV file from raw samples
static void write_wav16(const char* path, const std::vector<int16_t>& pcm, int sampleRate, int channels){
    uint32_t dataBytes = (uint32_t)(pcm.size() * sizeof(int16_t));
    uint16_t blockAlign = (uint16_t)(channels * 2);
    uint32_t byteRate   = (uint32_t)(sampleRate * blockAlign);
    std::ofstream out(path, std::ios::binary);
    out.write("RIFF",4); u32le(out, 36 + dataBytes); out.write("WAVEfmt ",8);
    u32le(out,16); u16le(out,1); u16le(out,(uint16_t)channels);
    u32le(out,(uint32_t)sampleRate); u32le(out,byteRate);
    u16le(out,blockAlign); u16le(out,16);
    out.write("data",4); u32le(out,dataBytes);
    out.write((const char*)pcm.data(), dataBytes);
}

// Load raw 16-bit PCM, add 100 with saturation, save and play
int main(){
    std::ifstream in("myfile.pcm", std::ios::binary);
    in.seekg(0,std::ios::end); std::streamsize bytes=in.tellg(); in.seekg(0,std::ios::beg);
    if(bytes < 0) return 1; if(bytes % 2) --bytes; // drop odd tail if any
    std::vector<int16_t> pcm((size_t)bytes/2);
    in.read((char*)pcm.data(), pcm.size()*sizeof(int16_t));

    for(auto& s: pcm){ int v = (int)s + 100; if(v>32767) v=32767; if(v<-32768) v=-32768; s=(int16_t)v; }

    write_wav16("out.wav", pcm, 16000, 1); // use channels=2 if stereo
    return 0;
}

On Windows, you can play the result directly from your console program with PlaySound. Include Windows.h and mmsystem.h, link winmm.lib, and call: PlaySoundA("out.wav", NULL, SND_FILENAME | SND_SYNC); This uses the standard WAVE path; see Microsoft’s RIFF/WAV layout and PlaySound docs for field meanings and flags. RIFF overview. Using PlaySound.

Recommended Answers

All 6 Replies

Sure, which bit exactly are you having problems with?

- reading into an array
- adding values
- playing it

Sure, which bit exactly are you having problems with?

- reading into an array
- adding values
- playing it

Thks for your answer
Here is my code of reading values into an array

#include <iostream>
#include <fstream>
using namespace std;

void main()
{
	std::fstream f_in;
	short speech, value[10000];
	

	f_in.open ("myfile.pcm", std::ios::in | std::ios::binary);
	

	int i = 0;
	while (i < 10000) {
		f_in.read((char *)&speech, 2);
               value[i] = speech;
		cout << speech << std::endl;
		i++;
	}
}

I think it works well.
The problem is how to play sound from value array, with frequency sampling Fs = 16000hz.
Thks for any advice

I can't help you with your problem, but you don't need that while loop f_in.read(speech, 10000 * sizeof(short)); But of course there is no guarentee that sizeof(short) will be 2. It might be on your system but if you intend to port that porgram to another os then the size may be something else.

Thks for all of you.
I found my answer here:

Thks

Sir can u tell me the answer

Thks for all of you.
I found my answer here:

Thks

Hello there, the link you have given is not working. I am in the same problem as you are. Can you give me some code or the solution? Will be very helpful.

Thanks in advance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.