Puppy In-House Development

Under development: PCMCIA, wireless, etc.
Message
Author
amigo
Posts: 2629
Joined: Mon 02 Apr 2007, 06:52

#241 Post by amigo »

I wound up cloning the whole repo -about 590MB, but following on technosaurus about wget recursive, I was able to get just the patches with:

Code: Select all

 wget -r -l1 --no-parent http://cgit.openembedded.org/openembedded/plain/recipes/xorg-xserver

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#242 Post by technosaurus »

@amigo thanks for the wget command. I'm in the process of moving so doing everything from my droid. I wouldn't be too concerned with the 560mbs though, you may discover some other interesting finds. I noted some interesting projects that I'd never heard of before.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#243 Post by technosaurus »

I posted a public domain MP3 and MP2 decoder here:
https://github.com/technosaurus/PDMP3
https://github.com/technosaurus/PDMP2
I'm still looking through them to see if it would be hard to merge them.
<edit>
I wrote a little (public domain) ogg player too using stb_vorbis ... compiles to 44kb with dietlibc, but I'll post just the source till I get a musl toolchain up.

Code: Select all

//diet gcc -Os -finline-small-functions oggplay.c -ffunction-sections -fdata-sections -fmerge-all-constants -Wl,--gc-sections,-s -o oggplay -lm
#define STB_ONLY
#include "stb.h"           /*  http://nothings.org/stb.h  */
#include "stb_vorbis.c"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <errno.h>

static inline void write2(char *msg){
	fputs(msg,stderr);
}

int main(int argc, char **argv){
	int error,
	value = AFMT_S16_LE ,
	pcm = open("/dev/dsp", O_WRONLY);
	if (pcm < 0)
		write2("cannot get fd\n");
	if (ioctl(pcm, SNDCTL_DSP_SETFMT, &value) < 0)
		write2("cannot set audio format: %s\n");

while (--argc) {
    short *decoded;
    int channels, len, sample_rate;
    len = stb_vorbis_decode_filename(argv[argc], &channels, &sample_rate, &decoded);
    if (ioctl(pcm, SNDCTL_DSP_CHANNELS, &channels) < 0)
		write2("cannot set channels");
    if (ioctl(pcm, SNDCTL_DSP_SPEED, &sample_rate) < 0)
		write2("cannot set sample rate");
	write(pcm,decoded,len*channels);
}
close(pcm);
return 0;
}
</edit>
So, I've been writing my own libc that is specifically designed for small static builds and as part of that I have been splitting each function into its own file with its own header so that instead of #include <string.h> and possibly getting unwanted garbage you can just #include "strlen.h", which is good in that you don't have to remember what functions go with what headers but can become rather tedious so I wrote this awk script that will find any occurrence of supported functions and generate an include file.

Code: Select all

#!/bin/awk -f
BEGIN{
	FS="[^a-zA-Z_]"

#supported functions are comma-separate in "allfuncs" file
	while ((getline line < "allfuncs") > 0)
		allfuncs=allfuncs line
	close("allfuncs")
}
{
	for(i=1;i<NF;i++)
		if (index(allfuncs,","$i","))
			if (needed[$i])	needed[$i]++;
			else needed[$i]=1
}
END{
	printf "#ifndef BQC_CONFIG_H\n#define BQC_CONFIG_H\n"
	for (i in needed) print "#include <" i ".h> //uses = " needed[i] 
	print "#endif"
}
This is just the start, I am also working on a script to detect which %* parameters are used in *printf functions so that unneeded conversion functions can be omitted and unused case labels removed. This can save a few kb.

I've also been messing around with building a shared c library where all of the functions are hidden and accessed through a few arrays of function pointers ... similar to how Linux syscalls work

Code: Select all

int f0(int a, int b){return a+b;} //ADD
int f1(int a, int b){return a-b;} //SUBTRACT
int f2(int a, int b){return a*b;} //MULTIPLY
int f3(int a, int b){return a/b;} //DIVIDE

//use these to access the function in the array
enum{ ADD, SUBTRACT, MULTIPLY, DIVIDE, NUM_FUNCS};

//assign the corresponding functions in same order as enum above
//type checking and number of parameters are for wusses
int (*f[NUM_FUNCS]) () = {f0,f1,f2,f3};

#define F(x,...) (*f[x]) (__VA_ARGS__)
 
#define add(...) F(ADD,__VA_ARGS__)
//note, the compiler probably won't complain if you add("hello","world")
//....
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#244 Post by technosaurus »

I could have just edited my last post, but in case anyone is following the thread, I wanted to get input on setting up a github team. As it goes most listings of the most difficult things in programming include "naming stuff". After considering PNG (short for puppy next generation after DSLR tradition of ungoogleable names) I thought Mite would be fitting for several reasons:
worlds fastest animal by size
some of the most powerful animals by size
their makeup defies traditional wisdom based on other species
they make use of stuff left behind by others
they occupy a wide range of niches
There are almost 50000 species to choose from for code-naming sub projects each with varying characteristics.

The os could be called Acari (the taxonomy subclass of all mites) or Acarina.

Any thoughts? I'm also amenable to a whole dinosaur based naming scheme.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
Karl Godt
Posts: 4199
Joined: Sun 20 Jun 2010, 13:52
Location: Kiel,Germany

#245 Post by Karl Godt »

MITE ??
I actually had to look up
http://en.wikipedia.org/wiki/Mite

MINOSUARUS ?

TIME ? Tiny Imbedded Modular Environment ?


But I have no stocks in C code though ..
«Give me GUI or Death» -- I give you [[Xx]term[inal]] [[Cc]on[s][ole]] .
Macpup user since 2010 on full installations.
People who want problems with Puppy boot frugal :P

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#246 Post by greengeek »

Yes, i think that "mite" be a very appropriate name.

Apparently puppies are an excellent host for mites...

http://puppies.about.com/od/OwnerPuppyC ... -Mites.htm

:-)
Attachments
puppy mite.JPG
(30.45 KiB) Downloaded 666 times

User avatar
mavrothal
Posts: 3096
Joined: Mon 24 Aug 2009, 18:23

#247 Post by mavrothal »

Mite also sounds like might (=strength),
but do you really want to name an OS after a whole bunch of ugly BUGs? :shock: :P

(yes, mites are not insects but they are "bugs" just the same)
== [url=http://www.catb.org/esr/faqs/smart-questions.html]Here is how to solve your[/url] [url=https://www.chiark.greenend.org.uk/~sgtatham/bugs.html]Linux problems fast[/url] ==

User avatar
Moat
Posts: 955
Joined: Tue 16 Jul 2013, 06:04
Location: Mid-mitten

#248 Post by Moat »

I think the Mite naming idea is great. Acari & Acarina = excellent. Mighty Mite!

User avatar
NeroVance
Posts: 201
Joined: Wed 10 Oct 2012, 23:00
Location: Halifax, Canada

#249 Post by NeroVance »

technosaurus wrote:I could have just edited my last post, but in case anyone is following the thread, I wanted to get input on setting up a github team. As it goes most listings of the most difficult things in programming include "naming stuff". After considering PNG (short for puppy next generation after DSLR tradition of ungoogleable names) I thought Mite would be fitting for several reasons:
worlds fastest animal by size
some of the most powerful animals by size
their makeup defies traditional wisdom based on other species
they make use of stuff left behind by others
they occupy a wide range of niches
There are almost 50000 species to choose from for code-naming sub projects each with varying characteristics.

The os could be called Acari (the taxonomy subclass of all mites) or Acarina.

Any thoughts? I'm also amenable to a whole dinosaur based naming scheme.
I do like the concept of something called Mite Linux or AcarinaPup(py) which would be quite nice.

I think I should look into developing using gtk1 somewhat as something I can do during my college break, but to also develop some tools for Mite. Anyone want to possibly build a Mite Forum and perhaps find a decent base to begin our work? Since while this is puppy derived, it does seem very different in it's scope and goal, and would benefit from being more of derivative in it's own right.

I'll try to design a logo for Mite, probably using public domain images to get a good visual for it.

Scooby
Posts: 599
Joined: Sat 03 Mar 2012, 09:04

#250 Post by Scooby »

Tried out luufs, but not much documentation?

not even "--help"

Is there a wiki or somthing somewhere?

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#251 Post by Iguleder »

There's a man page.
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

Scooby
Posts: 599
Joined: Sat 03 Mar 2012, 09:04

#252 Post by Scooby »

Thanks man, I didn't see it

*EDIT*
got it, use absolute path :D
keeping below for reference
----------------------------------------------------------------------------------------------------------------------
tried it though and got

Code: Select all

> ls -l
d????????? ? ?    ?       ?            ? target/

> ls target
ls: cannot access target: No such file or directory

> mount
...
luufs on /mnt/live/tmp/scratch/luufs/target type fuse.luufs (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
Does it have any dependencies?
Tried it in /tmp, /root (aufs writable branch) and HD

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#253 Post by Iguleder »

Just FUSE. It supports musl.
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#254 Post by technosaurus »

Here is a simple mixer for use in shell scripts:
usage:
mix /dev/mixer vol #prints current volume
mix /dev/mixer vol $((100*256+100)) #sets left & right volume to 100

you can also get/set bass, treble, synth, pcm, speaker, line, mic, cd, mix, pcm2, rec, igain, ogain, line1, line2, line3, dig1, dig2, dig3, phin, phout, video, radio, monitor

Code: Select all

/*This linux mixer dedicated to the Public Domain by Brad Conroy*/
#include <fcntl.h>
#include <linux/soundcard.h>

int get_dev(const char *name){
	int i;
	const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
	for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
		if (!strcmp(names[i], name)) return i;
	return -1;
}

#ifdef NOPRINTF
void putd(unsigned d){
	if (d==0){
		write(1,"0",1);
	}else{
		unsigned i=1000000000;
		char s[1];
		while (i > d) i/=10;
		while (0<i){
			*s='0'+(d/i);
			write(1,s,1);
			if (i<=d) d%=i;
			i/=10;
		}
	}
	write(1,"\n",1);
}
#else
#include <stdio.h>
#endif

int main(int argc, char **argv){ //mix /dev/mixer dev [value]
	int fd=open(argv[1], O_RDWR|O_NONBLOCK),
		dev=get_dev(argv[2]),
		buf;
	if (fd<0 || dev<0) return -1;
	if (argc>3){
		buf=atoi(argv[3]);
		if(ioctl(fd, MIXER_WRITE(dev),&buf)<0) return -1;
	}
	if(ioctl(fd, MIXER_READ(dev),&buf)<0) return -1;
#ifdef NOPRINTF
	putd(buf);
#else
	printf("%d\n",buf);
#endif
	close(fd);
	return 0;
}
Edit:

This (slightly larger) version accepts list or list: to output device names (and : current values)
  • >mix /dev/mixer list
    vol
    line
    mic
    pcm2
    igain
    dig1
    > ./mix /dev/mixer list:
    vol:25700
    line:25700
    mic:25700
    pcm2:25700
    igain:25700
    dig1:25700

Code: Select all

/*This linux mixer dedicated to the Public Domain by Brad Conroy*/
#include <fcntl.h>
#include <string.h>
#include <linux/soundcard.h>
#ifdef NOPRINTF
void putd(unsigned d){
	if (d==0){
		write(1,"0",1);
	}else{
		unsigned i=1000000000;
		char s[1];
		while (i > d) i/=10;
		while (0<i){
			*s='0'+(d/i);
			write(1,s,1);
			if (i<=d) d%=i;
			i/=10;
		}
	}
	write(1,"\n",1);
}
#else
#include <stdio.h>
#define putd(d) printf("%d\n",d)
#endif

int fd,dev,buf,i,mask; //global kludge

int get_dev(const char *name){
	const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
	if (!strncmp("list", name, 4)){
		ioctl(fd, SOUND_MIXER_READ_DEVMASK,&mask);
		for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
			if (1<<i & mask) {
				write(1,names[i],strlen(names[i]));
				if (name[4]==':'){
					write(1,":",1);
					if(ioctl(fd, MIXER_READ(i),&buf)<0) return -1;
					putd(buf);
				}else write(1,"\n",1);
			}
	}else for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
		if (!strcmp(names[i], name)) return i;
	return -1;
}


int main(int argc, char **argv){ //mix /dev/mixer dev [value]
	fd=open(argv[1], O_RDWR|O_NONBLOCK);
	dev=get_dev(argv[2]);
	if (fd<0 || dev<0) return -1;
	if (argc>3){
		buf=atoi(argv[3]);
		if(ioctl(fd, MIXER_WRITE(dev),&buf)<0) return -1;
	}
	if(ioctl(fd, MIXER_READ(dev),&buf)<0) return -1;
	putd(buf);
	close(fd);
	return 0;
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

wboz
Posts: 233
Joined: Wed 20 Nov 2013, 21:07

#255 Post by wboz »

I haven't reread this thread in its entirety but I am excited about this project. You definitely have my encouragement :)

I have tried Tiny Core in the past and several aspects put me off. I have strong feeling this group will make a great product.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#256 Post by technosaurus »

Are we planning to (eventually) implement kdbus functionality in future kernels for interprocess communication? rox, tinyx*,
... I ask because I was considering patching the xserver and tinyX to use kdbus vs unix domain (or even slower tcp) sockets to help make up for the speed difference of accelerated Xorg drivers.

Other TODOs :
Check Xservers for accelerated functions (pretty sure Xorg devs aren't watching this too closely, so here they are for reference):
  • /* fb ops */
    static struct fb_ops {
    .fb_open
    .fb_release
    .fb_check_var
    .fb_set_par
    .fb_setcolreg
    .fb_blank
    .fb_pan_display
    .fb_fillrect
    .fb_copyarea
    .fb_imageblit
    .fb_cursor
    .fb_sync
    .fb_ioctl
    .fb_mmap
    .fb_read
    .fb_write
    };
Refactor X11 - only 4 different basic types of messages are sent, with 3-4 different actions, so the shared lib can be as small as 20-30 functions with the rest in headers as static inlined functions (this will actually produce smaller executables due to the dumbass way X11 has 10s of parameters in functions instead of a struct pointer) The current method of including each function in the shared library has to push each parameter to the stack, set the stack pointer call another function which has to pop them to do stuff, return a value and then have the caller restore its stack.

fyi, the order you put parameters in makes a huge difference in how optimizable they are as exported functions, for instance:

Code: Select all

mega_func(a,b,c,d,e,f,g,h,i){
switch(a){
case 0 : return func0(b,c,d,e,f,g,h);
....
}
}
can be optimized to a single pop and a jump table
whereas the following has to pop all of the parameters first:

Code: Select all

mega_func(a,b,c,d,e,f,g,h,i){
switch(i){
case 0 : return func0(a,b,c,d,e,f,g,h);
....
}
}
The reason I bring this up is because X11 does this really poorly and code size could be reduce by having the standard function be a macro (or static inline helper function if we want C++ support) that swaps the parameters in the more efficient order ... this is why MS uses a different calling convention (pass by register vs stack) - it is faster and reduces code size
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#257 Post by Iguleder »

Trying to get the upstream LibreSSL to work with musl. At the moment, musl requires two sets of #ifdefs.

It's pretty much impossible to build a static OpenSSL without tons of hacks, but LibreSSL is an entirely different story - it uses autoconf. Very convenient! I got many applications to build statically against musl and LibreSSL (Dillo, Sylpheed, x11vnc, X-Chat, Lynx and more).
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#258 Post by technosaurus »

glibc has _versioning_ which is really annoying sometimes, but the very reason the runtime check is pointless... they should use a blacklist method and error on glibc<whatever.version, include their own version if it is missing or use the libc version ... not some random whitelist system that assumes that all other programmers are stupid... if they want to do that crap they should just have a #define PARANOID that only uses their versions of everything.

Edit: I've been putting together another audio app, but this time just a .wav player for toybox (on windows box without a compiler, so it is probably full of errors) -- in case anyone wants to see if it will build/play

Code: Select all

/* wav.c - Plays wav file(s).
 *
 * Copyright 2014 Brad Conroy <bconroy@uis.edu>
 *
 * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

USE_WAV(NEWTOY(wav, "<1", TOYFLAG_BIN))

config WAV
  bool "wav"
  default n
  help
    usage: wav [wav file...]

    Plays wav files.
*/

#define FOR_wav
#include "toys.h"

void do_wav(int wav, char **argv){

	struct {
		long	ChunkID; //0x52494646 "RIFF"
		long	ChunkSize;
		long	Format; //0x57415645 "WAVE"
		long	Subchunk1ID; //0x666d7420 "fmt "
		long	Subchunk1Size;
		short	AudioFormat; //1
		short	NumChannels; //1==mono, 2==stereo
		long	SampleRate; //8000, 44100,...
		long	ByteRate;
		short	BlockAlign;
		short	BitsPerSample;
		long	Subchunk2ID; //0x64617461 "data"
		long	Subchunk2Size;
	} *wav_hdr=&toybuf;

	int error,dsp;
	read(wav,wav_hdr,44);
	if (wav_hdr->Format==0x57415645 && 
		wav_hdr->Subchunk1ID==0x666d7420 &&
		wav_hdr->Subchunk2ID==0x64617461){
		if (dsp=open("/dev/dsp",O_WRONLY) >= 0 &&
			ioctl(dsp, SNDCTL_DSP_SPEED, &wav_hdr->SampleRate) >= 0 &&
			ioctl(dsp, SNDCTL_DSP_CHANNELS, &wav_hdr->NumChannels) >= 0
			&& ioctl(dsp, SNDCTL_DSP_SETFMT, &wav_hdr->BitsPerSample) >= 0){
			while (readall(wav,toybuf,sizeof(toybuf))
				writeall(dsp,toybuf,sizeof(toybuf));
			close(dsp);
		}else perror("dsp");
	}
}

void wav_main(void){
  loopfiles(toys.optargs, do_wav);
}
Edit2: @Iguleder, I noticed you also made an ogg player with stb_vorbis ... is there an advantage to using tinyalsa over /dev/dsp directly? ... aside from possibly missing a symlink from /dev/dspX like mixing multiple sources or support for platforms without OSS
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#259 Post by Ibidem »

technosaurus wrote:Edit: I've been putting together another audio app, but this time just a .wav player for toybox (on windows box without a compiler, so it is probably full of errors) -- in case anyone wants to see if it will build/play

Code: Select all

/* wav.c - Plays wav file(s).
 *
 * Copyright 2014 Brad Conroy <bconroy@uis.edu>
 *
 * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

USE_WAV(NEWTOY(wav, "<1", TOYFLAG_BIN))

config WAV
  bool "wav"
  default n
  help
    usage: wav [wav file...]

    Plays wav files.
*/

#define FOR_wav
#include "toys.h"

void do_wav(int wav, char **argv){

	struct {
		long	ChunkID; //0x52494646 "RIFF"
		long	ChunkSize;
		long	Format; //0x57415645 "WAVE"
		long	Subchunk1ID; //0x666d7420 "fmt "
		long	Subchunk1Size;
		short	AudioFormat; //1
		short	NumChannels; //1==mono, 2==stereo
		long	SampleRate; //8000, 44100,...
		long	ByteRate;
		short	BlockAlign;
		short	BitsPerSample;
		long	Subchunk2ID; //0x64617461 "data"
		long	Subchunk2Size;
	} *wav_hdr=&toybuf;

	int error,dsp;
	read(wav,wav_hdr,44);
	if (wav_hdr->Format==0x57415645 && 
		wav_hdr->Subchunk1ID==0x666d7420 &&
		wav_hdr->Subchunk2ID==0x64617461){
		if (dsp=open("/dev/dsp",O_WRONLY) >= 0 &&
			ioctl(dsp, SNDCTL_DSP_SPEED, &wav_hdr->SampleRate) >= 0 &&
			ioctl(dsp, SNDCTL_DSP_CHANNELS, &wav_hdr->NumChannels) >= 0
			&& ioctl(dsp, SNDCTL_DSP_SETFMT, &wav_hdr->BitsPerSample) >= 0){
			while (readall(wav,toybuf,sizeof(toybuf))
				writeall(dsp,toybuf,sizeof(toybuf));
			close(dsp);
		}else perror("dsp");
	}
}

void wav_main(void){
  loopfiles(toys.optargs, do_wav);
}
char *file, not char **argv.
Also, xopen() and xioctl(), unless you're expecting someone to create /dev/dsp while the player is running.
s/long/int/g
#include <linux/soundcard.h>

And endianness, what fun!
(It doesn't work on x86, since the bytes are the other way round. I tried to fix with strncmp.)
OK, I have a version that gets to the second ioctl().

And this works:

Code: Select all

/* wav.c - Plays wav file(s).
 *
 * Copyright 2014 Brad Conroy <bconroy@uis.edu>
 *
 * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

USE_WAV(NEWTOY(wav, "<1", TOYFLAG_BIN))

config WAV
  bool "wav"
  default n
  help
    usage: wav [wav file...]

    Plays wav files.
*/

#define FOR_wav
#include "toys.h"
#include <linux/soundcard.h>

void do_wav(int wav, char *wavfile){

  struct {
    char  ChunkID[4]; //0x52494646 "RIFF"
    int   ChunkSize;
    char  Format[4]; //0x57415645 "WAVE"
    char  Subchunk1ID[4]; //0x666d7420 "fmt "
    int   Subchunk1Size;
    short AudioFormat; //1
    short NumChannels; //1==mono, 2==stereo
    int   SampleRate; //8000, 44100,...
    int   ByteRate;
    short BlockAlign;
    short BitsPerSample;
    char  Subchunk2ID[4]; //0x64617461 "data"
    int   Subchunk2Size;
  } *wav_hdr = (void*)toybuf;

  int dsp, tmp;
  readall(wav,wav_hdr, 44);
  if (strncmp(wav_hdr->Format, "WAVE", 4)) {
    printf("format: %.4s", wav_hdr->Format); 
    return;
  }
  if (strncmp(wav_hdr->Subchunk1ID,"fmt ", 4)) {
    printf("ID1: %.4s", wav_hdr->Subchunk1ID); 
    return;
  }
  if (strncmp(wav_hdr->Subchunk2ID, "data", 4)) {
    printf("ID2: %.4s", wav_hdr->Subchunk2ID); 
    return;
  }
  dsp = xopen("/dev/dsp",O_WRONLY);
#if IS_LITTLE_ENDIAN
  bswap_32(wav_hdr->SampleRate);
  bswap_16(wav_hdr->NumChannels);
  bswap_16(wav_hdr->BitsPerSample);
#endif
  xioctl(dsp, SNDCTL_DSP_SPEED, &wav_hdr->SampleRate);
  tmp = wav_hdr->NumChannels;
  xioctl(dsp, SNDCTL_DSP_CHANNELS, &tmp);
  xioctl(dsp, SNDCTL_DSP_SETFMT, &wav_hdr->BitsPerSample);
  while (readall(wav,toybuf,sizeof(toybuf)))
    writeall(dsp,toybuf,sizeof(toybuf));
  close(dsp);
}

void wav_main(void){
  loopfiles(toys.optargs, do_wav);
}

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#260 Post by technosaurus »

Ibidem wrote: And this works:
Thanks, I was planning on #ifdeffing the endian stuff instead of strcmp
After reviewing the spec it looks like

Code: Select all

#if IS_LITTLE_ENDIAN
  if (wav_hdr->Format==0x45564157 && wav_hdr->Subchunk1ID==0x20746d66 && wav_hdr->Subchunk2ID==0x61746164){
#else
  bswap_32(wav_hdr->SampleRate);
  bswap_16(wav_hdr->NumChannels);
  bswap_16(wav_hdr->BitsPerSample);
  if (wav_hdr->Format==0x57415645 && wav_hdr->Subchunk1ID==0x666d7420 && wav_hdr->Subchunk2ID==0x64617461){
#endif
//note need to add Subchunk1Size==16 && AudioFormat==??

1 (0x0001) PCM/uncompressed
2 (0x0002) Microsoft ADPCM
6 (0x0006) ITU G.711 a-law
7 (0x0007) ITU G.711 µ-law
17 (0x0011) IMA ADPCM
20 (0x0016) ITU G.723 ADPCM (Yamaha)
49 (0x0031) GSM 6.10
64 (0x0040) ITU G.721 ADPCM
80 (0x0050) MPEG

for PCM the format is little endian based on bits per sample
AFMT_U16_LE, AFMT_U24_LE and AFMT_U32_LE
TODO check AFMT_IMA_ADPCM, AFMT_MU_LAW, AFMT_A_LAW and wait, wtf MPEG == AFMT_MPEG ?can we play mp2 audio?

Re: s/long/int/
actually it seems neither is _always_ correct - int32_t? (the kernel uses be32 and le32 types )
to avoid the ifdefs we could use these or these

Now I need to be able to set the volume on it, so need to toybox my previous mixer (probably split the list part into a separate command)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Post Reply