Page 1 of 1

Cannot link libtremor

Posted: Tue Oct 20, 2009 9:34 pm
by Malakhim
I'm incredibly new to NDS programming and I'm trying to create a program that will play an OGG file that's included in the NDS file. Unfortunately, when I try to compile the program I get the following:

Code: Select all

template.o: In function 'main':
c:/ndsprograms/src/FirstAudio/source/template.c:28: undefined reference to 'ov_open_callbacks'
c:/ndsprograms/src/FirstAudio/source/template.c:38: undefined reference to 'ov_read'
c:/ndsprograms/src/FirstAudio/source/template.c:53: undefined reference to 'ov_raw_tell'
c:/ndsprograms/src/FirstAudio/source/template.c:44: undefined reference to 'ov_pcm_seek'
c:/ndsprograms/src/FirstAudio/source/template.c:48: undefined reference to 'ov_read'
and so on. I have made sure to include "-lvorbisidec" in the "LIBS" section of the makefile and checking the output it does find the library but it still doesn't find the functions.

I got libtremor from source at the devkitPro download page on SourceForge (the 'portlibs' section) and after some tinkering with "os_types.h" compiled it with MinGW ("os_types.h" assumes if _WIN32 is defined it must be either MSVC/Borland or Cygwin and won't include "config_types.h") and moved the include and library files to their respective locations in the libnds folder for simplicities sake.

Is there any reason why it wouldn't be linking? This has caused me quite a headache and any help whatsoever in the matter would be greatly appreciated

Re: Cannot link libtremor

Posted: Wed Oct 21, 2009 8:20 pm
by WinterMute
You need to compile tremor with devkitARM in order to link it with DS applications, I'm surprised that the linker didn't complain about the archive format tbh.

I've uploaded an arm build of libtremor to the portlibs section, which is intended to be installed in $DEVKITPRO/portlibs/arm. Using it once there is simply a matter of adding that directory to the LIBDIRS variable in the Makefile & -lvorbisidec to LIBS as you've done.

http://sourceforge.net/projects/devkitp ... /portlibs/

Code: Select all

#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS	:= 	-lvorbisdec -lnds9

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS	:=	$(DEVKITPRO)/portlibs/arm $(LIBNDS)
The next devkitARM release will have this path defined in $(PORTLIBS), due any day now™

Re: Cannot link libtremor

Posted: Thu Oct 22, 2009 3:45 am
by Malakhim
Thanks a lot WinterMute, that did the trick.

If I might ask, how would one compile a library from source using devkitARM? I tried putting the binaries in devkitARM\bin in the path as well as the binaries in devkitARM\arm-eabi\bin and both times the configure script errored out claiming that 'The compiler cannot create executeables'.

Re: Cannot link libtremor

Posted: Thu Oct 22, 2009 4:19 pm
by WinterMute
For most portable libraries this will work

Code: Select all

PATH=$DEVKITARM/bin:$PATH
<path/to/>configure --prefix=$DEVKITPRO/portlibs/arm --host=arm-eabi --disable-shared --enable-static
make && make install
Never run configure from the source directory unless the library requires it. You'll need to run this from the msys shell on windows.

Re: Cannot link libtremor

Posted: Thu Oct 22, 2009 11:24 pm
by Malakhim
Thanks again.

One last question: both ov_open and ov_open_callbacks block when I call them and pass them the OGG file. I put the OGG in the 'data' folder, renamed it 'Audio.bin' and I'm passing the pointer Audio_bin to ov_open_callbacks. The audio file is a little over a meg in size.

How would one go about fixing this?

Re: Cannot link libtremor

Posted: Sun Mar 20, 2011 1:06 pm
by spinal
I realise this is quite an old post, but I tried following the above instructions, but I get the following error -

Code: Select all

c:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.5.1/../../../../arm-eabi/bin/ld.exe: cannot find -lvorbisidec
collect2: ld returned 1 exit status
I'm not too good with makefiles, mine reads as follows -

Code: Select all

#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------

ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif

include $(DEVKITARM)/ds_rules

#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET		:=	$(shell basename $(CURDIR))
BUILD		:=	build
SOURCES		:=	gfx source data
INCLUDES	:=	include build 

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH	:=	-mthumb -mthumb-interwork

CFLAGS	:=	-g -Wall -O2\
 			-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
			-ffast-math \
			$(ARCH)

CFLAGS	+=	$(INCLUDE) -DARM9
CXXFLAGS	:= $(CFLAGS) -fno-rtti -fno-exceptions

ASFLAGS	:=	-g $(ARCH)
LDFLAGS	=	-specs=ds_arm9.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*.map)

#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS	:= -lvorbisidec -lnds9
 
 
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS	:=	$(DEVKITPRO)/portlibs/arm $(LIBNDS)
 
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
 
export OUTPUT	:=	$(CURDIR)/$(TARGET)
 
export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
export DEPSDIR	:=	$(CURDIR)/$(BUILD)

CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))
 
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
	export LD	:=	$(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
	export LD	:=	$(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES	:=	$(BINFILES:.bin=.o) \
					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
 
export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
					$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
					$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
					-I$(CURDIR)/$(BUILD)
 
export LIBPATHS	:=	$(foreach dir,$(LIBDIRS),-L$(dir)/lib)
 
.PHONY: $(BUILD) clean
 
#---------------------------------------------------------------------------------
$(BUILD):
	@[ -d $@ ] || mkdir -p $@
	@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
 
#---------------------------------------------------------------------------------
clean:
	@echo clean ...
	@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).ds.gba 
 
 
#---------------------------------------------------------------------------------
else
 
DEPENDS	:=	$(OFILES:.o=.d)
 
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds	: 	$(OUTPUT).elf
$(OUTPUT).elf	:	$(OFILES)
 
#---------------------------------------------------------------------------------
%.o	:	%.bin
#---------------------------------------------------------------------------------
	@echo $(notdir $<)
	$(bin2o)
 
 
-include $(DEPENDS)
 
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
with both libvorbisidec.a and libvorbisidec.la residing in C:\devkitPro\portlibs\arm


Have I missed something stupid?

Re: Cannot link libtremor

Posted: Tue Mar 22, 2011 1:19 am
by WinterMute
Yes, you need to extract the archive into that folder, not place the libraries there. You should have an include and lib folder in the portlibs/arm folder.

Re: Cannot link libtremor

Posted: Fri Mar 25, 2011 1:08 pm
by spinal
I'm having a little trouble playing the audio that is created with tremor. Although I can tell what the audio is, it is playing a varying speed (speeding up and slowing down) with a constant clicking all of the way through. I assume that the clicking is because of the audio being interrupted, perhaps by the buffer not being filled either completely or fast enough...

Code: Select all


#include <nds.h>
#include <fat.h>

#include <stdio.h>
#include <stdlib.h>

//ogg includes
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>

#define BUFFER_SIZE 4096 // In halfwords 

int freq=0;
int channels=0;

u16 buffer[BUFFER_SIZE]; 
u16 bufferLeft[BUFFER_SIZE/2]; 
u16 bufferRight[BUFFER_SIZE/2]; 

  OggVorbis_File vf;
  int eof=0;
  int current_section;
  long ret;

void startStream( int volume, int pan ) 
{ 
	ret=ov_read(&vf,buffer,sizeof(buffer),&current_section);

    // Sync timer 0 with the sound channel timer 
    TIMER0_DATA = -0x2000000 / freq;
    TIMER1_DATA = -BUFFER_SIZE;

    soundPlaySample( buffer, SoundFormat_16Bit, BUFFER_SIZE*2, freq, volume, 64, true, 0 ); 

    // Start timers 
    TIMER0_CR = TIMER_ENABLE; 
    TIMER1_CR = TIMER_ENABLE | TIMER_CASCADE; 

    fillStart = 0; 
}

// Call after swiWaitForVBlank() 
void updateStream()
{ 
	ret=ov_read(&vf,buffer,sizeof(buffer),&current_section);
}

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	consoleDemoInit();
	iprintf("      Ogg player test\n");

	fatInitDefault();

	FILE * myOgg = fopen("test.ogg", "rb");
  
	if(ov_open(myOgg, &vf, NULL, 0) < 0) {
		fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
		while(1){};
	}  
  
    char **ptr=ov_comment(&vf,-1)->user_comments;
    vorbis_info *vi=ov_info(&vf,-1);
    while(*ptr){
      fprintf(stderr,"%s\n",*ptr);
      ++ptr;
    }
    fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate);
    fprintf(stderr,"\nDecoded length: %ld samples\n",(long)ov_pcm_total(&vf,-1));
    fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);

	soundEnable(); // enable audio playing

	freq = vi->rate;
	channels = vi->channels;

	startStream(127, 64);
	
	while(!eof){
		swiWaitForVBlank();
		updateStream();
			if (ret == 0) eof=1;
	}
 
	ov_clear(&vf);
	fclose(myOgg);
    
	return 0;
}
Have I yet again missed something simple? or is real time music playing just not possible?

Re: Cannot link libtremor

Posted: Fri Mar 25, 2011 2:14 pm
by elhobbs
I can see that you setup a timer, but I cannot see that you are using it to fill the the sample buffer at the proper rate. I do not know if you are just using mono files, but a stereo file would have both channels - left, right alternating and you would need to split them to separate channels for the ds.

also, I think you may be using the old timer frequency algorithm that is not very accurate - look in the libnds timers.h file for the updated code.

Re: Cannot link libtremor

Posted: Fri Mar 25, 2011 6:14 pm
by WinterMute
Use the maxmod streaming code, see http://maxmod.org/ref/tut/streaming.html. There's also an example which uses this code.