Opened 9 years ago

Closed 9 years ago

#4920 closed bug (fixed)

gcc4 BSoundPlayer broken on Alpha

Reported by: Adek336 Owned by: marcusoverhagen
Priority: normal Milestone: R1
Component: Kits/Media Kit Version: R1/alpha1
Keywords: Cc:
Blocked By: Blocking: #3437, #4893
Has a Patch: no Platform: All

Description

This is an application with the example code from the Be Book

http://www.acm.uiuc.edu/bug/Be%20Book/The%20Media%20Kit/SoundPlayer.html

#include <Application.h>
#include <Sound.h>
#include <SoundPlayer.h>

typedef struct cookie_record {
   float value;
   float direction;
} cookie_record;


void BufferProc(void *theCookie, void *buffer, size_t size,
            const media_raw_audio_format &format) {
   size_t i, j;
   float *buf = (float *) buffer;
   size_t float_size = size/4;
   uint32 channel_count = format.channel_count;
   cookie_record *cookie = (cookie_record *) theCookie;
   
   // We're going to be cheap and only work for floating-point audio
   
   if (format.format != media_raw_audio_format::B_AUDIO_FLOAT) {
      return;
   }
   
   // Now fill the buffer with sound!
   
   for (i=0; i<float_size; i+=channel_count) {
      for (j=0; j<channel_count; j++) {
         buf[i+j] = cookie->value;
      }
      if ((cookie->direction == 1.0) && (cookie->value >= 1.0)) {
         cookie->direction = -1.0;
      }
      else if ((cookie->direction == -1.0) && (cookie->value <= -1.0)) {
         cookie->direction = 1.0;
      }
      cookie->value += cookie->direction*(1.0/64.0);
   }
}

int main()
{
   BApplication app("application/dzwiek");

   
   cookie_record cookie;
   
   cookie.value = 0.0;
   cookie.direction = 1.0;
   
   BSoundPlayer player("wave_player", BufferProc, NULL, &cookie);
   player.Start();
   player.SetHasData(true);

   sleep(10);

   player.Stop();
}

If we compile it with gcc4, it works on Hybrid-4 but doesn't work on Hybrid-2.

If we compile it with gcc2, it works on Hybrid-2 but doesn't work on Hybrid-4.

As a result, applications compiled with gcc4 can't play sound on a gcc2 Haiku build. This includes gcc4 built applications that use SDL, for example Free Heroes Of Might And Magic.

Attachments (2)

sdlaudio.cc (2.1 KB) - added by Adek336 9 years ago.
proposed.fix.diff (1.4 KB) - added by Adek336 9 years ago.

Download all attachments as: .zip

Change History (9)

Changed 9 years ago by Adek336

Attachment: sdlaudio.cc added

comment:1 Changed 9 years ago by Adek336

sdlaudio.cc - additional test case, which uses SDL

comment:2 Changed 9 years ago by Adek336

When using the example code compiled with gcc4 on a hybrid-2 Haiku build, we can observe the following symptoms -

  • no sound;
  • heavy CPU usage;
  • error message "_SoundPlayNode::FillNextBuffer: RequestBuffer failed".

comment:3 Changed 9 years ago by Adek336

The error message is printed repeatedly, flooding the console.

comment:4 Changed 9 years ago by Adek336

Blocking: 4893 added

comment:5 Changed 9 years ago by Adek336

Blocking: 3437 added

Changed 9 years ago by Adek336

Attachment: proposed.fix.diff added

comment:6 Changed 9 years ago by Adek336

Proposed fix, please review.

gcc2 and gcc4 treat empty structures differently.

In particular, the following program yields different results with the two compilers:

#include <iostream>
using namespace std;

struct one {
};

struct two : one {
};

struct two_1 : one {
	char x;
};

struct two_2 : one {
	short x;
};

struct two_4 : one {
	int x;
};

struct two_8 : one {
	long long x;
};

struct three : two {
};

struct three_2 : two {
	short x;
};

struct three_4 : two {
	int x;
};

int main()
{
	cout << "__GNUC__\t" << __GNUC__ << endl;
	cout << "sizeof(one)\t" << sizeof(one) << endl;
	cout << "sizeof(two)\t" << sizeof(two) << endl;
	cout << "sizeof(two_1)\t" << sizeof(two_1) << endl;
	cout << "sizeof(two_2)\t" << sizeof(two_2) << endl;
	cout << "sizeof(two_4)\t" << sizeof(two_4) << endl;
	cout << "sizeof(two_8)\t" << sizeof(two_8) << endl;
	cout << "sizeof(three)\t" << sizeof(three) << endl;
	cout << "sizeof(three_2)\t" << sizeof(three_2) << endl;
	cout << "sizeof(three_4)\t" << sizeof(three_4) << endl;
	return 0;
}


	

results

~> setgcc gcc2
~> g++ a.cc -o a
~> ./a
__GNUC__        2
sizeof(one)     1
sizeof(two)     1
sizeof(two_1)   2
sizeof(two_2)   4
sizeof(two_4)   8
sizeof(two_8)   12
sizeof(three)   1
sizeof(three_2) 4
sizeof(three_4) 8
~> setgcc gcc4
~> g++ a.cc -o a
~> ./a
__GNUC__        4
sizeof(one)     1
sizeof(two)     1
sizeof(two_1)   1
sizeof(two_2)   2
sizeof(two_4)   4
sizeof(two_8)   8
sizeof(three)   1
sizeof(three_2) 2
sizeof(three_4) 4

Perhaps there are more empty structures in Haiku breaking compatibility between compiler versions.

The proposed fix makes the gcc4 builds of media kit compatible with the gcc2 builds and does not influence the ABI of the gcc2 builds.

The patch also adds the cstring header to two test files which need it.

comment:7 Changed 9 years ago by axeld

Resolution: fixed
Status: newclosed

Applied in hrev33997, thanks!

We actually prefer to use POSIX headers instead of the C++ ones (ie. <string.h> rather than <cstring>). I'll fix those in an extra commit.

Note: See TracTickets for help on using tickets.